NXEngine v1.0.0.6
[NXEngine.git] / common / DBuffer.h
blob23802173ff1ced896f6a5d5a52d3a38a4d0238f8
2 #ifndef _DBUFFER_H
3 #define _DBUFFER_H
5 #include "basics.h"
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdint.h>
11 DBuffer vs. DString
13 The difference is that with a DBuffer, if you AppendString() multiple times,
14 you will get null-terminators in between each string. With a DString,
15 the strings will be concatenated. You can override this behavior in a DBuffer
16 by calling AppendStringNoNull instead of AppendString, but there is no function
17 for inserting NULLs into a DString, as that doesn't make sense.
20 #define DBUFFER_BUILTIN_SIZE 16
22 class DBuffer
24 public:
25 DBuffer();
26 ~DBuffer();
28 void SetTo(const uint8_t *data, int length);
29 void SetTo(const char *string);
30 void SetTo(DBuffer *other);
31 void SetTo(DBuffer &other);
33 void AppendData(const uchar *data, int length);
34 void AppendString(const char *str);
35 void AppendStringNoNull(const char *str);
37 void AppendBool(bool value);
38 void AppendChar(uchar ch);
39 void Append8(uint8_t value);
40 void Append16(uint16_t value);
41 void Append24(uint32_t value);
42 void Append32(uint32_t value);
44 bool ReadTo(DBuffer *line, uchar ch, bool add_null=true);
45 void EnsureAlloc(int min_required);
47 void ReplaceUnprintableChars();
49 DBuffer &operator= (const DBuffer &other);
51 // ---------------------------------------
53 void Clear();
54 uint8_t *Data();
55 uint8_t *TakeData();
56 char *String();
57 int Length();
59 private:
60 uint8_t *fData;
61 int fLength;
62 int fAllocSize;
63 bool fAllocdExternal;
65 uint8_t fBuiltInData[DBUFFER_BUILTIN_SIZE];
69 inline void DBuffer::EnsureAlloc(int min_required)
71 if (min_required > fAllocSize)
73 fAllocSize = (min_required + (min_required >> 1));
75 if (fAllocdExternal)
77 fData = (uint8_t *)realloc(fData, fAllocSize);
79 else
81 fData = (uint8_t *)malloc(fAllocSize);
82 fAllocdExternal = true;
84 // compatibility with String() - copy the potential extra null-terminator
85 int copysize = (fLength + 1);
86 if (copysize > fAllocSize) copysize = fAllocSize;
87 memcpy(fData, fBuiltInData, copysize);
92 inline void DBuffer::Clear()
94 // free any external memory and switch back to builtin
95 if (fAllocdExternal)
97 free(fData);
98 fData = &fBuiltInData[0];
99 fAllocSize = DBUFFER_BUILTIN_SIZE;
100 fAllocdExternal = false;
103 fLength = 0;
106 inline void DBuffer::SetTo(const uint8_t *data, int length)
108 // SetTo from a portion of ourselves
109 if (data >= fData && data <= fData + (fLength - 1))
111 uint8_t *tempBuffer = (uint8_t *)malloc(length);
112 memcpy(tempBuffer, data, length);
113 SetTo(tempBuffer, length);
114 free(tempBuffer);
115 return;
118 if (fAllocdExternal && length < DBUFFER_BUILTIN_SIZE)
120 free(fData);
121 fData = &fBuiltInData[0];
122 fAllocSize = DBUFFER_BUILTIN_SIZE;
123 fAllocdExternal = false;
125 else if (length > fAllocSize)
126 { // we are growing, so allocate more memory
127 if (fAllocdExternal) free(fData);
128 fAllocdExternal = true;
130 fAllocSize = (length + 16); // arbitrary, is just space for growing
131 fData = (uint8_t *)malloc(fAllocSize);
134 if (length) memcpy(fData, data, length);
135 fLength = length;
139 inline void DBuffer::AppendChar(uchar ch)
141 AppendData((uchar *)&ch, 1);
144 inline void DBuffer::Append8(uint8_t value)
146 AppendData((uchar *)&value, 1);
149 #endif