StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StDbXmlReader.cc
1 /***************************************************************************
2  *
3  * $Id: StDbXmlReader.cc,v 1.19 2016/05/27 16:26:23 dmitry Exp $
4  *
5  * Author: R. Jeff Porter
6  ***************************************************************************
7  *
8  * Description: implement typeAcceptor for READING XML files of DB-tables
9  *
10  ***************************************************************************
11  *
12  * $Log: StDbXmlReader.cc,v $
13  * Revision 1.19 2016/05/27 16:26:23 dmitry
14  * more coverity
15  *
16  * Revision 1.18 2016/05/25 21:01:30 dmitry
17  * coverity - buffer size
18  *
19  * Revision 1.17 2015/05/15 19:11:44 dmitry
20  * typo, now doing proper deallocation
21  *
22  * Revision 1.16 2015/05/15 19:07:09 dmitry
23  * small memory leak fixed
24  *
25  * Revision 1.15 2012/06/11 14:33:47 fisyak
26  * std namespace
27  *
28  * Revision 1.14 2007/08/20 18:21:31 deph
29  * New Version of Load Balancer
30  *
31  * Revision 1.13 2007/05/16 22:48:10 deph
32  * Replaced cerr with LOG_ERROR <<endm; for logger
33  *
34  * Revision 1.12 2004/01/15 00:02:25 fisyak
35  * Replace ostringstream => StString, add option for alpha
36  *
37  * Revision 1.11 2003/09/16 22:44:18 porter
38  * got rid of all ostrstream objects; replaced with StString+string.
39  * modified rules.make and added file stdb_streams.h for standalone compilation
40  *
41  * Revision 1.10 2003/09/02 17:57:50 perev
42  * gcc 3.2 updates + WarnOff
43  *
44  * Revision 1.9 2001/10/24 04:05:20 porter
45  * added long long type to I/O and got rid of obsolete dataIndex table
46  *
47  * Revision 1.8 2001/01/22 18:38:02 porter
48  * Update of code needed in next year running. This update has little
49  * effect on the interface (only 1 method has been changed in the interface).
50  * Code also preserves backwards compatibility so that old versions of
51  * StDbLib can read new table structures.
52  * -Important features:
53  * a. more efficient low-level table structure (see StDbSql.cc)
54  * b. more flexible indexing for new systems (see StDbElememtIndex.cc)
55  * c. environment variable override KEYS for each database
56  * d. StMessage support & clock-time logging diagnostics
57  * -Cosmetic features
58  * e. hid stl behind interfaces (see new *Impl.* files) to again allow rootcint access
59  * f. removed codes that have been obsolete for awhile (e.g. db factories)
60  * & renamed some classes for clarity (e.g. tableQuery became StDataBaseI
61  * and mysqlAccessor became StDbSql)
62  *
63  * Revision 1.7 2000/01/10 20:37:55 porter
64  * expanded functionality based on planned additions or feedback from Online work.
65  * update includes:
66  * 1. basis for real transaction model with roll-back
67  * 2. limited SQL access via the manager for run-log & tagDb
68  * 3. balance obtained between enumerated & string access to databases
69  * 4. 3-levels of diagnostic output: Quiet, Normal, Verbose
70  * 5. restructured Node model for better XML support
71  *
72  * Revision 1.6 1999/12/07 21:25:25 porter
73  * some fixes for linux warnings
74  *
75  * Revision 1.5 1999/12/03 17:03:22 porter
76  * added multi-row support for the Xml reader & writer
77  *
78  * Revision 1.4 1999/09/30 02:06:11 porter
79  * add StDbTime to better handle timestamps, modify SQL content (mysqlAccessor)
80  * allow multiple rows (StDbTable), & Added the comment sections at top of
81  * each header and src file
82  *
83  **************************************************************************/
84 #include "StDbXmlReader.h"
85 #include "stdb_streams.h"
86 #include <string.h>
87 
88 #include "dbStruct.hh"
89 
90 #ifndef __STDB_STANDALONE__
91 #include "StMessMgr.h"
92 #else
93 #define LOG_DEBUG cout
94 #define LOG_INFO cout
95 #define LOG_WARN cout
96 #define LOG_ERROR cerr
97 #define LOG_FATAL cerr
98 #define LOG_QA cout
99 #define endm "\n"
100 #endif
101 using namespace std;
102 template<class T>
103 static void passAux(elem* e, T*& i, int& len)
104 {
105  len = e->size.isize;
106  i = new T[len];
107  memset(i,0,sizeof(T)*len);
108  const char* p1 = e->val.data;
109  const char* p2=p1;
110  int iloop = 0;
111  for(;1;p2++) {
112  if (p2[0] && p2[0]!=',') continue;
113  i[iloop++] = (T)atof(p1);
114  p1=p2+1;
115  if (iloop==len || p2[0]==0) break;
116  }
117 }
118 
119 //----------------------------------------------------
120 StDbXmlReader::StDbXmlReader(){ tab = new dbTable(); }
121 
122 //----------------------------------------------------
123 
124 StDbXmlReader::~StDbXmlReader() { delete tab; }
125 
126 //----------------------------------------------------
127 elem*
128 StDbXmlReader::findElement(char* name){
129 
130 elem* e = 0;
131 elem* retVal = 0;
132 
133 int k;
134 // check accessor 1st
135 // here it's a bit scary : if accessor element has same name as data-element
136  if(tab->curRow==-1){
137  for(k=0;k<tab->a.nelems;k++){
138  e=tab->a.e[k];
139  if(strcmp(name,e->name)==0){
140  retVal=e;
141  break;
142  }
143  }
144  }
145 
146  if(!retVal){ // now check rows
147  if(tab->curRow==-1)tab->curRow=0; // init row
148  if(tab->curRow==tab->numRows)return retVal;
149  for(k=0;k<tab->row[tab->curRow]->nelems;k++){
150  // cout <<k<<" elements = " << tab->nelems << endl;
151  e=tab->row[tab->curRow]->e[k];
152  if(strcmp(name,e->name)==0){
153  retVal=e;
154  break;
155  }
156  }
157  if(k==tab->row[tab->curRow]->nelems-1)tab->curRow++;
158  }
159 
160 return retVal;
161 }
162 
163 //----------------------------------------------------
164 
165 //----------------------------------------------------
166 
167 void
168 StDbXmlReader::readTable(ifstream &is){
169 
170  int done = 0;
171  int i = 0;
172  int j,icount,k;
173  char tmp[2];
174  char line[256];
175  char line2[256];
176 
177  while(!done){
178  if(is.eof()){
179  done = 1;
180  } else {
181  // cout << "line . " << i << endl;
182  is.getline(line,255);
183  k = strlen(line);
184  j = 0;
185  line2[j]='\0';
186  char* ptr=&line2[0];
187  for(icount=0;icount<k;icount++){
188  if(!(line[icount]==' ')){
189  *tmp=line[icount];
190  tmp[1]='\0';
191  j++;
192  strncpy(ptr,tmp,1);
193  ptr++;
194  }
195  }
196  line2[j]='\0';
197  // cout << line << endl;
198  loca[i] = new char[strlen(line2)+1];
199  strcpy(loca[i],line2);
200  // cout << "line i = "<< loca[i] << endl;
201  i++;
202  }
203  }
204 
205 maxlines = i-1;
206 
207 buildDbTable();
208 
209 }
210 
211 //-----------------------------------------------------------
212 
213 
214 void
215 StDbXmlReader::buildDbTable(){
216 
217  int done = 0;
218  int j=0;
219 
220  // find table start
221  while (!done) {
222  if(strstr(loca[j],tab->startKey)){
223  tab->istart = j;
224  done = 1;
225  }
226  j++;
227  }
228 
229  // find accessor start
230  j=tab->istart+1;
231  done = 0;
232  while (!done) {
233  // cout << loca[j] << endl;
234  if(strstr(loca[j],(tab->a).startKey)){
235  (tab->a).istart = j;
236  done = 1;
237  }
238  j++;
239  }
240 
241  // if(j>=maxlines)cout << "1 j to big " << j << " max= " << maxlines << endl;
242 
243  elem* e0;
244  elem *e = new elem(); // key holder
245  // (tab->a).e.push_back(e)
246  done = 0;
247  int nelems = 0;
248  j=(tab->a).istart+1;
249  // if(j>=maxlines)cout << "2 j to big " << j << " max= " << maxlines << endl;
250  while (!done) {
251  if(strstr(loca[j],e->startKey)){
252  e0 = new elem();
253  e0->istart = j;
254  (tab->a).e.push_back(e0);
255  nelems++;
256  if(strstr(loca[j],e->endKey))e0->iend = j;
257  } else if(strstr(loca[j],e->endKey)){
258  e0->iend = j;
259  } else if(strstr(loca[j],(tab->a).endKey)){
260  if(strstr(loca[j],e->endKey))e0->iend = j;
261  (tab->a).iend = j;
262  (tab->a).nelems = nelems;
263  done = 1;
264  }
265  j++;
266  }
267 
268  // end of accessor
269  // find all rows
270  j=(tab->a).iend+1;
271  // if(j>=maxlines)cout << "3 j to big " << j << " max= " << maxlines << endl;
272  dbRow row;
273  dbRow* row0;
274 
275  done = 0;
276  int numRows = 0;
277  while (!done) {
278  if(strstr(loca[j],row.startKey)){
279  row0 = new dbRow();
280  row0->istart = j;
281  if(strstr(loca[j],row.endKey))row0->iend = j;
282  tab->row.push_back(row0);
283  row0->rowNumber = numRows;
284  numRows++;
285  } else if(strstr(loca[j],tab->endKey)){
286  tab->iend = j;
287  tab->numRows = numRows;
288  tab->curRow = -1;
289  done = 1;
290  }
291  j++;
292  }
293 
294  // cout << "Numrows = " << numRows<< endl;
295  // cout << "Current Row = " << tab->curRow << endl;
296  //
297  // Loop over rows
298  //
299  for(int nrows=0; nrows<tab->numRows; nrows++){
300  done = 0;
301  nelems = 0;
302  j=tab->row[nrows]->istart;
303  while (!done) {
304  // cout << loca[j] << endl;
305  if(strstr(loca[j],e->startKey)){
306  e0 = new elem();
307  e0->istart = j;
308  tab->row[nrows]->e.push_back(e0);
309  nelems++;
310  if(strstr(loca[j],e->endKey))e0->iend = j;
311  // cout<<"estart"<< loca[j] <<endl;
312  } else if(strstr(loca[j],e->endKey)){
313  e0->iend = j;
314  // cout<<"eend"<< loca[j] <<endl;
315  } else if(strstr(loca[j],row.endKey)){
316  tab->row[nrows]->nelems = nelems;
317  done = 1;
318  // cout<<"rowend"<< loca[j] <<endl;
319  }
320  j++;
321  }
322  }
323 
324 buildStruct();
325  delete e;
326 }
327 
328 //-----------------------------------------------------------
329 
330 void
331 StDbXmlReader::buildStruct(){
332 
333  char * p1 = strstr(loca[tab->istart],tab->startKey);
334  int len = strlen(tab->startKey);
335  int k;
336  for(k=0;k<len+1;k++)p1++;
337 
338  char* tmpName = new char[strlen(p1)+1];
339  strcpy(tmpName,p1);
340  char* id;
341 
342  if((id=strstr(tmpName,"<")))*id='\0';
343  tab->name=new char[strlen(tmpName)+1];
344  strcpy(tab->name,tmpName);
345  delete [] tmpName;
346 
347  accessor * a = &(tab->a);
348  fillElements(a);
349  // a = (accessor*)(tab);
350 
351  len = strlen(tab->row[0]->startKey);
352 
353  for(int n=0; n<tab->numRows;n++){
354 
355  // 1st get rowID (elementID) of this row
356  p1 = strstr(loca[tab->row[n]->istart],tab->row[n]->startKey);
357  for(k=0;k<len+1;k++)p1++;
358  tmpName = new char[strlen(p1)+1];
359  strcpy(tmpName,p1);
360  if((id=strstr(tmpName,"<")))*id='\0';
361  tab->row[n]->rowID = atoi(tmpName);
362  delete [] tmpName;
363 
364  // now get row values
365 
366  a = (accessor*)(tab->row[n]);
367  fillElements(a);
368 
369  }
370 
371 }
372 
373 //-----------------------------------------------------------
374 
375 void
376 StDbXmlReader::fillElements(accessor* a){
377 
378 elem* e;
379 int len,j;
380 char *p1 = 0, *p2 = 0, *hlen = 0;
381 int ilist;
382 int iline;
383 
384  for(int k=0;k<a->nelems;k++){
385 
386  e=a->e[k];
387 
388  // get Type
389 
390  p1=strstr(loca[e->istart],e->startKey) + strlen(e->startKey);
391 
392  p2=strstr(loca[e->istart],">");
393  len = strlen(p1) - strlen(p2);
394  e->type = new char[len+1];
395  memcpy(e->type,p1,len);
396  e->type[len]='\0';
397 
398  // get Name
399  p2++;
400  while(p2[0]==' ')p2++;
401  p1 = strstr(p2,"<");
402  len = strlen(p2) - strlen(p1);
403  e->name = new char[len+1];
404  memcpy(e->name,p2,len);
405  e->name[len]='\0';
406 
407  // get size
408 
409  p1=strstr(loca[e->istart],e->size.startKey);
410 
411 if(p1){
412  p1+=strlen(e->size.startKey);
413  p2=strstr(loca[e->istart],e->size.endKey);
414  len = strlen(p1) - strlen(p2)+1;
415  hlen = new char[len+1];
416  memcpy(hlen,p1,len);
417  hlen[len]='\0';
418  e->size.isize = atoi(hlen);
419  delete [] hlen;
420 }
421  if(e->size.isize==0)e->size.isize=1; // <length> not required for len=1
422 
423 
424  // get values : if array it is on separate lines
425 
426  p1=strstr(loca[e->istart],(e->val).startKey);
427  if(p1){
428  // <element Type> ... <value> data </value>
429  // </element Type>
430  p1+=strlen((e->val).startKey);
431  while(p1[0]==' ')p1++;
432  p2=strstr(loca[e->istart],(e->val).endKey);
433  len = strlen(p1) - strlen(p2);
434  (e->val).data = new char[len];
435  memcpy((e->val).data,p1,len);
436  (e->val).data[len]='\0';
437  } else {
438  // <element Type> ...
439  // <value>
440  // data
441  // data
442  // </value> </element Type>
443  ilist =e->iend - e->istart;
444  iline =0;
445  for(j=2;j<ilist;j++)iline += strlen(loca[e->istart+j]);
446  StString fs;
447  for(j=2;j<ilist;j++) fs<<loca[e->istart+j]; //<<endl;
448  string fs2=fs.str();
449  e->val.data = new char[fs2.length()+1];
450  //cout << "TEST:: " << fullLine << " len = " << strlen(fullLine) << endl;
451  strcpy(e->val.data,fs2.c_str());
452 
453  }
454 
455  // cout << "Test:: " << endl;
456  // cout << e->name << " "<<e->type << " " << e->val.data << endl;
457  }
458 
459 }
460 
461 
462 //----------------------------------------------------
463 
464 void
465 StDbXmlReader::pass(char* name, char*& i, int& len){
466  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
467  if(strcmp(e->type,"String")==0){
468  i=new char[strlen((e->val).data)+1];
469  strcpy(i,(e->val).data);
470  }
471 }
472 
473 //----------------------------------------------------------
474 
475 void
476 StDbXmlReader::pass(char* name, unsigned char& i, int& len){
477  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
478  if(strcmp(e->type,"Char")==0)i=atoi((e->val).data);
479 }
480 
482 
483 void
484 StDbXmlReader::pass(char* name, unsigned char*& i, int& len)
485 {
486  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
487  if(!strstr(e->type,"UChar")) return;
488  passAux(e,i,len);
489 }
490 
491 
492 //----------------------------------------------------
493 
494 
495 //----------------------------------------------------
496 
497 void
498 StDbXmlReader::pass(char* name, short& i, int& len){
499  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
500  if(strcmp(e->type,"Short")==0)i=atoi((e->val).data);
501 }
502 
503 
504 //----------------------------------------------------
505 
506 void
507 StDbXmlReader::pass(char* name, short*& i, int& len){
508 
509  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
510  if(!strstr(e->type,"Short"))return;
511  passAux(e,i,len);
512 }
513 
514 
515 //----------------------------------------------------
516 
517 void
518 StDbXmlReader::pass(char* name, unsigned short& i, int& len){
519  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
520  if(strcmp(e->type,"UShort")==0)i=atoi((e->val).data);
521 }
522 
523 
524 //----------------------------------------------------
525 
526 void
527 StDbXmlReader::pass(char* name, unsigned short*& i, int& len){
528 
529  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
530  if(!strstr(e->type,"UShort"))return;
531  passAux(e,i,len);
532 }
533 
534 void
535 StDbXmlReader::pass(char* name, int& i, int& len){
536  // cout << "In Int " << endl;
537 
538  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
539  if(strcmp(e->type,"Int")==0)i=atoi((e->val).data);
540 }
541 
542 //----------------------------------------------------
543 
544 void
545 StDbXmlReader::pass(char* name, int*& i, int& len){
546 
547  // cout << "In IntArray " << endl;
548  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
549  if(!strstr(e->type,"Int")) return;
550  passAux(e,i,len);
551 }
552 void
553 StDbXmlReader::pass(char* name,unsigned int& i, int& len){
554  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
555  if(strcmp(e->type,"UInt")==0)i=atoi((e->val).data);
556 }
557 
558 //----------------------------------------------------
559 
560 void
561 StDbXmlReader::pass(char* name,unsigned int*& i, int& len){
562 
563  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
564  if(!strstr(e->type,"UInt"))return;
565  passAux(e,i,len);
566 }
567 
568 //----------------------------------------------------
569 
570 void
571 StDbXmlReader::pass(char* name, long& i, int& len){
572  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
573  if(strcmp(e->type,"Long")==0)i=atol((e->val).data);
574 }
575 
576 
577 //----------------------------------------------------
578 
579 void
580 StDbXmlReader::pass(char* name, long*& i, int& len){
581 
582  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
583  if(!strstr(e->type,"Long")) return;
584  passAux(e,i,len);
585 }
586 
587 //----------------------------------------------------
588 
589 void
590 StDbXmlReader::pass(char* name, unsigned long& i, int& len){
591  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
592  if(strcmp(e->type,"ULong")==0)i=atol((e->val).data);
593 }
594 
595 //----------------------------------------------------
596 
597 void
598 StDbXmlReader::pass(char* name, long long& i, int& len){
599  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
600 #ifndef __osf__
601  if(strcmp(e->type,"LongLong")==0)i=atoll((e->val).data);
602 #else
603  if(strcmp(e->type,"LongLong")==0)i=atol((e->val).data);
604 #endif
605 }
606 void
607 StDbXmlReader::pass(char* name, long long*& i, int& len){
608  //
609  cout<<"Not Yet Implemented"<<endl;
610 }
611 
612 
613 //----------------------------------------------------
614 
615 void
616 StDbXmlReader::pass(char* name, unsigned long*& i, int& len){
617 
618  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
619  if(!strstr(e->type,"ULong"))return;
620  passAux(e,i,len);
621 }
622 
623 
624 //----------------------------------------------------
625 
626 void
627 StDbXmlReader::pass(char* name, float*& i, int& len){
628 
629  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
630  if(!strstr(e->type,"Float")) return;
631  passAux(e,i,len);
632 }
633 //----------------------------------------------------
634 
635 void
636 StDbXmlReader::pass(char* name, double*& i, int& len){
637 
638  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
639  if(!strstr(e->type,"Double"))return;
640  passAux(e,i,len);
641 }
642 //----------------------------------------------------
643 
644 void
645 StDbXmlReader::pass(char* name, float& i, int& len){
646  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
647  if(strcmp(e->type,"Float")==0)i=(float)atof((e->val).data);
648 
649 }
650 
651 
652 void
653 StDbXmlReader::pass(char* name, double& i, int& len){
654  elem* e = findElement(name); if(!e){ LOG_ERROR<<name<<" not found"<<endm; return;}
655  if(strcmp(e->type,"Double")==0)i=atof((e->val).data);
656 
657 }
658 
659 
660 
661 
662 
663 
664 
665 
Definition: dbStruct.hh:78