src/data_buffer.cc

changeset 73
1ee9b312dc18
child 75
bf8c57437231
equal deleted inserted replaced
72:03e4d9db3fd9 73:1ee9b312dc18
1 /*
2 Copyright (c) 2013-2014, Santeri Piippo
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 * Neither the name of the <organization> nor the
16 names of its contributors may be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "data_buffer.h"
32
33 // ============================================================================
34 //
35 void data_buffer::merge (data_buffer* other)
36 {
37 if (!other)
38 return;
39
40 int oldsize = writesize;
41
42 for (int x = 0; x < other->writesize; x++)
43 write (* (other->buffer + x));
44
45 // Merge its marks and references
46 int u = 0;
47
48 for (u = 0; u < MAX_MARKS; u++)
49 {
50 if (other->marks[u])
51 {
52 // Merge the mark and offset its position.
53 if (marks[u])
54 error ("DataBuffer: duplicate mark %d!\n");
55
56 marks[u] = other->marks[u];
57 marks[u]->pos += oldsize;
58
59 // The original mark becomes null so that the deconstructor
60 // will not delete it prematurely. (should it delete any
61 // marks in the first place since there is no such thing
62 // as at temporary mark?)
63 other->marks[u] = null;
64 }
65
66 if (other->refs[u])
67 {
68 // Same for references
69 // TODO: add a g_NextRef system like here, akin to marks!
70 int r = AddMarkReference (other->refs[u]->num, false);
71 refs[r]->pos = other->refs[u]->pos + oldsize;
72 }
73 }
74
75 delete other;
76 }
77
78 // ============================================================================
79 //
80 data_buffer* data_buffer::clone()
81 {
82 data_buffer* other = new data_buffer;
83
84 for (int x = 0; x < writesize; x++)
85 other->write (* (buffer + x));
86
87 return other;
88 }
89
90 // ============================================================================
91 //
92 int data_buffer::add_mark (string name)
93 {
94 // Find a free slot for the mark
95 int u = g_NextMark++;
96
97 if (marks[u])
98 error ("DataBuffer: attempted to re-create mark %u!\n", u);
99
100 if (u >= MAX_MARKS)
101 error ("mark quota exceeded, all labels, if-structs and loops add marks\n");
102
103 ScriptMark* m = new ScriptMark;
104 m->name = name;
105 m->pos = writesize;
106 marks[u] = m;
107 return u;
108 }
109
110 // ============================================================================
111 //
112 int data_buffer::AddMarkReference (int marknum, bool placeholder)
113 {
114 int u;
115
116 for (u = 0; u < MAX_MARKS; u++)
117 if (!refs[u])
118 break;
119
120 if (u == MAX_MARKS)
121 error ("mark reference quota exceeded, all goto-statements, if-structs and loops add refs\n");
122
123 ScriptMarkReference* r = new ScriptMarkReference;
124 r->num = marknum;
125 r->pos = writesize;
126 refs[u] = r;
127
128 // Write a dummy placeholder for the reference
129 if (placeholder)
130 write (1234);
131
132 return u;
133 }
134
135 // ============================================================================
136 //
137 void data_buffer::delete_mark (int marknum)
138 {
139 if (!marks[marknum])
140 return;
141
142 // Delete the mark
143 delete marks[marknum];
144 marks[marknum] = null;
145
146 // Delete its references
147 for (int u = 0; u < MAX_MARKS; u++)
148 {
149 if (refs[u]->num == marknum)
150 {
151 delete refs[u];
152 refs[u] = null;
153 }
154 }
155 }
156
157 // ============================================================================
158 //
159 void data_buffer::move_mark (int i)
160 {
161 if (!marks[i])
162 return;
163
164 marks[i]->pos = writesize;
165 }
166
167 // ============================================================================
168 //
169 void data_buffer::offset_mark (int mark, int offset)
170 {
171 if (!marks[mark])
172 return;
173
174 marks[mark]->pos += offset;
175 }
176
177 // ============================================================================
178 //
179 int data_buffer::count_marks()
180 {
181 int count = 0;
182
183 for (int u = 0; u < MAX_MARKS; u++)
184 count += !!marks[u];
185
186 return count;
187 }
188
189 // ============================================================================
190 //
191 int data_buffer::count_references()
192 {
193 int count = 0;
194
195 for (int u = 0; u < MAX_MARKS; u++)
196 count += !!refs[u];
197
198 return count;
199 }
200
201 // ============================================================================
202 //
203 void data_buffer::write_float (string floatstring)
204 {
205 // TODO: Casting float to word causes the decimal to be lost.
206 // Find a way to store the number without such loss.
207 float val = atof (floatstring);
208 write (DH_PUSHNUMBER);
209 write (static_cast<word> ((val > 0) ? val : -val));
210
211 if (val < 0)
212 write (DH_UNARYMINUS);
213 }
214
215 // ============================================================================
216 //
217 void data_buffer::write_string (string a)
218 {
219 write (DH_PUSHSTRINGINDEX);
220 write (get_string_table_index (a));
221 }
222
223 // ============================================================================
224 //
225 void data_buffer::dump()
226 {
227 for (int x = 0; x < writesize; x++)
228 printf ("%d. [%d]\n", x, * (buffer + x));
229 }
230
231 // ============================================================================
232 //
233 data_buffer::~data_buffer()
234 {
235 delete buffer;
236
237 // Delete any marks and references
238 for (int i = 0; i < MAX_MARKS; i++)
239 {
240 delete marks[i];
241 delete refs[i];
242 }
243 }
244
245 // ============================================================================
246 //
247 data_buffer::data_buffer (int size)
248 {
249 writesize = 0;
250
251 buffer = new unsigned char[size];
252 allocsize = size;
253
254 // Clear the marks table out
255 for (int u = 0; u < MAX_MARKS; u++)
256 {
257 marks[u] = null;
258 refs[u] = null;
259 }
260 }

mercurial