MongoDB  2.0.3
alignedbuilder.h
00001 // @file alignedbuilder.h
00002 
00019 #pragma once
00020 
00021 #include "../bson/stringdata.h"
00022 
00023 namespace mongo {
00024 
00026     class AlignedBuilder {
00027     public:
00028         AlignedBuilder(unsigned init_size);
00029         ~AlignedBuilder() { kill(); }
00030 
00032         void reset(unsigned sz);
00033 
00035         void reset();
00036 
00038         const char* buf() const { return _p._data; }
00039 
00043         size_t skip(unsigned n) {
00044             unsigned l = len();
00045             grow(n);
00046             return l;
00047         }
00048 
00050         char* atOfs(unsigned ofs) { return _p._data + ofs; }
00051 
00053         char* cur() { return _p._data + _len; }
00054 
00055         void appendChar(char j) {
00056             *((char*)grow(sizeof(char))) = j;
00057         }
00058         void appendNum(char j) {
00059             *((char*)grow(sizeof(char))) = j;
00060         }
00061         void appendNum(short j) {
00062             *((short*)grow(sizeof(short))) = j;
00063         }
00064         void appendNum(int j) {
00065             *((int*)grow(sizeof(int))) = j;
00066         }
00067         void appendNum(unsigned j) {
00068             *((unsigned*)grow(sizeof(unsigned))) = j;
00069         }
00070         void appendNum(bool j) {
00071             *((bool*)grow(sizeof(bool))) = j;
00072         }
00073         void appendNum(double j) {
00074             *((double*)grow(sizeof(double))) = j;
00075         }
00076         void appendNum(long long j) {
00077             *((long long*)grow(sizeof(long long))) = j;
00078         }
00079         void appendNum(unsigned long long j) {
00080             *((unsigned long long*)grow(sizeof(unsigned long long))) = j;
00081         }
00082 
00083         void appendBuf(const void *src, size_t len) { memcpy(grow((unsigned) len), src, len); }
00084 
00085         template<class T>
00086         void appendStruct(const T& s) { appendBuf(&s, sizeof(T)); }
00087 
00088         void appendStr(const StringData &str , bool includeEOO = true ) {
00089             const unsigned len = str.size() + ( includeEOO ? 1 : 0 );
00090             assert( len < (unsigned) BSONObjMaxUserSize );
00091             memcpy(grow(len), str.data(), len);
00092         }
00093 
00095         unsigned len() const { return _len; }
00096 
00097     private:
00098         static const unsigned Alignment = 8192;
00099 
00101         inline char* grow(unsigned by) {
00102             unsigned oldlen = _len;
00103             _len += by;
00104             if (MONGO_unlikely( _len > _p._size )) {
00105                 growReallocate(oldlen);
00106             }
00107             return _p._data + oldlen;
00108         }
00109 
00110         void growReallocate(unsigned oldLenInUse);
00111         void kill();
00112         void mallocSelfAligned(unsigned sz);
00113         void _malloc(unsigned sz);
00114         void _realloc(unsigned newSize, unsigned oldLenInUse);
00115         void _free(void*);
00116 
00117         struct AllocationInfo {
00118             char *_data;
00119             void *_allocationAddress;
00120             unsigned _size;
00121         } _p;
00122         unsigned _len;  // bytes in use
00123     };
00124 
00125 }