Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 273 lines (243 sloc) 6.647 kB
d515827 @CO2 Initial Commit
authored
1 // Copyright (C) 2009, 2010 Brendon Duncan
2
3 /* This file is a part of UDMFConvert.
4
5 UDMFConvert is free software: you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation, either version
8 3 of the License or (at your option) any later version.
9
10 UDMFConvert is distributed in the hope that it will be useful
11 but WITHOUT ANY WARRANTY; without even the implied warranty
12 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with this program. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include "udmf.h"
20 #include <math.h>
21 #include <cstring>
22 #include "exceptions.h"
23
24 #define vtod(x,y,z) switch (x) \
25 { case BVT_BOOLEAN: z = y.boolval;break; \
26 case BVT_FLOAT: z = y.floatval;break; \
27 case BVT_INTEGER: z = y.intval;break; \
28 default: z = 0;break; }
29
30 namespace udmf
31 {
32 variant::variant()
33 {
34 this->valtype = BVT_NULL;
35 }
36
37 variant::variant(const variant &src)
38 {
39 this->valtype = src.valtype;
40 this->val = src.val;
41 }
42
43 variant::variant(int newval)
44 {
45 this->valtype = BVT_INTEGER;
46 this->val.intval = newval;
47 }
48
49 variant::variant(double newval)
50 {
51 this->valtype = BVT_FLOAT;
52 this->val.floatval = newval;
53 }
54
55 variant::variant(bool newval)
56 {
57 this->valtype = BVT_BOOLEAN;
58 this->val.boolval = newval;
59 }
60
61 variant::variant(const char *newval)
62 {
63 this->valtype = BVT_STRING;
64 this->val.stringval = new char[strlen(newval) + 1];
65 strcpy(this->val.stringval,newval);
66 }
67
68 variant::variant(const udmf::block &newval)
69 {
70 this->valtype = BVT_SUBBLOCK;
71 this->val.subval = new udmf::block;
72 *(this->val.subval) = newval;
73 }
74
75 variant &variant::operator=(const variant &other)
76 {
77 if (this->valtype == BVT_STRING)
78 delete[] this->val.stringval;
79 else if (this->valtype == BVT_SUBBLOCK)
80 delete this->val.subval;
81 this->valtype = other.valtype;
82 if (other.valtype == BVT_STRING)
83 {
84 this->val.stringval = new char[strlen(other.val.stringval) + 1];
85 strcpy(this->val.stringval,other.val.stringval);
86 }
87 else if (other.valtype == BVT_SUBBLOCK)
88 {
89 this->val.subval = new udmf::block;
90 *(this->val.subval) = *(other.val.subval);
91 }
92 else
93 this->val = other.val;
94 return *this;
95 }
96
97 bool variant::operator>(const variant &other) const
98 {
99 double a;
100 double b;
101 vtod(this->valtype,(*this).val,a);
102 vtod(other.valtype,other.val,b);
103 return (a > b);
104 }
105
106 bool variant::operator<(const variant &other) const
107 {
108 double a;
109 double b;
110 vtod(this->valtype,(*this).val,a);
111 vtod(other.valtype,other.val,b);
112 return (a < b);
113 }
114
115 bool variant::operator>=(const variant &other) const
116 {
117 double a;
118 double b;
119 vtod(this->valtype,(*this).val,a);
120 vtod(other.valtype,other.val,b);
121 return (a >= b);
122 }
123
124 bool variant::operator<=(const variant &other) const
125 {
126 double a;
127 double b;
128 vtod(this->valtype,(*this).val,a);
129 vtod(other.valtype,other.val,b);
130 return (a <= b);
131 }
132
133 bool variant::operator==(const variant &other) const
134 {
135 if ((this->valtype == BVT_STRING) && (other.valtype == BVT_STRING))
136 return !strcmp(this->val.stringval,other.val.stringval);
137 double a;
138 double b;
139 vtod(this->valtype,(*this).val,a);
140 vtod(other.valtype,other.val,b);
141 return (a == b);
142 }
143
144 bool variant::operator!=(const variant &other) const
145 {
146 if ((this->valtype == BVT_STRING) && (other.valtype == BVT_STRING))
147 return strcmp(this->val.stringval,other.val.stringval);
148 double a;
149 double b;
150 vtod(this->valtype,(*this).val,a);
151 vtod(other.valtype,other.val,b);
152 return (a != b);
153 }
154
155 void variant::nullify()
156 {
157 if (this->valtype == BVT_STRING)
158 delete[] this->val.stringval;
159 else if (this->valtype == BVT_SUBBLOCK)
160 delete this->val.subval;
161 this->valtype = BVT_NULL;
162 }
163
164 void variant::setint(int newval)
165 {
166 if (this->valtype == BVT_STRING)
167 delete[] this->val.stringval;
168 else if (this->valtype == BVT_SUBBLOCK)
169 delete this->val.subval;
170 this->valtype = BVT_INTEGER;
171 this->val.intval = newval;
172 }
173
174 void variant::setfloat(double newval)
175 {
176 if (this->valtype == BVT_STRING)
177 delete[] this->val.stringval;
178 else if (this->valtype == BVT_SUBBLOCK)
179 delete this->val.subval;
180 this->valtype = BVT_FLOAT;
181 this->val.floatval = newval;
182 }
183
184 void variant::setbool(bool newval)
185 {
186 if (this->valtype == BVT_STRING)
187 delete[] this->val.stringval;
188 else if (this->valtype == BVT_SUBBLOCK)
189 delete this->val.subval;
190 this->valtype = BVT_BOOLEAN;
191 this->val.boolval = newval;
192 }
193
194 void variant::setstr(const char *newval)
195 {
196 if (this->valtype == BVT_STRING)
197 delete[] this->val.stringval;
198 else if (this->valtype == BVT_SUBBLOCK)
199 delete this->val.subval;
200 this->valtype = BVT_STRING;
201 this->val.stringval = new char[strlen(newval) + 1];
202 strcpy(this->val.stringval,newval);
203 }
204
205 void variant::setstr(const char *newval,int len)
206 {
207 if (this->valtype == BVT_STRING)
208 delete[] this->val.stringval;
209 else if (this->valtype == BVT_SUBBLOCK)
210 delete this->val.subval;
211 this->valtype = BVT_STRING;
212 this->val.stringval = new char[len + 1];
213 strncpy(this->val.stringval,newval,len);
214 this->val.stringval[len] = 0;
215 }
216
217 void variant::setsub(const udmf::block &other)
218 {
219 if (this->valtype == BVT_STRING)
220 delete[] this->val.stringval;
221 else if (this->valtype == BVT_SUBBLOCK)
222 delete this->val.subval;
223 this->valtype = BVT_SUBBLOCK;
224 this->val.subval = new udmf::block;
225 *(this->val.subval) = other;
226 }
227
228 variant::~variant()
229 {
230 if (this->valtype == BVT_STRING)
231 delete[] this->val.stringval;
232 else if (this->valtype == BVT_SUBBLOCK)
233 delete this->val.subval;
234 }
235
236 void writeblock(const char *name,block b,std::ofstream &out)
237 {
238 out << name << "\n{\n";
239 for (block::iterator it = b.begin();it != b.end();it++)
240 {
241 if (it->second.valtype == BVT_NULL)
242 continue;
243 out << it->first << " = ";
244 switch (it->second.valtype)
245 {
246 case BVT_BOOLEAN:
247 out << (it->second.val.boolval ? "true" : "false");
248 break;
249 case BVT_FLOAT:
250 if (it->second.val.floatval == floor(it->second.val.floatval))
251 out << it->second.val.floatval << '.';
252 else
253 out << it->second.val.floatval;
254 break;
255 case BVT_INTEGER:
256 out << it->second.val.intval;
257 break;
258 case BVT_STRING:
259 out << '\"' << it->second.val.stringval << '\"';
260 //Does not escape strings and backslashes like it should
261 break;
262 case BVT_SUBBLOCK:
263 writeblock(it->first.c_str(),*(it->second.val.subval),out);
264 break;
265 default:
266 throw exception::root("Unknown variant type detected");
267 }
268 out << ";\n";
269 }
270 out << "}\n\n";
271 }
272 };
Something went wrong with that request. Please try again.