00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdio.h>
00016 #include <iostream>
00017 #include <assert.h>
00018
00019 #include "XmlOdb.h"
00020
00021 #include <TList.h>
00022
00023 XmlOdb::XmlOdb(const char*xbuf,int bufLength)
00024 {
00025 fOdb = NULL;
00026 fParser = new TDOMParser();
00027 fParser->SetValidate(false);
00028
00029 char*buf = (char*)malloc(bufLength);
00030 memcpy(buf, xbuf, bufLength);
00031 for (int i=0; i<bufLength; i++)
00032 if (!isascii(buf[i]))
00033 buf[i] = 'X';
00034 else if (buf[i]=='\n')
00035 0;
00036 else if (buf[i]=='\r')
00037 0;
00038 else if (!isprint(buf[i]))
00039 buf[i] = 'X';
00040 else if (buf[i] == 0x1D)
00041 buf[i] = 'X';
00042
00043 char* xend = strstr(buf,"odb>");
00044 if (xend)
00045 xend[4] = 0;
00046
00047
00048
00049 fParser->ParseBuffer(buf,bufLength);
00050
00051 TXMLDocument* doc = fParser->GetXMLDocument();
00052 if (!doc)
00053 {
00054 fprintf(stderr,"XmlOdb::XmlOdb: Malformed ODB dump: cannot get XML document\n");
00055 return;
00056 }
00057
00058 fOdb = FindNode(doc->GetRootNode(),"odb");
00059 if (!fOdb)
00060 {
00061 fprintf(stderr,"XmlOdb::XmlOdb: Malformed ODB dump: cannot find <odb> tag\n");
00062 return;
00063 }
00064 }
00065
00066 XmlOdb::XmlOdb(const char* filename)
00067 {
00068 fOdb = NULL;
00069 fParser = new TDOMParser();
00070 fParser->SetValidate(false);
00071
00072 int status = fParser->ParseFile(filename);
00073 if (status != 0)
00074 {
00075 fprintf(stderr,"XmlOdb::XmlOdb: Failed to parse XML file \'%s\', ParseFile() returned %d\n", filename, status);
00076 return;
00077 }
00078
00079 TXMLDocument* doc = fParser->GetXMLDocument();
00080 if (!doc)
00081 {
00082 fprintf(stderr,"XmlOdb::XmlOdb: Malformed ODB dump: cannot get XML document\n");
00083 return;
00084 }
00085
00086 fOdb = FindNode(doc->GetRootNode(),"odb");
00087 if (!fOdb)
00088 {
00089 fprintf(stderr,"XmlOdb::XmlOdb: Malformed ODB dump: cannot find <odb> tag\n");
00090 return;
00091 }
00092 }
00093
00094 XmlOdb::~XmlOdb()
00095 {
00096 delete fParser;
00097 fParser = NULL;
00098 }
00099
00100 TXMLNode* XmlOdb::FindNode(TXMLNode*node, const char*name)
00101 {
00102 for (; node != NULL; node = node->GetNextNode())
00103 {
00104
00105 if (strcmp(node->GetNodeName(),name) == 0)
00106 return node;
00107
00108 if (node->HasChildren())
00109 {
00110 TXMLNode* found = FindNode(node->GetChildren(),name);
00111 if (found)
00112 return found;
00113 }
00114 }
00115
00116 return NULL;
00117 }
00118
00119 void XmlOdb::DumpTree(TXMLNode*node,int level)
00120 {
00121 if (!node)
00122 node = fOdb;
00123
00124 if (!node)
00125 {
00126 fprintf(stderr,"XmlOdb::DumpTree: node is NULL!\n");
00127 return;
00128 }
00129
00130 while (node)
00131 {
00132 for (int i=0; i<level; i++)
00133 printf(" ");
00134 printf("node name: \"%s\"\n",node->GetNodeName());
00135 TList* attrs = node->GetAttributes();
00136 TIter next(attrs);
00137 while (TXMLAttr *attr = (TXMLAttr*)next())
00138 {
00139 for (int i=0; i<level; i++)
00140 printf(" ");
00141 printf("attribute name: \"%s\", value: \"%s\"\n",attr->GetName(),attr->GetValue());
00142 }
00143 const char*text = node->GetText();
00144 if (text)
00145 {
00146 for (int i=0; i<level; i++)
00147 printf(" ");
00148 printf("node text: \"%s\"\n",node->GetText());
00149 }
00150 if (node->HasChildren())
00151 DumpTree(node->GetChildren(),level + 1);
00152 node = node->GetNextNode();
00153 }
00154
00155 }
00156
00157 void XmlOdb::DumpDirTree(TXMLNode*node,int level)
00158 {
00159 if (!node)
00160 node = fOdb;
00161
00162 if (!node)
00163 {
00164 fprintf(stderr,"XmlOdb::DumpDirTree: node is NULL!\n");
00165 return;
00166 }
00167
00168 for (; node != NULL; node = node->GetNextNode())
00169 {
00170 const char* name = node->GetNodeName();
00171
00172 if (strcmp(name,"dir") != 0)
00173 continue;
00174
00175 for (int i=0; i<level; i++)
00176 printf(" ");
00177 printf("node name: \"%s\"\n",node->GetNodeName());
00178 TList* attrs = node->GetAttributes();
00179 TIter next(attrs);
00180 while (TXMLAttr *attr = (TXMLAttr*)next())
00181 {
00182 for (int i=0; i<level; i++)
00183 printf(" ");
00184 printf("attribute name: \"%s\", value: \"%s\"\n",attr->GetName(),attr->GetValue());
00185 }
00186 if (node->HasChildren())
00187 DumpDirTree(node->GetChildren(),level + 1);
00188 }
00189
00190 }
00191
00192
00193
00194
00195 const char* XmlOdb::GetAttrValue(TXMLNode*node,const char*attrName)
00196 {
00197 TList* attrs = node->GetAttributes();
00198 TIter next(attrs);
00199 while (TXMLAttr *attr = (TXMLAttr*)next())
00200 {
00201
00202
00203 if (strcmp(attr->GetName(),attrName)==0)
00204 return attr->GetValue();
00205 }
00206 return NULL;
00207 }
00208
00209
00210
00211
00212 TXMLNode* XmlOdb::FindPath(TXMLNode*node,const char* path)
00213 {
00214 if (!fOdb)
00215 return NULL;
00216
00217 if (!node)
00218 node = fOdb->GetChildren();
00219
00220 while (1)
00221 {
00222
00223 while (*path == '/')
00224 path++;
00225
00226 if (*path == 0)
00227 return node;
00228
00229 const int kElemSize = 256;
00230 char elem[kElemSize+1];
00231 memset(elem,0,kElemSize+1);
00232
00233
00234
00235 for (int i=0; i<kElemSize; i++)
00236 {
00237 if (*path==0 || *path=='/')
00238 break;
00239 elem[i] = *path++;
00240 }
00241
00242
00243
00244 for (; node != NULL; node = node->GetNextNode())
00245 {
00246 const char* nodename = node->GetNodeName();
00247 const char* namevalue = GetAttrValue(node,"name");
00248
00249
00250
00251 bool isDir = strcmp(nodename,"dir") == 0;
00252 bool isKey = strcmp(nodename,"key") == 0;
00253 bool isKeyArray = strcmp(nodename,"keyarray") == 0;
00254
00255 if (!isKey && !isDir && !isKeyArray)
00256 continue;
00257
00258
00259
00260
00261
00262 if (strcasecmp(elem,namevalue) == 0)
00263 {
00264 if (isDir)
00265 {
00266
00267 node = node->GetChildren();
00268 break;
00269 }
00270 else if (isKey || isKeyArray)
00271 {
00272 return node;
00273 }
00274 }
00275 }
00276 }
00277 }
00278
00279
00280
00281
00282 TXMLNode* XmlOdb::FindArrayPath(TXMLNode*node,const char* path,const char* type,int index)
00283 {
00284 if (!fOdb)
00285 return NULL;
00286
00287 if (!node)
00288 node = fOdb->GetChildren();
00289
00290 node = FindPath(node, path);
00291
00292 if (!node)
00293 return NULL;
00294
00295 const char* nodename = node->GetNodeName();
00296 const char* num_values = GetAttrValue(node,"num_values");
00297
00298 const char* typevalue = GetAttrValue(node,"type");
00299
00300 if (!typevalue || (strcasecmp(typevalue,type) != 0))
00301 {
00302 fprintf(stderr,"XmlOdb::FindArrayPath: Type mismatch: \'%s\' has type \'%s\', we expected \'%s\'\n", path, typevalue, type);
00303 return NULL;
00304 }
00305
00306 bool isKeyArray = (num_values!=NULL) && (strcmp(nodename,"keyarray")==0);
00307
00308 if (!isKeyArray)
00309 {
00310 if (index != 0)
00311 {
00312 fprintf(stderr,"XmlOdb::FindArrayPath: Attempt to access array element %d, but \'%s\' is not an array\n", index, path);
00313 return NULL;
00314 }
00315
00316 return node;
00317 }
00318
00319 int max_index = atoi(num_values);
00320
00321 if (index < 0 || index >= max_index)
00322 {
00323 fprintf(stderr,"XmlOdb::FindArrayPath: Attempt to access array element %d, but size of array \'%s\' is %d\n", index, path, max_index);
00324 return NULL;
00325 }
00326
00327
00328
00329 TXMLNode* elem = node->GetChildren();
00330
00331 for (int i=0; elem!=NULL; )
00332 {
00333 const char* name = elem->GetNodeName();
00334 const char* text = elem->GetText();
00335
00336
00337 if (strcmp(name,"value") == 0)
00338 {
00339 if (i == index)
00340 return elem;
00341 i++;
00342 }
00343
00344 elem = elem->GetNextNode();
00345 }
00346
00347
00348 return node;
00349 }
00350
00351 int XmlOdb::odbReadAny( const char*name, int index, int tid,void* buf, int bufsize) { assert(!"Not implemented!"); }
00352
00353 uint32_t XmlOdb::odbReadUint32(const char*name, int index, uint32_t defaultValue)
00354 {
00355 TXMLNode *node = FindArrayPath(NULL,name,"DWORD",index);
00356 if (!node)
00357 return defaultValue;
00358 const char* text = node->GetText();
00359 if (!text)
00360 return defaultValue;
00361 return strtoul(text,NULL,0);
00362 }
00363
00364 double XmlOdb::odbReadDouble(const char*name, int index, double defaultValue)
00365 {
00366 TXMLNode *node = FindArrayPath(NULL,name,"DOUBLE",index);
00367 if (!node)
00368 return defaultValue;
00369 const char* text = node->GetText();
00370 if (!text)
00371 return defaultValue;
00372 return atof(text);
00373 }
00374
00375 float XmlOdb::odbReadFloat(const char*name, int index, float defaultValue)
00376 {
00377 TXMLNode *node = FindArrayPath(NULL,name,"FLOAT",index);
00378 if (!node)
00379 return defaultValue;
00380 const char* text = node->GetText();
00381 if (!text)
00382 return defaultValue;
00383 return atof(text);
00384 }
00385
00386 int XmlOdb::odbReadInt( const char*name, int index, int defaultValue)
00387 {
00388 TXMLNode *node = FindArrayPath(NULL,name,"INT",index);
00389 if (!node)
00390 return defaultValue;
00391 const char* text = node->GetText();
00392 if (!text)
00393 return defaultValue;
00394 return atoi(text);
00395
00396
00397
00398 return 0;
00399 }
00400
00401 bool XmlOdb::odbReadBool( const char*name, int index, bool defaultValue)
00402 {
00403 TXMLNode *node = FindArrayPath(NULL,name,"BOOL",index);
00404 if (!node)
00405 return defaultValue;
00406 const char* text = node->GetText();
00407 if (!text)
00408 return defaultValue;
00409 if (*text == 'n')
00410 return false;
00411 return true;
00412 }
00413
00414 const char* XmlOdb::odbReadString(const char* name, int index, const char* defaultValue)
00415 {
00416 TXMLNode *node = FindArrayPath(NULL, name, "STRING", index);
00417 if (!node)
00418 return defaultValue;
00419 const char* text = node->GetText();
00420 if (!text)
00421 return defaultValue;
00422 return text;
00423 }
00424
00425 int XmlOdb::odbReadArraySize(const char*name)
00426 {
00427 TXMLNode *node = FindPath(NULL,name);
00428 if (!node)
00429 return 0;
00430 const char* num_values = GetAttrValue(node,"num_values");
00431 if (!num_values)
00432 return 1;
00433 return atoi(num_values);
00434 }
00435
00436