26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
28 |
28 |
29 #include "dataBuffer.h" |
29 #include "dataBuffer.h" |
30 |
30 |
31 // ============================================================================ |
31 // ------------------------------------------------------------------------------------------------- |
32 // |
32 // |
33 DataBuffer::DataBuffer (int size) |
33 DataBuffer::DataBuffer (int size) : |
34 { |
34 m_buffer (new char[size]), |
35 setBuffer (new char[size]); |
35 m_position (&buffer()[0]), |
36 setPosition (&buffer()[0]); |
36 m_allocatedSize (size) {} |
37 setAllocatedSize (size); |
37 |
38 } |
38 // ------------------------------------------------------------------------------------------------- |
39 |
|
40 // ============================================================================ |
|
41 // |
39 // |
42 DataBuffer::~DataBuffer() |
40 DataBuffer::~DataBuffer() |
43 { |
41 { |
44 ASSERT (marks().isEmpty()); |
42 ASSERT (marks().isEmpty()); |
45 ASSERT (references().isEmpty()); |
43 ASSERT (references().isEmpty()); |
46 delete buffer(); |
44 delete buffer(); |
47 } |
45 } |
48 |
46 |
49 // ============================================================================ |
47 // ------------------------------------------------------------------------------------------------- |
|
48 // |
|
49 // Copies the contents of the given buffer into this buffer. The other buffer's marks and |
|
50 // references will be moved along and the buffer is then destroyed. |
50 // |
51 // |
51 void DataBuffer::mergeAndDestroy (DataBuffer* other) |
52 void DataBuffer::mergeAndDestroy (DataBuffer* other) |
52 { |
53 { |
53 if (other == null) |
54 if (other == null) |
54 return; |
55 return; |
59 other->transferMarksTo (this); |
60 other->transferMarksTo (this); |
60 copyBuffer (other); |
61 copyBuffer (other); |
61 delete other; |
62 delete other; |
62 } |
63 } |
63 |
64 |
64 // ============================================================================ |
65 // ------------------------------------------------------------------------------------------------- |
65 // |
66 // |
66 // Clones this databuffer to a new one and returns it. Note that the original |
67 // Clones this databuffer to a new one and returns it. Note that the original transfers its marks |
67 // transfers its marks and references and loses them in the process. |
68 // and references and loses them in the process. |
68 // |
69 // |
69 DataBuffer* DataBuffer::clone() |
70 DataBuffer* DataBuffer::clone() |
70 { |
71 { |
71 DataBuffer* other = new DataBuffer; |
72 DataBuffer* other = new DataBuffer; |
72 transferMarksTo (other); |
73 transferMarksTo (other); |
103 |
104 |
104 m_marks.clear(); |
105 m_marks.clear(); |
105 m_references.clear(); |
106 m_references.clear(); |
106 } |
107 } |
107 |
108 |
108 // ============================================================================ |
109 // ------------------------------------------------------------------------------------------------- |
|
110 // |
|
111 // Adds a new mark to the current position with the given name |
109 // |
112 // |
110 ByteMark* DataBuffer::addMark (const String& name) |
113 ByteMark* DataBuffer::addMark (const String& name) |
111 { |
114 { |
112 ByteMark* mark = new ByteMark; |
115 ByteMark* mark = new ByteMark; |
113 mark->name = name; |
116 mark->name = name; |
114 mark->pos = writtenSize(); |
117 mark->pos = writtenSize(); |
115 m_marks << mark; |
118 m_marks << mark; |
116 return mark; |
119 return mark; |
117 } |
120 } |
118 |
121 |
119 // ============================================================================ |
122 // ------------------------------------------------------------------------------------------------- |
|
123 // |
|
124 // Adds a new reference to the given mark at the current position. This function will write 4 |
|
125 // bytes to the buffer whose value will be determined at final output writing. |
120 // |
126 // |
121 MarkReference* DataBuffer::addReference (ByteMark* mark) |
127 MarkReference* DataBuffer::addReference (ByteMark* mark) |
122 { |
128 { |
123 MarkReference* ref = new MarkReference; |
129 MarkReference* ref = new MarkReference; |
124 ref->target = mark; |
130 ref->target = mark; |
129 writeDWord (0xBEEFCAFE); |
135 writeDWord (0xBEEFCAFE); |
130 |
136 |
131 return ref; |
137 return ref; |
132 } |
138 } |
133 |
139 |
134 // ============================================================================ |
140 // ------------------------------------------------------------------------------------------------- |
|
141 // |
|
142 // Moves the given mark to the current bytecode position. |
135 // |
143 // |
136 void DataBuffer::adjustMark (ByteMark* mark) |
144 void DataBuffer::adjustMark (ByteMark* mark) |
137 { |
145 { |
138 mark->pos = writtenSize(); |
146 mark->pos = writtenSize(); |
139 } |
147 } |
140 |
148 |
141 // ============================================================================ |
149 // ------------------------------------------------------------------------------------------------- |
142 // |
150 // |
143 void DataBuffer::offsetMark (ByteMark* mark, int position) |
151 // Shifts the given mark by the amount of bytes |
144 { |
152 // |
145 mark->pos += position; |
153 void DataBuffer::offsetMark (ByteMark* mark, int bytes) |
146 } |
154 { |
147 |
155 mark->pos += bytes; |
148 // ============================================================================ |
156 } |
|
157 |
|
158 // ------------------------------------------------------------------------------------------------- |
|
159 // |
|
160 // Writes a push of the index of the given string. 8 bytes will be written and the string index |
|
161 // will be pushed to stack. |
149 // |
162 // |
150 void DataBuffer::writeStringIndex (const String& a) |
163 void DataBuffer::writeStringIndex (const String& a) |
151 { |
164 { |
152 writeDWord (DH_PushStringIndex); |
165 writeDWord (DataHeader::PushStringIndex); |
153 writeDWord (getStringTableIndex (a)); |
166 writeDWord (getStringTableIndex (a)); |
154 } |
167 } |
155 |
168 |
156 // ============================================================================ |
169 // ------------------------------------------------------------------------------------------------- |
|
170 // |
|
171 // Prints the buffer to stdout. |
157 // |
172 // |
158 void DataBuffer::dump() |
173 void DataBuffer::dump() |
159 { |
174 { |
160 for (int i = 0; i < writtenSize(); ++i) |
175 for (int i = 0; i < writtenSize(); ++i) |
161 printf ("%d. [0x%X]\n", i, buffer()[i]); |
176 printf ("%d. [0x%X]\n", i, buffer()[i]); |
162 } |
177 } |
163 |
178 |
164 // ============================================================================ |
179 // ------------------------------------------------------------------------------------------------- |
|
180 // |
|
181 // Ensures there's at least the given amount of bytes left in the buffer. Will resize if necessary, |
|
182 // no-op if not. On resize, 512 extra bytes are allocated to reduce the amount of resizes. |
165 // |
183 // |
166 void DataBuffer::checkSpace (int bytes) |
184 void DataBuffer::checkSpace (int bytes) |
167 { |
185 { |
168 int writesize = writtenSize(); |
186 int writesize = writtenSize(); |
169 |
187 |
189 memcpy (m_buffer, copy, allocatedSize()); |
207 memcpy (m_buffer, copy, allocatedSize()); |
190 setPosition (buffer() + writesize); |
208 setPosition (buffer() + writesize); |
191 delete copy; |
209 delete copy; |
192 } |
210 } |
193 |
211 |
194 // ============================================================================= |
212 // ------------------------------------------------------------------------------------------------- |
|
213 // |
|
214 // Writes the given byte into the buffer. |
195 // |
215 // |
196 void DataBuffer::writeByte (int8_t data) |
216 void DataBuffer::writeByte (int8_t data) |
197 { |
217 { |
198 checkSpace (1); |
218 checkSpace (1); |
199 *m_position++ = data; |
219 *m_position++ = data; |
200 } |
220 } |
201 |
221 |
202 // ============================================================================= |
222 // ------------------------------------------------------------------------------------------------- |
|
223 // |
|
224 // Writes the given word into the buffer. 2 bytes will be written. |
203 // |
225 // |
204 void DataBuffer::writeWord (int16_t data) |
226 void DataBuffer::writeWord (int16_t data) |
205 { |
227 { |
206 checkSpace (2); |
228 checkSpace (2); |
207 |
229 |
208 for (int i = 0; i < 2; ++i) |
230 for (int i = 0; i < 2; ++i) |
209 *m_position++ = (data >> (i * 8)) & 0xFF; |
231 *m_position++ = (data >> (i * 8)) & 0xFF; |
210 } |
232 } |
211 |
233 |
212 // ============================================================================= |
234 // ------------------------------------------------------------------------------------------------- |
|
235 // |
|
236 // Writes the given dword into the buffer. 4bytes will be written. |
213 // |
237 // |
214 void DataBuffer::writeDWord (int32_t data) |
238 void DataBuffer::writeDWord (int32_t data) |
215 { |
239 { |
216 checkSpace (4); |
240 checkSpace (4); |
217 |
241 |
218 for (int i = 0; i < 4; ++i) |
242 for (int i = 0; i < 4; ++i) |
219 *m_position++ = (data >> (i * 8)) & 0xFF; |
243 *m_position++ = (data >> (i * 8)) & 0xFF; |
220 } |
244 } |
221 |
245 |
222 // ============================================================================= |
246 // ------------------------------------------------------------------------------------------------- |
|
247 // |
|
248 // Writes the given string to the databuffer. The string will be written as-is without using string |
|
249 // indices. This will write 4 + length bytes. No header will be written. |
223 // |
250 // |
224 void DataBuffer::writeString (const String& a) |
251 void DataBuffer::writeString (const String& a) |
225 { |
252 { |
226 checkSpace (a.length() + 4); |
253 checkSpace (a.length() + 4); |
227 writeDWord (a.length()); |
254 writeDWord (a.length()); |
228 |
255 |
229 for (char c : a) |
256 for (char c : a) |
230 writeByte (c); |
257 writeByte (c); |
231 } |
258 } |
232 |
259 |
233 |
260 // ------------------------------------------------------------------------------------------------- |
234 // ============================================================================= |
261 // |
|
262 // Tries to locate the mark by the given name. Returns null if not found. |
235 // |
263 // |
236 ByteMark* DataBuffer::findMarkByName (const String& name) |
264 ByteMark* DataBuffer::findMarkByName (const String& name) |
237 { |
265 { |
238 for (ByteMark* mark : marks()) |
266 for (ByteMark* mark : marks()) |
|
267 { |
239 if (mark->name == name) |
268 if (mark->name == name) |
240 return mark; |
269 return mark; |
|
270 } |
241 |
271 |
242 return null; |
272 return null; |
243 } |
273 } |