| 30 |
30 |
| 31 // ============================================================================ |
31 // ============================================================================ |
| 32 // |
32 // |
| 33 DataBuffer::DataBuffer (int size) |
33 DataBuffer::DataBuffer (int size) |
| 34 { |
34 { |
| 35 SetBuffer (new char[size]); |
35 setBuffer (new char[size]); |
| 36 SetPosition (&Buffer()[0]); |
36 setPosition (&buffer()[0]); |
| 37 SetAllocatedSize (size); |
37 setAllocatedSize (size); |
| 38 } |
38 } |
| 39 |
39 |
| 40 // ============================================================================ |
40 // ============================================================================ |
| 41 // |
41 // |
| 42 DataBuffer::~DataBuffer() |
42 DataBuffer::~DataBuffer() |
| 43 { |
43 { |
| 44 assert (Marks().Size() == 0 && References().Size() == 0); |
44 assert (marks().isEmpty() && references().isEmpty()); |
| 45 delete Buffer(); |
45 delete buffer(); |
| 46 } |
46 } |
| 47 |
47 |
| 48 // ============================================================================ |
48 // ============================================================================ |
| 49 // |
49 // |
| 50 void DataBuffer::MergeAndDestroy (DataBuffer* other) |
50 void DataBuffer::mergeAndDestroy (DataBuffer* other) |
| 51 { |
51 { |
| 52 if (!other) |
52 if (other == null) |
| 53 return; |
53 return; |
| 54 |
54 |
| 55 // Note: We transfer the marks before the buffer is copied, so that the |
55 // Note: We transfer the marks before the buffer is copied, so that the |
| 56 // offset uses the proper value (which is the written size of @other, which |
56 // offset uses the proper value (which is the written size of @other, which |
| 57 // we don't want our written size to be added to yet). |
57 // we don't want our written size to be added to yet). |
| 58 other->TransferMarks (this); |
58 other->transferMarksTo (this); |
| 59 CopyBuffer (other); |
59 copyBuffer (other); |
| 60 delete other; |
60 delete other; |
| 61 } |
61 } |
| 62 |
62 |
| 63 // ============================================================================ |
63 // ============================================================================ |
| 64 // |
64 // |
| 65 // Clones this databuffer to a new one and returns it. Note that the original |
65 // Clones this databuffer to a new one and returns it. Note that the original |
| 66 // transfers its marks and references and loses them in the process. |
66 // transfers its marks and references and loses them in the process. |
| 67 // |
67 // |
| 68 DataBuffer* DataBuffer::Clone() |
68 DataBuffer* DataBuffer::clone() |
| 69 { |
69 { |
| 70 DataBuffer* other = new DataBuffer; |
70 DataBuffer* other = new DataBuffer; |
| 71 TransferMarks (other); |
71 transferMarksTo (other); |
| 72 other->CopyBuffer (this); |
72 other->copyBuffer (this); |
| 73 return other; |
73 return other; |
| 74 } |
74 } |
| 75 |
75 |
| 76 // ============================================================================ |
76 // ============================================================================ |
| 77 // |
77 // |
| 78 void DataBuffer::CopyBuffer (const DataBuffer* buf) |
78 void DataBuffer::copyBuffer (const DataBuffer* buf) |
| 79 { |
79 { |
| 80 CheckSpace (buf->WrittenSize()); |
80 checkSpace (buf->writtenSize()); |
| 81 memcpy (mPosition, buf->Buffer(), buf->WrittenSize()); |
81 memcpy (m_position, buf->buffer(), buf->writtenSize()); |
| 82 mPosition += buf->WrittenSize(); |
82 m_position += buf->writtenSize(); |
| 83 } |
83 } |
| 84 |
84 |
| 85 // ============================================================================ |
85 // ============================================================================ |
| 86 // |
86 // |
| 87 void DataBuffer::TransferMarks (DataBuffer* other) |
87 void DataBuffer::transferMarksTo (DataBuffer* dest) |
| 88 { |
88 { |
| 89 int offset = other->WrittenSize(); |
89 int offset = dest->writtenSize(); |
| 90 |
90 |
| 91 for (ByteMark* mark : Marks()) |
91 for (ByteMark* mark : marks()) |
| 92 { |
92 { |
| 93 mark->pos += offset; |
93 mark->pos += offset; |
| 94 other->mMarks << mark; |
94 dest->m_marks << mark; |
| 95 } |
95 } |
| 96 |
96 |
| 97 for (MarkReference* ref : References()) |
97 for (MarkReference* ref : references()) |
| 98 { |
98 { |
| 99 ref->pos += offset; |
99 ref->pos += offset; |
| 100 other->mReferences << ref; |
100 dest->m_references << ref; |
| 101 } |
101 } |
| 102 |
102 |
| 103 mMarks.Clear(); |
103 m_marks.clear(); |
| 104 mReferences.Clear(); |
104 m_references.clear(); |
| 105 } |
105 } |
| 106 |
106 |
| 107 // ============================================================================ |
107 // ============================================================================ |
| 108 // |
108 // |
| 109 ByteMark* DataBuffer::AddMark (String name) |
109 ByteMark* DataBuffer::addMark (const String& name) |
| 110 { |
110 { |
| 111 ByteMark* mark = new ByteMark; |
111 ByteMark* mark = new ByteMark; |
| 112 mark->name = name; |
112 mark->name = name; |
| 113 mark->pos = WrittenSize(); |
113 mark->pos = writtenSize(); |
| 114 mMarks << mark; |
114 m_marks << mark; |
| 115 return mark; |
115 return mark; |
| 116 } |
116 } |
| 117 |
117 |
| 118 // ============================================================================ |
118 // ============================================================================ |
| 119 // |
119 // |
| 120 MarkReference* DataBuffer::AddReference (ByteMark* mark) |
120 MarkReference* DataBuffer::addReference (ByteMark* mark) |
| 121 { |
121 { |
| 122 MarkReference* ref = new MarkReference; |
122 MarkReference* ref = new MarkReference; |
| 123 ref->target = mark; |
123 ref->target = mark; |
| 124 ref->pos = WrittenSize(); |
124 ref->pos = writtenSize(); |
| 125 mReferences << ref; |
125 m_references << ref; |
| 126 |
126 |
| 127 // Write a dummy placeholder for the reference |
127 // Write a dummy placeholder for the reference |
| 128 WriteDWord (0xBEEFCAFE); |
128 writeDWord (0xBEEFCAFE); |
| 129 |
129 |
| 130 return ref; |
130 return ref; |
| 131 } |
131 } |
| 132 |
132 |
| 133 // ============================================================================ |
133 // ============================================================================ |
| 134 // |
134 // |
| 135 void DataBuffer::AdjustMark (ByteMark* mark) |
135 void DataBuffer::adjustMark (ByteMark* mark) |
| 136 { |
136 { |
| 137 mark->pos = WrittenSize(); |
137 mark->pos = writtenSize(); |
| 138 } |
138 } |
| 139 |
139 |
| 140 // ============================================================================ |
140 // ============================================================================ |
| 141 // |
141 // |
| 142 void DataBuffer::OffsetMark (ByteMark* mark, int offset) |
142 void DataBuffer::offsetMark (ByteMark* mark, int position) |
| 143 { |
143 { |
| 144 mark->pos += offset; |
144 mark->pos += position; |
| 145 } |
145 } |
| 146 |
146 |
| 147 // ============================================================================ |
147 // ============================================================================ |
| 148 // |
148 // |
| 149 void DataBuffer::WriteStringIndex (const String& a) |
149 void DataBuffer::writeStringIndex (const String& a) |
| 150 { |
150 { |
| 151 WriteDWord (DH_PushStringIndex); |
151 writeDWord (DH_PushStringIndex); |
| 152 WriteDWord (StringTableIndex (a)); |
152 writeDWord (getStringTableIndex (a)); |
| 153 } |
153 } |
| 154 |
154 |
| 155 // ============================================================================ |
155 // ============================================================================ |
| 156 // |
156 // |
| 157 void DataBuffer::Dump() |
157 void DataBuffer::dump() |
| 158 { |
158 { |
| 159 for (int i = 0; i < WrittenSize(); ++i) |
159 for (int i = 0; i < writtenSize(); ++i) |
| 160 printf ("%d. [0x%X]\n", i, Buffer()[i]); |
160 printf ("%d. [0x%X]\n", i, buffer()[i]); |
| 161 } |
161 } |
| 162 |
162 |
| 163 // ============================================================================ |
163 // ============================================================================ |
| 164 // |
164 // |
| 165 void DataBuffer::CheckSpace (int bytes) |
165 void DataBuffer::checkSpace (int bytes) |
| 166 { |
166 { |
| 167 int writesize = WrittenSize(); |
167 int writesize = writtenSize(); |
| 168 |
168 |
| 169 if (writesize + bytes < AllocatedSize()) |
169 if (writesize + bytes < allocatedSize()) |
| 170 return; |
170 return; |
| 171 |
171 |
| 172 // We don't have enough space in the buffer to write |
172 // We don't have enough space in the buffer to write |
| 173 // the stuff - thus resize. First, store the old |
173 // the stuff - thus resize. First, store the old |
| 174 // buffer temporarily: |
174 // buffer temporarily: |
| 175 char* copy = new char[AllocatedSize()]; |
175 char* copy = new char[allocatedSize()]; |
| 176 memcpy (copy, Buffer(), AllocatedSize()); |
176 memcpy (copy, buffer(), allocatedSize()); |
| 177 |
177 |
| 178 // Remake the buffer with the new size. Have enough space |
178 // Remake the buffer with the new size. Have enough space |
| 179 // for the stuff we're going to write, as well as a bit |
179 // for the stuff we're going to write, as well as a bit |
| 180 // of leeway so we don't have to resize immediately again. |
180 // of leeway so we don't have to resize immediately again. |
| 181 int newsize = AllocatedSize() + bytes + 512; |
181 int newsize = allocatedSize() + bytes + 512; |
| 182 |
182 |
| 183 delete Buffer(); |
183 delete buffer(); |
| 184 SetBuffer (new char[newsize]); |
184 setBuffer (new char[newsize]); |
| 185 SetAllocatedSize (newsize); |
185 setAllocatedSize (newsize); |
| 186 |
186 |
| 187 // Now, copy the stuff back. |
187 // Now, copy the stuff back. |
| 188 memcpy (mBuffer, copy, AllocatedSize()); |
188 memcpy (m_buffer, copy, allocatedSize()); |
| 189 SetPosition (Buffer() + writesize); |
189 setPosition (buffer() + writesize); |
| 190 delete copy; |
190 delete copy; |
| 191 } |
191 } |
| 192 |
192 |
| 193 // ============================================================================= |
193 // ============================================================================= |
| 194 // |
194 // |
| 195 void DataBuffer::WriteByte (int8_t data) |
195 void DataBuffer::writeByte (int8_t data) |
| 196 { |
196 { |
| 197 CheckSpace (1); |
197 checkSpace (1); |
| 198 *mPosition++ = data; |
198 *m_position++ = data; |
| 199 } |
199 } |
| 200 |
200 |
| 201 // ============================================================================= |
201 // ============================================================================= |
| 202 // |
202 // |
| 203 void DataBuffer::WriteWord (int16_t data) |
203 void DataBuffer::writeWord (int16_t data) |
| 204 { |
204 { |
| 205 CheckSpace (2); |
205 checkSpace (2); |
| 206 |
206 |
| 207 for (int i = 0; i < 2; ++i) |
207 for (int i = 0; i < 2; ++i) |
| 208 *mPosition++ = (data >> (i * 8)) & 0xFF; |
208 *m_position++ = (data >> (i * 8)) & 0xFF; |
| 209 } |
209 } |
| 210 |
210 |
| 211 // ============================================================================= |
211 // ============================================================================= |
| 212 // |
212 // |
| 213 void DataBuffer::WriteDWord (int32_t data) |
213 void DataBuffer::writeDWord (int32_t data) |
| 214 { |
214 { |
| 215 CheckSpace (4); |
215 checkSpace (4); |
| 216 |
216 |
| 217 for (int i = 0; i < 4; ++i) |
217 for (int i = 0; i < 4; ++i) |
| 218 *mPosition++ = (data >> (i * 8)) & 0xFF; |
218 *m_position++ = (data >> (i * 8)) & 0xFF; |
| 219 } |
219 } |
| 220 |
220 |
| 221 // ============================================================================= |
221 // ============================================================================= |
| 222 // |
222 // |
| 223 void DataBuffer::WriteString (const String& a) |
223 void DataBuffer::writeString (const String& a) |
| 224 { |
224 { |
| 225 CheckSpace (a.Length() + 4); |
225 checkSpace (a.length() + 4); |
| 226 WriteDWord (a.Length()); |
226 writeDWord (a.length()); |
| 227 |
227 |
| 228 for (char c : a) |
228 for (char c : a) |
| 229 WriteByte (c); |
229 writeByte (c); |
| 230 } |
230 } |
| 231 |
231 |
| 232 |
232 |
| 233 // ============================================================================= |
233 // ============================================================================= |
| 234 // |
234 // |
| 235 ByteMark* DataBuffer::FindMarkByName (const String& target) |
235 ByteMark* DataBuffer::findMarkByName (const String& name) |
| 236 { |
236 { |
| 237 for (ByteMark* mark : Marks()) |
237 for (ByteMark* mark : marks()) |
| 238 if (mark->name == target) |
238 if (mark->name == name) |
| 239 return mark; |
239 return mark; |
| 240 |
240 |
| 241 return null; |
241 return null; |
| 242 } |
242 } |