00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "parser.h"
00011
00012
00013
00014
00015 Value::Value(double d)
00016 {
00017 type = NumberType;
00018 data.d = d;
00019 }
00020
00021 Value::Value(string s)
00022 {
00023 type = StringType;
00024 data.s = new string(s);
00025 }
00026
00027 Value::Value(Array* a)
00028 {
00029 type = ArrayType;
00030 data.a = a;
00031 }
00032
00033 Value::Value(Hash* h)
00034 {
00035 type = HashType;
00036 data.h = h;
00037 }
00038
00039 Value::Value(bool b)
00040 {
00041 type = BooleanType;
00042 data.d = b ? 1.0 : 0.0;
00043 }
00044
00045 Value::~Value()
00046 {
00047 if (type == StringType)
00048 {
00049 delete data.s;
00050 }
00051 else if (type == ArrayType)
00052 {
00053 if (data.a != NULL)
00054 {
00055 for (unsigned int i = 0; i < data.a->size(); i++)
00056 delete (*data.a)[i];
00057 delete data.a;
00058 }
00059 }
00060 else if (type == HashType)
00061 {
00062 if (data.h != NULL)
00063 {
00064 #if 0
00065 Hash::iterator iter = data.h->begin();
00066 while (iter != data.h->end())
00067 {
00068 delete iter->second;
00069 iter++;
00070 }
00071 #endif
00072 delete data.h;
00073 }
00074 }
00075 }
00076
00077 Value::ValueType Value::getType() const
00078 {
00079 return type;
00080 }
00081
00082 double Value::getNumber() const
00083 {
00084
00085 return data.d;
00086 }
00087
00088 string Value::getString() const
00089 {
00090
00091 return *data.s;
00092 }
00093
00094 Array* Value::getArray() const
00095 {
00096
00097 return data.a;
00098 }
00099
00100 Hash* Value::getHash() const
00101 {
00102
00103 return data.h;
00104 }
00105
00106 bool Value::getBoolean() const
00107 {
00108
00109 return (data.d != 0.0);
00110 }
00111
00112
00113
00114
00115 Parser::Parser(Tokenizer* _tokenizer) :
00116 tokenizer(_tokenizer)
00117 {
00118 }
00119
00120
00121 Array* Parser::readArray()
00122 {
00123 Tokenizer::TokenType tok = tokenizer->nextToken();
00124 if (tok != Tokenizer::TokenBeginArray)
00125 {
00126 tokenizer->pushBack();
00127 return NULL;
00128 }
00129
00130 Array* array = new Array();
00131
00132 Value* v = readValue();
00133 while (v != NULL)
00134 {
00135 array->insert(array->end(), v);
00136 v = readValue();
00137 }
00138
00139 tok = tokenizer->nextToken();
00140 if (tok != Tokenizer::TokenEndArray)
00141 {
00142 tokenizer->pushBack();
00143 delete array;
00144 return NULL;
00145 }
00146
00147 return array;
00148 }
00149
00150
00151 Hash* Parser::readHash()
00152 {
00153 Tokenizer::TokenType tok = tokenizer->nextToken();
00154 if (tok != Tokenizer::TokenBeginGroup)
00155 {
00156 tokenizer->pushBack();
00157 return NULL;
00158 }
00159
00160 Hash* hash = new Hash();
00161
00162 tok = tokenizer->nextToken();
00163 while (tok != Tokenizer::TokenEndGroup)
00164 {
00165 if (tok != Tokenizer::TokenName)
00166 {
00167 tokenizer->pushBack();
00168 delete hash;
00169 return NULL;
00170 }
00171 string name = tokenizer->getNameValue();
00172
00173 Value* value = readValue();
00174 if (value == NULL)
00175 {
00176 delete hash;
00177 return NULL;
00178 }
00179
00180 hash->addValue(name, *value);
00181
00182 tok = tokenizer->nextToken();
00183 }
00184
00185 return hash;
00186 }
00187
00188
00189 Value* Parser::readValue()
00190 {
00191 Tokenizer::TokenType tok = tokenizer->nextToken();
00192 switch (tok)
00193 {
00194 case Tokenizer::TokenNumber:
00195 return new Value(tokenizer->getNumberValue());
00196
00197 case Tokenizer::TokenString:
00198 return new Value(tokenizer->getStringValue());
00199
00200 case Tokenizer::TokenName:
00201 if (tokenizer->getNameValue() == "false")
00202 return new Value(false);
00203 else if (tokenizer->getNameValue() == "true")
00204 return new Value(true);
00205 else
00206 {
00207 tokenizer->pushBack();
00208 return NULL;
00209 }
00210
00211 case Tokenizer::TokenBeginArray:
00212 tokenizer->pushBack();
00213 {
00214 Array* array = readArray();
00215 if (array == NULL)
00216 return NULL;
00217 else
00218 return new Value(array);
00219 }
00220
00221 case Tokenizer::TokenBeginGroup:
00222 tokenizer->pushBack();
00223 {
00224 Hash* hash = readHash();
00225 if (hash == NULL)
00226 return NULL;
00227 else
00228 return new Value(hash);
00229 }
00230
00231 default:
00232 tokenizer->pushBack();
00233 return NULL;
00234 }
00235 }
00236
00237
00238 AssociativeArray::AssociativeArray()
00239 {
00240 }
00241
00242 AssociativeArray::~AssociativeArray()
00243 {
00244 #if 0
00245 Hash::iterator iter = data.h->begin();
00246 while (iter != data.h->end())
00247 {
00248 delete iter->second;
00249 iter++;
00250 }
00251 #endif
00252 for (map<string, Value*>::iterator iter = assoc.begin(); iter != assoc.end(); iter++)
00253 delete iter->second;
00254 }
00255
00256 Value* AssociativeArray::getValue(string key) const
00257 {
00258 map<string, Value*>::const_iterator iter = assoc.find(key);
00259 if (iter == assoc.end())
00260 return NULL;
00261 else
00262 return iter->second;
00263 }
00264
00265 void AssociativeArray::addValue(string key, Value& val)
00266 {
00267 assoc.insert(map<string, Value*>::value_type(key, &val));
00268 }
00269
00270 bool AssociativeArray::getNumber(const string& key, double& val) const
00271 {
00272 Value* v = getValue(key);
00273 if (v == NULL || v->getType() != Value::NumberType)
00274 return false;
00275
00276 val = v->getNumber();
00277
00278 return true;
00279 }
00280
00281 bool AssociativeArray::getNumber(const string& key, float& val) const
00282 {
00283 double dval;
00284
00285 if (!getNumber(key, dval))
00286 {
00287 return false;
00288 }
00289 else
00290 {
00291 val = (float) dval;
00292 return true;
00293 }
00294 }
00295
00296 bool AssociativeArray::getNumber(const string& key, int& val) const
00297 {
00298 double ival;
00299
00300 if (!getNumber(key, ival))
00301 {
00302 return false;
00303 }
00304 else
00305 {
00306 val = (int) ival;
00307 return true;
00308 }
00309 }
00310
00311 bool AssociativeArray::getString(const string& key, string& val) const
00312 {
00313 Value* v = getValue(key);
00314 if (v == NULL || v->getType() != Value::StringType)
00315 return false;
00316
00317 val = v->getString();
00318
00319 return true;
00320 }
00321
00322 bool AssociativeArray::getBoolean(const string& key, bool& val) const
00323 {
00324 Value* v = getValue(key);
00325 if (v == NULL || v->getType() != Value::BooleanType)
00326 return false;
00327
00328 val = v->getBoolean();
00329
00330 return true;
00331 }
00332
00333 bool AssociativeArray::getVector(const string& key, Vec3d& val) const
00334 {
00335 Value* v = getValue(key);
00336 if (v == NULL || v->getType() != Value::ArrayType)
00337 return false;
00338
00339 Array* arr = v->getArray();
00340 if (arr->size() != 3)
00341 return false;
00342
00343 Value* x = (*arr)[0];
00344 Value* y = (*arr)[1];
00345 Value* z = (*arr)[2];
00346
00347 if (x->getType() != Value::NumberType ||
00348 y->getType() != Value::NumberType ||
00349 z->getType() != Value::NumberType)
00350 return false;
00351
00352 val = Vec3d(x->getNumber(), y->getNumber(), z->getNumber());
00353
00354 return true;
00355 }
00356
00357 bool AssociativeArray::getVector(const string& key, Vec3f& val) const
00358 {
00359 Vec3d vecVal;
00360
00361 if (!getVector(key, vecVal))
00362 return false;
00363
00364 val = Vec3f((float) vecVal.x, (float) vecVal.y, (float) vecVal.z);
00365
00366 return true;
00367 }
00368
00369
00370 bool AssociativeArray::getRotation(const string& key, Quatf& val) const
00371 {
00372 Value* v = getValue(key);
00373 if (v == NULL || v->getType() != Value::ArrayType)
00374 return false;
00375
00376 Array* arr = v->getArray();
00377 if (arr->size() != 4)
00378 return false;
00379
00380 Value* w = (*arr)[0];
00381 Value* x = (*arr)[1];
00382 Value* y = (*arr)[2];
00383 Value* z = (*arr)[3];
00384
00385 if (w->getType() != Value::NumberType ||
00386 x->getType() != Value::NumberType ||
00387 y->getType() != Value::NumberType ||
00388 z->getType() != Value::NumberType)
00389 return false;
00390
00391 Vec3f axis((float) x->getNumber(),
00392 (float) y->getNumber(),
00393 (float) z->getNumber());
00394 axis.normalize();
00395 float angle = degToRad((float) w->getNumber());
00396 val.setAxisAngle(axis, angle);
00397
00398 return true;
00399 }
00400
00401 bool AssociativeArray::getColor(const string& key, Color& val) const
00402 {
00403 Vec3d vecVal;
00404
00405 if (!getVector(key, vecVal))
00406 return false;
00407
00408 val = Color((float) vecVal.x, (float) vecVal.y, (float) vecVal.z);
00409
00410 return true;
00411 }