1 // parser.cpp
2 //
3 // Copyright (C) 2001 Chris Laurel <claurel@shatters.net>
4 //
5 // This program 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 2
8 // of the License, or (at your option) any later version.
9 
10 #include "parser.h"
11 
12 
13 /****** Value method implementations *******/
14 
Value(double d)15 Value::Value(double d)
16 {
17     type = NumberType;
18     data.d = d;
19 }
20 
Value(string s)21 Value::Value(string s)
22 {
23     type = StringType;
24     data.s = new string(s);
25 }
26 
Value(Array * a)27 Value::Value(Array* a)
28 {
29     type = ArrayType;
30     data.a = a;
31 }
32 
Value(Hash * h)33 Value::Value(Hash* h)
34 {
35     type = HashType;
36     data.h = h;
37 }
38 
Value(bool b)39 Value::Value(bool b)
40 {
41     type = BooleanType;
42     data.d = b ? 1.0 : 0.0;
43 }
44 
~Value()45 Value::~Value()
46 {
47     if (type == StringType)
48     {
49         delete data.s;
50     }
51     else if (type == ArrayType)
52     {
53         if (data.a != NULL)
54         {
55             for (unsigned int i = 0; i < data.a->size(); i++)
56                 delete (*data.a)[i];
57             delete data.a;
58         }
59     }
60     else if (type == HashType)
61     {
62         if (data.h != NULL)
63         {
64 #if 0
65             Hash::iterator iter = data.h->begin();
66             while (iter != data.h->end())
67             {
68                 delete iter->second;
69                 iter++;
70             }
71 #endif
72             delete data.h;
73         }
74     }
75 }
76 
getType() const77 Value::ValueType Value::getType() const
78 {
79     return type;
80 }
81 
getNumber() const82 double Value::getNumber() const
83 {
84     // ASSERT(type == NumberType);
85     return data.d;
86 }
87 
getString() const88 string Value::getString() const
89 {
90     // ASSERT(type == StringType);
91     return *data.s;
92 }
93 
getArray() const94 Array* Value::getArray() const
95 {
96     // ASSERT(type == ArrayType);
97     return data.a;
98 }
99 
getHash() const100 Hash* Value::getHash() const
101 {
102     // ASSERT(type == HashType);
103     return data.h;
104 }
105 
getBoolean() const106 bool Value::getBoolean() const
107 {
108     // ASSERT(type == BooleanType);
109     return (data.d != 0.0);
110 }
111 
112 
113 /****** Parser method implementation ******/
114 
Parser(Tokenizer * _tokenizer)115 Parser::Parser(Tokenizer* _tokenizer) :
116     tokenizer(_tokenizer)
117 {
118 }
119 
120 
readArray()121 Array* Parser::readArray()
122 {
123     Tokenizer::TokenType tok = tokenizer->nextToken();
124     if (tok != Tokenizer::TokenBeginArray)
125     {
126         tokenizer->pushBack();
127         return NULL;
128     }
129 
130     Array* array = new Array();
131 
132     Value* v = readValue();
133     while (v != NULL)
134     {
135         array->insert(array->end(), v);
136         v = readValue();
137     }
138 
139     tok = tokenizer->nextToken();
140     if (tok != Tokenizer::TokenEndArray)
141     {
142         tokenizer->pushBack();
143         delete array;
144         return NULL;
145     }
146 
147     return array;
148 }
149 
150 
readHash()151 Hash* Parser::readHash()
152 {
153     Tokenizer::TokenType tok = tokenizer->nextToken();
154     if (tok != Tokenizer::TokenBeginGroup)
155     {
156         tokenizer->pushBack();
157         return NULL;
158     }
159 
160     Hash* hash = new Hash();
161 
162     tok = tokenizer->nextToken();
163     while (tok != Tokenizer::TokenEndGroup)
164     {
165         if (tok != Tokenizer::TokenName)
166         {
167             tokenizer->pushBack();
168             delete hash;
169             return NULL;
170         }
171         string name = tokenizer->getNameValue();
172 
173         Value* value = readValue();
174         if (value == NULL)
175         {
176             delete hash;
177             return NULL;
178         }
179 
180         hash->addValue(name, *value);
181 
182         tok = tokenizer->nextToken();
183     }
184 
185     return hash;
186 }
187 
188 
readValue()189 Value* Parser::readValue()
190 {
191     Tokenizer::TokenType tok = tokenizer->nextToken();
192     switch (tok)
193     {
194     case Tokenizer::TokenNumber:
195         return new Value(tokenizer->getNumberValue());
196 
197     case Tokenizer::TokenString:
198         return new Value(tokenizer->getStringValue());
199 
200     case Tokenizer::TokenName:
201         if (tokenizer->getNameValue() == "false")
202             return new Value(false);
203         else if (tokenizer->getNameValue() == "true")
204             return new Value(true);
205         else
206         {
207             tokenizer->pushBack();
208             return NULL;
209         }
210 
211     case Tokenizer::TokenBeginArray:
212         tokenizer->pushBack();
213         {
214             Array* array = readArray();
215             if (array == NULL)
216                 return NULL;
217             else
218                 return new Value(array);
219         }
220 
221     case Tokenizer::TokenBeginGroup:
222         tokenizer->pushBack();
223         {
224             Hash* hash = readHash();
225             if (hash == NULL)
226                 return NULL;
227             else
228                 return new Value(hash);
229         }
230 
231     default:
232         tokenizer->pushBack();
233         return NULL;
234     }
235 }
236 
237 
AssociativeArray()238 AssociativeArray::AssociativeArray()
239 {
240 }
241 
~AssociativeArray()242 AssociativeArray::~AssociativeArray()
243 {
244 #if 0
245     Hash::iterator iter = data.h->begin();
246     while (iter != data.h->end())
247     {
248         delete iter->second;
249         iter++;
250     }
251 #endif
252     for (map<string, Value*>::iterator iter = assoc.begin(); iter != assoc.end(); iter++)
253         delete iter->second;
254 }
255 
getValue(string key) const256 Value* AssociativeArray::getValue(string key) const
257 {
258     map<string, Value*>::const_iterator iter = assoc.find(key);
259     if (iter == assoc.end())
260         return NULL;
261     else
262         return iter->second;
263 }
264 
addValue(string key,Value & val)265 void AssociativeArray::addValue(string key, Value& val)
266 {
267     assoc.insert(map<string, Value*>::value_type(key, &val));
268 }
269 
getNumber(const string & key,double & val) const270 bool AssociativeArray::getNumber(const string& key, double& val) const
271 {
272     Value* v = getValue(key);
273     if (v == NULL || v->getType() != Value::NumberType)
274         return false;
275 
276     val = v->getNumber();
277 
278     return true;
279 }
280 
getNumber(const string & key,float & val) const281 bool AssociativeArray::getNumber(const string& key, float& val) const
282 {
283     double dval;
284 
285     if (!getNumber(key, dval))
286     {
287         return false;
288     }
289     else
290     {
291         val = (float) dval;
292         return true;
293     }
294 }
295 
getNumber(const string & key,int & val) const296 bool AssociativeArray::getNumber(const string& key, int& val) const
297 {
298     double ival;
299 
300     if (!getNumber(key, ival))
301     {
302         return false;
303     }
304     else
305     {
306         val = (int) ival;
307         return true;
308     }
309 }
310 
getNumber(const string & key,uint32 & val) const311 bool AssociativeArray::getNumber(const string& key, uint32& val) const
312 {
313     double ival;
314 
315     if (!getNumber(key, ival))
316     {
317         return false;
318     }
319     else
320     {
321         val = (uint32) ival;
322         return true;
323     }
324 }
325 
getString(const string & key,string & val) const326 bool AssociativeArray::getString(const string& key, string& val) const
327 {
328     Value* v = getValue(key);
329     if (v == NULL || v->getType() != Value::StringType)
330         return false;
331 
332     val = v->getString();
333 
334     return true;
335 }
336 
getBoolean(const string & key,bool & val) const337 bool AssociativeArray::getBoolean(const string& key, bool& val) const
338 {
339     Value* v = getValue(key);
340     if (v == NULL || v->getType() != Value::BooleanType)
341         return false;
342 
343     val = v->getBoolean();
344 
345     return true;
346 }
347 
getVector(const string & key,Vec3d & val) const348 bool AssociativeArray::getVector(const string& key, Vec3d& val) const
349 {
350     Value* v = getValue(key);
351     if (v == NULL || v->getType() != Value::ArrayType)
352         return false;
353 
354     Array* arr = v->getArray();
355     if (arr->size() != 3)
356         return false;
357 
358     Value* x = (*arr)[0];
359     Value* y = (*arr)[1];
360     Value* z = (*arr)[2];
361 
362     if (x->getType() != Value::NumberType ||
363         y->getType() != Value::NumberType ||
364         z->getType() != Value::NumberType)
365         return false;
366 
367     val = Vec3d(x->getNumber(), y->getNumber(), z->getNumber());
368 
369     return true;
370 }
371 
getVector(const string & key,Vec3f & val) const372 bool AssociativeArray::getVector(const string& key, Vec3f& val) const
373 {
374     Vec3d vecVal;
375 
376     if (!getVector(key, vecVal))
377         return false;
378 
379     val = Vec3f((float) vecVal.x, (float) vecVal.y, (float) vecVal.z);
380 
381     return true;
382 }
383 
384 
getRotation(const string & key,Quatf & val) const385 bool AssociativeArray::getRotation(const string& key, Quatf& val) const
386 {
387     Value* v = getValue(key);
388     if (v == NULL || v->getType() != Value::ArrayType)
389         return false;
390 
391     Array* arr = v->getArray();
392     if (arr->size() != 4)
393         return false;
394 
395     Value* w = (*arr)[0];
396     Value* x = (*arr)[1];
397     Value* y = (*arr)[2];
398     Value* z = (*arr)[3];
399 
400     if (w->getType() != Value::NumberType ||
401         x->getType() != Value::NumberType ||
402         y->getType() != Value::NumberType ||
403         z->getType() != Value::NumberType)
404         return false;
405 
406     Vec3f axis((float) x->getNumber(),
407                (float) y->getNumber(),
408                (float) z->getNumber());
409     axis.normalize();
410     float angle = degToRad((float) w->getNumber());
411     val.setAxisAngle(axis, angle);
412 
413     return true;
414 }
415 
getColor(const string & key,Color & val) const416 bool AssociativeArray::getColor(const string& key, Color& val) const
417 {
418     Vec3d vecVal;
419 
420     if (!getVector(key, vecVal))
421         return false;
422 
423     val = Color((float) vecVal.x, (float) vecVal.y, (float) vecVal.z);
424 
425     return true;
426 }
427 
428 
429 HashIterator
begin()430 AssociativeArray::begin()
431 {
432     return assoc.begin();
433 }
434 
435 
436 HashIterator
end()437 AssociativeArray::end()
438 {
439     return assoc.end();
440 }
441