XmlOdb.cxx

Go to the documentation of this file.
00001 //
00002 // ALPHA ROOT analyzer
00003 //
00004 // Name: XmlOdb.cxx
00005 // Author: K.Olchanski, 11-July-2006
00006 //
00007 // $Id$
00008 //
00009 // $Log: XmlOdb.cxx,v $
00010 // Revision 1.1  2006/07/11 18:53:18  alpha
00011 // KO- code to access to ODB from XML ODB dumps in MIDAS data files
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) //ctor
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   //printf("end: %s\n", buf+bufLength-5);
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) //ctor
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() // dtor
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       //printf("node name: \"%s\"\n",node->GetNodeName());
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   //printf("no more next nodes...\n");
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   //printf("no more next nodes...\n");
00190 }
00191 
00192 //
00193 // Return the value of the named attribute
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       //printf("attribute name: \"%s\", value: \"%s\"\n",attr->GetName(),attr->GetValue());
00202       
00203       if (strcmp(attr->GetName(),attrName)==0)
00204         return attr->GetValue();
00205     }
00206   return NULL;
00207 }
00208 
00209 //
00210 // Follow the ODB path through the XML DOM tree
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       // skip leading slashes
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       // copy the next path element into "elem"-
00234       // copy "path" until we hit "/" or end of string
00235       for (int i=0; i<kElemSize; i++)
00236         {
00237           if (*path==0 || *path=='/')
00238             break;
00239           elem[i] = *path++;
00240         }
00241       
00242       //printf("looking for \"%s\" more \"%s\"\n",elem,path);
00243       
00244       for (; node != NULL; node = node->GetNextNode())
00245         {
00246           const char* nodename = node->GetNodeName();
00247           const char* namevalue = GetAttrValue(node,"name");
00248           
00249           //printf("node name: \"%s\", \"name\" value: \"%s\"\n",node->GetNodeName(),namevalue);
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           // compare directory names
00260           //
00261           
00262           if (strcasecmp(elem,namevalue) == 0)
00263             {
00264               if (isDir)
00265                 {
00266                   // found the right subdirectory, descend into it
00267                   node = node->GetChildren();
00268                   break;
00269                 }
00270               else if (isKey || isKeyArray)
00271                 {
00272                   return node;
00273                 }
00274             }
00275         }
00276     }
00277 }
00278 
00279 //
00280 // Follow the ODB path through the XML DOM tree
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   //printf("nodename [%s]\n", nodename);
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       //printf("index %d, name [%s] text [%s]\n", i, name, text);
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   //printf("for \'%s\', type is \'%s\', text is \'%s\'\n", name, typevalue, text);
00396   //DumpTree(node);
00397   //exit(1);
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 //end

Generated on 12 Feb 2016 for ROOT Analyzer by  doxygen 1.6.1