27 #include "mongo/bson/inline_decls.h"
28 #include "mongo/base/string_data.h"
29 #include "mongo/util/assert_util.h"
50 const int BSONObjMaxUserSize = 16 * 1024 * 1024;
56 const int BSONObjMaxInternalSize = BSONObjMaxUserSize + ( 16 * 1024 );
58 const int BufferMaxSize = 64 * 1024 * 1024;
60 void msgasserted(
int msgid,
const char *msg);
62 template <
typename Allocator>
67 void* Malloc(
size_t sz) {
return malloc(sz); }
68 void* Realloc(
void *p,
size_t sz) {
return realloc(p, sz); }
69 void Free(
void *p) { free(p); }
75 void* Malloc(
size_t sz) {
76 if( sz <= SZ )
return buf;
79 void* Realloc(
void *p,
size_t sz) {
81 if( sz <= SZ )
return buf;
84 msgasserted( 15912 ,
"out of memory StackAllocator::Realloc" );
88 return realloc(p, sz);
98 template<
class Allocator >
107 data = (
char *) al.Malloc(size);
109 msgasserted(10000,
"out of memory BufBuilder");
128 void reset(
int maxSize ) {
130 if ( maxSize && size > maxSize ) {
132 data = (
char*)al.Malloc(maxSize);
134 msgasserted( 15913 ,
"out of memory BufBuilder::reset" );
142 char*
skip(
int n) {
return grow(n); }
145 char* buf() {
return data; }
146 const char* buf()
const {
return data; }
149 void decouple() { data = 0; }
151 void appendUChar(
unsigned char j) {
152 *((
unsigned char*)grow(
sizeof(
unsigned char))) = j;
154 void appendChar(
char j) {
155 *((
char*)grow(
sizeof(
char))) = j;
157 void appendNum(
char j) {
158 *((
char*)grow(
sizeof(
char))) = j;
160 void appendNum(
short j) {
161 *((
short*)grow(
sizeof(
short))) = j;
163 void appendNum(
int j) {
164 *((
int*)grow(
sizeof(
int))) = j;
166 void appendNum(
unsigned j) {
167 *((
unsigned*)grow(
sizeof(
unsigned))) = j;
169 void appendNum(
bool j) {
170 *((
bool*)grow(
sizeof(
bool))) = j;
172 void appendNum(
double j) {
173 (
reinterpret_cast< PackedDouble*
>(grow(
sizeof(
double))))->d = j;
175 void appendNum(
long long j) {
176 *((
long long*)grow(
sizeof(
long long))) = j;
178 void appendNum(
unsigned long long j) {
179 *((
unsigned long long*)grow(
sizeof(
unsigned long long))) = j;
182 void appendBuf(
const void *src,
size_t len) {
183 memcpy(grow((
int) len), src, len);
187 void appendStruct(
const T& s) {
188 appendBuf(&s,
sizeof(T));
191 void appendStr(
const StringData &str ,
bool includeEndingNull =
true ) {
192 const int len = str.size() + ( includeEndingNull ? 1 : 0 );
193 str.copyTo( grow(len), includeEndingNull );
197 int len()
const {
return l; }
198 void setlen(
int newLen ) { l = newLen; }
203 inline char* grow(
int by) {
206 if ( newLen > size ) {
207 grow_reallocate(newLen);
210 return data + oldlen;
215 void NOINLINE_DECL grow_reallocate(
int newLen) {
219 if ( a > BufferMaxSize ) {
220 std::stringstream ss;
221 ss <<
"BufBuilder attempted to grow() to " << a <<
" bytes, past the 64MB limit.";
222 msgasserted(13548, ss.str().c_str());
224 data = (
char *) al.Realloc(data, a);
226 msgasserted( 16070 ,
"out of memory BufBuilder::grow_reallocate" );
234 friend class StringBuilderImpl<Allocator>;
237 typedef _BufBuilder<TrivialAllocator> BufBuilder;
253 #pragma push_macro("snprintf")
254 #define snprintf _snprintf
258 template <
typename Allocator>
261 static const size_t MONGO_DBL_SIZE = 3 + DBL_MANT_DIG - DBL_MIN_EXP;
262 static const size_t MONGO_S32_SIZE = 12;
263 static const size_t MONGO_U32_SIZE = 11;
264 static const size_t MONGO_S64_SIZE = 23;
265 static const size_t MONGO_U64_SIZE = 22;
266 static const size_t MONGO_S16_SIZE = 7;
270 StringBuilderImpl& operator<<(
double x ) {
271 return SBNUM( x , MONGO_DBL_SIZE ,
"%g" );
273 StringBuilderImpl& operator<<(
int x ) {
274 return SBNUM( x , MONGO_S32_SIZE ,
"%d" );
276 StringBuilderImpl& operator<<(
unsigned x ) {
277 return SBNUM( x , MONGO_U32_SIZE ,
"%u" );
279 StringBuilderImpl& operator<<(
long x ) {
280 return SBNUM( x , MONGO_S64_SIZE ,
"%ld" );
282 StringBuilderImpl& operator<<(
unsigned long x ) {
283 return SBNUM( x , MONGO_U64_SIZE ,
"%lu" );
285 StringBuilderImpl& operator<<(
long long x ) {
286 return SBNUM( x , MONGO_S64_SIZE ,
"%lld" );
288 StringBuilderImpl& operator<<(
unsigned long long x ) {
289 return SBNUM( x , MONGO_U64_SIZE ,
"%llu" );
291 StringBuilderImpl& operator<<(
short x ) {
292 return SBNUM( x , MONGO_S16_SIZE ,
"%hd" );
294 StringBuilderImpl& operator<<(
char c ) {
295 _buf.grow( 1 )[0] = c;
299 void appendDoubleNice(
double x ) {
300 const int prev = _buf.l;
301 const int maxSize = 32;
302 char * start = _buf.grow( maxSize );
303 int z = snprintf( start , maxSize ,
"%.16g" , x );
305 verify( z < maxSize );
307 if( strchr(start,
'.') == 0 && strchr(start,
'E') == 0 && strchr(start,
'N') == 0 ) {
312 void write(
const char* buf,
int len) { memcpy( _buf.grow( len ) , buf ,
len ); }
314 void append(
const StringData& str ) { str.copyTo( _buf.grow( str.size() ),
false ); }
316 StringBuilderImpl& operator<<(
const StringData& str ) {
321 void reset(
int maxSize = 0 ) { _buf.reset( maxSize ); }
323 std::string str()
const {
return std::string(_buf.data, _buf.l); }
326 int len()
const {
return _buf.l; }
335 template <
typename T>
338 int z = snprintf( _buf.grow(maxSize) , maxSize , macro , (val) );
340 verify( z < maxSize );
346 typedef StringBuilderImpl<TrivialAllocator> StringBuilder;
347 typedef StringBuilderImpl<StackAllocator> StackStringBuilder;
351 #pragma pop_macro("snprintf")