25 #include <boost/static_assert.hpp>
27 #include "mongo/base/data_view.h"
28 #include "mongo/base/string_data.h"
29 #include "mongo/bson/inline_decls.h"
30 #include "mongo/util/assert_util.h"
42 const int BSONObjMaxUserSize = 16 * 1024 * 1024;
48 const int BSONObjMaxInternalSize = BSONObjMaxUserSize + (16 * 1024);
50 const int BufferMaxSize = 64 * 1024 * 1024;
52 template <
typename Allocator>
57 void* Malloc(
size_t sz) {
60 void* Realloc(
void* p,
size_t sz) {
61 return realloc(p, sz);
71 void* Malloc(
size_t sz) {
76 void* Realloc(
void* p,
size_t sz) {
82 msgasserted(15912,
"out of memory StackAllocator::Realloc");
86 return realloc(p, sz);
97 template <
class Allocator>
107 data = (
char*)al.Malloc(size);
109 msgasserted(10000,
"out of memory BufBuilder");
131 void reset(
int maxSize) {
134 if (maxSize && size > maxSize) {
136 data = (
char*)al.Malloc(maxSize);
138 msgasserted(15913,
"out of memory BufBuilder::reset");
155 const char* buf()
const {
164 void appendUChar(
unsigned char j) {
165 BOOST_STATIC_ASSERT(CHAR_BIT == 8);
168 void appendChar(
char j) {
171 void appendNum(
char j) {
174 void appendNum(
short j) {
175 BOOST_STATIC_ASSERT(
sizeof(
short) == 2);
178 void appendNum(
int j) {
179 BOOST_STATIC_ASSERT(
sizeof(
int) == 4);
182 void appendNum(
unsigned j) {
187 #if __cplusplus >= 201103L
188 void appendNum(
bool j) =
delete;
190 void appendNum(
bool j) {
195 void appendNum(
double j) {
196 BOOST_STATIC_ASSERT(
sizeof(
double) == 8);
199 void appendNum(
long long j) {
200 BOOST_STATIC_ASSERT(
sizeof(
long long) == 8);
203 void appendNum(
unsigned long long j) {
207 void appendBuf(
const void* src,
size_t len) {
208 memcpy(grow((
int)len), src, len);
212 void appendStruct(
const T& s) {
213 appendBuf(&s,
sizeof(T));
216 void appendStr(
const StringData& str,
bool includeEndingNull =
true) {
217 const int len = str.size() + (includeEndingNull ? 1 : 0);
218 str.copyTo(grow(len), includeEndingNull);
225 void setlen(
int newLen) {
234 inline char* grow(
int by) {
237 int minSize = newLen + reservedBytes;
238 if (minSize > size) {
239 grow_reallocate(minSize);
242 return data + oldlen;
249 int minSize = l + reservedBytes + bytes;
251 grow_reallocate(minSize);
254 reservedBytes += bytes;
263 invariant(reservedBytes >= bytes);
264 reservedBytes -= bytes;
268 template <
typename T>
269 void appendNumImpl(T t) {
274 DataView(grow(
sizeof(t))).writeLE(t);
279 void NOINLINE_DECL grow_reallocate(
int minSize) {
284 if (a > BufferMaxSize) {
285 std::stringstream ss;
286 ss <<
"BufBuilder attempted to grow() to " << a <<
" bytes, past the 64MB limit.";
287 msgasserted(13548, ss.str().c_str());
289 data = (
char*)al.Realloc(data, a);
291 msgasserted(16070,
"out of memory BufBuilder::grow_reallocate");
300 friend class StringBuilderImpl<Allocator>;
303 typedef _BufBuilder<TrivialAllocator> BufBuilder;
319 #pragma push_macro("snprintf")
320 #define snprintf _snprintf
324 template <
typename Allocator>
328 static const size_t MONGO_DBL_SIZE = 3 + DBL_MANT_DIG - DBL_MIN_EXP + 1;
329 static const size_t MONGO_S32_SIZE = 12;
330 static const size_t MONGO_U32_SIZE = 11;
331 static const size_t MONGO_S64_SIZE = 23;
332 static const size_t MONGO_U64_SIZE = 22;
333 static const size_t MONGO_S16_SIZE = 7;
334 static const size_t MONGO_PTR_SIZE = 19;
338 StringBuilderImpl& operator<<(
double x) {
339 return SBNUM(x, MONGO_DBL_SIZE,
"%g");
341 StringBuilderImpl& operator<<(
int x) {
342 return SBNUM(x, MONGO_S32_SIZE,
"%d");
344 StringBuilderImpl& operator<<(
unsigned x) {
345 return SBNUM(x, MONGO_U32_SIZE,
"%u");
347 StringBuilderImpl& operator<<(
long x) {
348 return SBNUM(x, MONGO_S64_SIZE,
"%ld");
350 StringBuilderImpl& operator<<(
unsigned long x) {
351 return SBNUM(x, MONGO_U64_SIZE,
"%lu");
353 StringBuilderImpl& operator<<(
long long x) {
354 return SBNUM(x, MONGO_S64_SIZE,
"%lld");
356 StringBuilderImpl& operator<<(
unsigned long long x) {
357 return SBNUM(x, MONGO_U64_SIZE,
"%llu");
359 StringBuilderImpl& operator<<(
short x) {
360 return SBNUM(x, MONGO_S16_SIZE,
"%hd");
362 StringBuilderImpl& operator<<(
const void* x) {
363 if (
sizeof(x) == 8) {
364 return SBNUM(x, MONGO_PTR_SIZE,
"0x%llX");
366 return SBNUM(x, MONGO_PTR_SIZE,
"0x%lX");
369 StringBuilderImpl& operator<<(
char c) {
373 StringBuilderImpl& operator<<(
const char* str) {
374 return *
this << StringData(str);
376 StringBuilderImpl& operator<<(
const StringData& str) {
381 void appendDoubleNice(
double x) {
382 const int prev = _buf.l;
383 const int maxSize = 32;
384 char* start = _buf.grow(maxSize);
385 int z = snprintf(start, maxSize,
"%.16g", x);
389 if (strchr(start,
'.') == 0 && strchr(start,
'E') == 0 && strchr(start,
'N') == 0) {
394 void write(
const char* buf,
int len) {
395 memcpy(_buf.grow(len), buf,
len);
398 void append(
const StringData& str) {
399 str.copyTo(_buf.grow(str.size()),
false);
402 void reset(
int maxSize = 0) {
406 std::string str()
const {
407 return std::string(_buf.data, _buf.l);
422 template <
typename T>
425 int z = snprintf(_buf.grow(maxSize), maxSize, macro, (val));
433 typedef StringBuilderImpl<TrivialAllocator> StringBuilder;
434 typedef StringBuilderImpl<StackAllocator> StackStringBuilder;
438 #pragma pop_macro("snprintf")
std::stringstream deals with locale so this is a lot faster than std::stringstream for UTF8 ...
Definition: builder.h:53
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
void claimReservedBytes(int bytes)
Claim an earlier reservation of some number of bytes.
Definition: builder.h:262
void reserveBytes(int bytes)
Reserve room for some number of bytes to be claimed at a later time.
Definition: builder.h:248
char * skip(int n)
leave room for some stuff later
Definition: builder.h:147
int getSize() const
Definition: builder.h:229
int len() const
size of current string
Definition: builder.h:411
int len() const
Definition: builder.h:222
Definition: data_view.h:71
The StackBufBuilder builds smaller datasets on the stack instead of using malloc. ...
Definition: builder.h:312