ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
xDataTOM_importXML.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file xDataTOM_importXML.cc
1 /*
2 # <<BEGIN-copyright>>
3 # <<END-copyright>>
4 */
5 
6 #include <stdlib.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <errno.h>
13 
14 #ifdef WIN32
15 #include <BaseTsd.h>
16 #include <io.h>
17 #include <windows.h>
18 #define realpath( a, b ) GetFullPathName( a, PATH_MAX, b, NULL )
19 #define strtoll _strtoi64
20 typedef SSIZE_T ssize_t;
21 #else
22 #include <unistd.h>
23 #endif
24 
26 
27 #if defined __cplusplus
28 namespace GIDI {
29 using namespace GIDI;
30 #endif
31 
32 #ifndef PATH_MAX
33 #define PATH_MAX 4096
34 #endif
35 
39 static void *xDataXML_freeElement( statusMessageReporting *smr, xDataXML_element *element );
41 static int xDataXML_parse( xDataXML_document *doc, char const *s );
42 static void XMLCALL xDataXML_parseStartElement( void *userData, char const *name, char const **attris );
43 static void XMLCALL xDataXML_parseEndElement( void *userData, char const *name );
44 static void XMLCALL xDataXML_parseCharacterData( void *userData, XML_Char const *s, int len );
45 static void xDataXML_initializeRootElement( xDataXML_document *doc, xDataXML_rootElement *re, xDataXML_element *parentElement, int depth );
47 static int xDataXML_addElementToRoot( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, char const *name, char const **attris );
49 static int xDataXML_init_xDataTypeNone( xDataXMLType *xDT, xDataXML_element *element );
51 static char *xDataXML_getTraceback2( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, int n );
52 static int xDataXML_setFileName( statusMessageReporting *smr, xDataXML_document *doc, char const *fileName );
53 
56 static char *xDataXML_smrUserInterface( void *userData );
57 static char const *xDataXML_shortStringForMessage( size_t size, char *Out, char const *In );
58 
60 /*
61 ************************************************************
62 */
64 /*
65 * Returns NULL is any error occurred. If an error occurs in an expat routine, xDataXML_endXMLParsing will set smr appropriately.
66 */
67  xDataTOM_TOM *TOM = NULL;
68  xDataXML_document *XML = NULL;
69  xDataXML_element *element;
70 
71  if( ( XML = xDataXML_importFile2( smr, fileName ) ) == NULL ) return( NULL );
72 
73  if( ( TOM = xDataTOM_mallocTOM( smr ) ) == NULL ) goto Err;
74  if( xDataTOM_setFileNameTOM( smr, TOM, fileName ) != 0 ) goto Err;
75 
76  element = xDataXML_getDocumentsElement( XML );
77  if( xDataXML_constructTOM( smr, (&TOM->root), element ) != 0 ) goto Err;
78 
79  xDataXML_freeDoc( smr, XML );
80  return( TOM );
81 
82 Err:
83  if( XML != NULL ) xDataXML_freeDoc( smr, XML );
84  if( TOM != NULL ) xDataTOM_freeTOM( smr, &TOM );
85  return( NULL );
86 }
87 /*
88 ************************************************************
89 */
91 /*
92 * Returns NULL is any error occurred. If an error occurs in an expat routine, xDataXML_endXMLParsing will set smr appropriately.
93 */
94  int f;
95  char buffer[10 * 1000];
96  ssize_t count, n = sizeof( buffer ) - 1;
97  ssize_t s = 0;
98  xDataXML_document *doc;
99 
100  if( ( doc = xDataXML_mallocDoc( smr ) ) == NULL ) return( NULL );
101  if( xDataXML_setFileName( smr, doc, fileName ) == 0 ) {
102  f = open( fileName, O_RDONLY );
103  if( f == -1 ) {
104  xDataXML_endXMLParsing( smr, doc );
105  smr_setReportError2( smr, xDataTOM_smrLibraryID, xDataXML_errFileError, "could not open XML file %s", fileName ); }
106  else {
107  while( ( count = read( f, buffer, n ) ) > 0 ) {
108  s += count;
109  buffer[count] = 0;
110  if( xDataXML_parse( doc, buffer ) ) break;
111  if( !smr_isOk( doc->smr ) ) break;
112  } // Loop checking, 11.06.2015, T. Koi
113  close( f );
114  xDataXML_endXMLParsing( smr, doc );
115  if( count < 0 ) smr_setReportError2( smr, xDataTOM_smrLibraryID, xDataXML_errFileError, "read failed with errno = %d for XML %s",
116  errno, fileName );
117  }
118  }
119  if( doc != NULL ) {
120  if( !smr_isOk( smr ) ) {
121  xDataXML_freeDoc( smr, doc );
122  doc = NULL;
123  }
124  }
125  return( doc );
126 }
127 /*
128 ************************************************************
129 */
131 
132  xDataXML_document *doc;
133 
134  if( ( doc = (xDataXML_document *) smr_malloc2( smr, sizeof( xDataXML_document ), 1, "xDataXML_document" ) ) != NULL ) {
135  if( xDataXML_initializeDoc( smr, doc ) ) doc = (xDataXML_document *) xDataXML_freeDoc( smr, doc );
136  }
137  return( doc );
138 }
139 /*
140 ************************************************************
141 */
143 
145  doc->error = xDataXML_errNone;
146  doc->err = XML_ERROR_NONE;
147  doc->err_line = 0;
148  doc->err_column = 0;
149  doc->fileName = NULL;
150  doc->realFileName = NULL;
152  doc->smr= smr;
153  if( ( doc->xmlParser = XML_ParserCreate( NULL ) ) == NULL ) {
154  smr_setReportError2p( smr, xDataTOM_smrLibraryID, xDataXML_errXML_ParserCreate, "XML_ParserCreate failed" ); }
155  else {
156  XML_SetUserData( doc->xmlParser, doc );
157  xDataXML_initializeRootElement( doc, &(doc->root), NULL, 0 );
158  doc->currentRoot = &(doc->root);
161  }
162  return( !smr_isOk( smr ) );
163 }
164 /*
165 ************************************************************
166 */
168 
169  if( doc->xmlParser ) {
170  doc->err = XML_GetErrorCode( doc->xmlParser );
173  if( smr_isOk( smr ) && ( XML_Parse( doc->xmlParser, NULL, 0, 1 ) == XML_STATUS_ERROR ) ) {
176  "status = %d\nXML_Error code = %d\nXML_ErrorString = %s\nerror line, column = %d, %d", xDataXML_errXMLParser,
177  doc->err, XML_ErrorString( doc->err ), doc->err_line, doc->err_column );
178  }
179  XML_ParserFree( doc->xmlParser );
180  doc->xmlParser = NULL;
182  }
183  return( 0 );
184 }
185 /*
186 ************************************************************
187 */
189 
190  xDataXML_endXMLParsing( smr, doc );
192  smr_freeMemory( (void **) &(doc->fileName) );
193  smr_freeMemory( (void **) &(doc->realFileName) );
195  smr_freeMemory( (void **) &doc );
196  return( NULL );
197 }
198 /*
199 ************************************************************
200 */
202 
203  xDataXML_element *next;
204 
205  for( ; element != NULL; element = next ) {
206  next = element->next;
207  xDataXML_freeElementItems( smr, element );
208  smr_freeMemory( (void **) &element );
209  }
210  return( NULL );
211 }
212 /*
213 ************************************************************
214 */
216 
218 /* BRB, The next line needs work */
219  if( ( !strcmp( element->name, "xData" ) ) && ( element->xDataTypeInfo.release != NULL ) ) element->xDataTypeInfo.release( smr, &(element->xDataTypeInfo) );
220  smr_freeMemory( (void **) &(element->name) );
221  smr_freeMemory( (void **) &(element->fullName) );
222  if( element->attributes.attributes ) smr_freeMemory( (void **) &(element->attributes.attributes) );
223  if( element->text.text ) smr_freeMemory( (void **) &(element->text.text) );
224 }
225 /*
226 ************************************************************
227 */
228 static int xDataXML_parse( xDataXML_document *doc, char const *s ) {
229 
230  if( doc->status != xDataXML_statusParsing ) return( doc->status );
231  if( XML_Parse( doc->xmlParser, s, (int) strlen( s ), 0 ) == XML_STATUS_ERROR ) return( -1 );
232  return( 0 );
233 }
234 /*
235 ************************************************************
236 */
237 static void XMLCALL xDataXML_parseStartElement( void *userData, char const *name, char const **attris ) {
238 
239  xDataXML_document *doc = (xDataXML_document *) userData;
240 
241  if( !smr_isOk( doc->smr ) ) return;
242  xDataXML_addElementToRoot( doc->smr, doc->currentRoot, name, attris );
243 }
244 /*
245 ************************************************************
246 */
247 static void XMLCALL xDataXML_parseEndElement( void *userData, char const * /*name*/ ) {
248 
249  xDataXML_document *doc = (xDataXML_document *) userData;
250 
251  doc->currentRoot->currentChild = NULL;
252  doc->currentRoot = doc->currentRoot->parentRoot;
253 }
254 /*
255 ************************************************************
256 */
257 static void XMLCALL xDataXML_parseCharacterData( void *userData, XML_Char const *s, int len ) {
258 /*
259 * Always terminates text with a 0.
260 */
261  xDataXML_document *doc = (xDataXML_document *) userData;
263  size_t needSize = text->length + len + 1, l;
264  char *p;
265 
266  if( !smr_isOk( doc->smr ) ) return;
267  if( needSize < 8 ) needSize = 8;
268  if( needSize > text->allocated ) {
269  if( text->allocated != 0 ) {
270  l = ( 20 * text->allocated ) / 100;
271  if( l < 100 ) l = 100;
272  if( needSize < ( text->allocated + l ) ) needSize = text->allocated + l;
273  }
274  text->allocated = needSize;
275  text->text = (char *) smr_realloc2( doc->smr, text->text, text->allocated, "text" );
276  if( !smr_isOk( doc->smr ) ) return;
277  }
278  p = &(text->text[text->length]);
279  strncpy( p, s, len );
280  text->length += len;
281  p[len] = 0;
282 }
283 /*
284 ************************************************************
285 */
286 static void xDataXML_initializeRootElement( xDataXML_document *doc, xDataXML_rootElement *re, xDataXML_element *parentElement, int depth ) {
287 
288  re->xData_doc = doc;
289  re->parentElement = parentElement;
290  re->parentRoot = NULL;
291  if( parentElement != NULL ) re->parentRoot = parentElement->parentRoot;
292  re->depth = depth;
293  re->numberOfElements = 0;
294  re->children = NULL;
295  re->currentChild = NULL;
296 }
297 /*
298 ************************************************************
299 */
301 
302  xDataXML_parseGetCurrentPosition( doc, &(text->docInfo) );
303  text->allocated = 0;
304  text->length = 0;
305  text->text = NULL;
306  return( 0 );
307 }
308 /*
309 ************************************************************
310 */
311 static int xDataXML_addElementToRoot( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, char const *name, char const **attris ) {
312 
313  xDataXML_document *doc = parentRoot->xData_doc;
314  xDataXML_element *element;
315  int i, n, status = 1;
316  size_t lens;
317  char *p, *e;
318  char const **pAttris;
320  void *smrUser;
321 
322  element = (xDataXML_element *) smr_malloc2( doc->smr, sizeof( xDataXML_element ), 1, "xDataXML_element" );
323  if( element == NULL ) return( 1 );
324  xDataXML_parseGetCurrentPosition( doc, &(element->docInfo) );
325  element->ordinal = parentRoot->numberOfElements;
326  element->index = -1;
327  element->accessed = 0;
328  element->parentRoot = parentRoot;
329  xDataXML_initializeRootElement( doc, &(element->childrenRoot), element, parentRoot->depth + 1 );
330  element->next = NULL;
331  if( ( element->name = (char *) smr_malloc2( doc->smr, strlen( name ) + 1, 0, "name" ) ) == NULL ) {
332  smr_freeMemory( (void **) &element );
333  return( 1 );
334  }
335  strcpy( element->name, name );
336  if( ( element->fullName = xDataXML_getTraceback( smr, element ) ) == NULL ) {
337  smr_freeMemory( (void **) &(element->name) );
338  smr_freeMemory( (void **) &element );
339  return( 1 );
340  }
341  for( i = 0, lens = 0, pAttris = attris; *pAttris; i++, pAttris++ ) lens += strlen( *pAttris ) + 1;
342  n = i / 2;
343  element->attributes.size = n * sizeof( xDataXML_attribute ) + lens;
344  element->attributes.number = n;
345  element->attributes.attributes = NULL;
346  smrUser = xDataXML_get_smrUserInterfaceFromElement( element );
347  if( element->attributes.size ) {
348  if( ( element->attributes.attributes = (xDataXML_attribute *) smr_malloc2( doc->smr, element->attributes.size, 0, "attributes") ) == NULL ) {
349  status = 0; }
350  else {
351  a = element->attributes.attributes;
352  p = (char *) &(element->attributes.attributes[n]);
353  for( i = 0, pAttris = attris; ( i < n ) && status; i++, a++, pAttris++ ) {
354  lens = strlen( *pAttris ) + 1;
355  a->name = p;
356  strcpy( p, *pAttris );
357  p += lens;
358  pAttris++;
359  lens = strlen( *pAttris ) + 1;
360  a->value= p;
361  strcpy( p, *pAttris );
362  p += lens;
363  if( !strcmp( "index", a->name ) ) {
364  element->index = (int) strtoll( a->value, &e, 10 );
365  if( *e != 0 ) {
366  status = 0;
367  smr_setReportError3( doc->smr, smrUser, xDataTOM_smrLibraryID, -1, "could not convert index attribute = %s to integer", a->value );
368  }
369  }
370  }
371  }
372  }
373  if( !status ) {
374  smr_freeMemory( (void **) &(element->attributes.attributes) );
375  smr_freeMemory( (void **) &(element->name) );
376  smr_freeMemory( (void **) &(element->fullName) );
377  smr_freeMemory( (void **) &element );
378  return( 1 );
379  }
380  xDataXML_init_xDataTypeNone( &(element->xDataTypeInfo), element );
381  element->textOffset = 0;
382  xDataXML_parseInitializeText( doc, &(element->text) );
383  if( parentRoot->parentElement != NULL ) element->textOffset = parentRoot->parentElement->text.length;
384  if( parentRoot->currentChild == NULL ) {
385  parentRoot->children = element; }
386  else {
387  parentRoot->currentChild->next = element;
388  }
389  parentRoot->numberOfElements++;
390  parentRoot->currentChild = element;
391  doc->currentRoot = &(element->childrenRoot);
392  return( 0 );
393 }
394 /*
395 ************************************************************
396 */
398 
399  docInfo->column = XML_GetCurrentColumnNumber( doc->xmlParser );
400  docInfo->line = XML_GetCurrentLineNumber( doc->xmlParser );
401  return( xDataXML_errNone );
402 }
403 /*
404 ************************************************************
405 */
407 
408  return( doc->status == xDataXML_statusError );
409 }
410 /*
411 ************************************************************
412 */
415 xDataXML_element *xDataXML_getNextElement( xDataXML_element *element ) { return( element->next ); }
416 /*
417 ************************************************************
418 */
420 
421  item->parentElement = element;
422  item->element = xDataXML_getFirstElement( element );
423  if( item->element == NULL ) {
424  item->mode = xDataXML_itemModeText;
425  if( element->text.length == 0 ) item->mode = xDataXML_itemModeEnd; }
426  else {
428  if( 0 < item->element->textOffset ) item->mode = xDataXML_itemModeText;
429  }
430  item->textOffset = 0;
431  item->textLength = element->text.length;
432  if( item->element != NULL ) item->textLength = item->element->textOffset;
433  item->text = element->text.text;
434  return( item->mode );
435 }
436 /*
437 ************************************************************
438 */
440 
441  if( item->mode != xDataXML_itemModeEnd ) {
442  if( item->mode == xDataXML_itemModeText ) {
444  if( item->element == NULL ) item->mode = xDataXML_itemModeEnd;
445  item->textOffset += item->textLength;
446  item->textLength = 0;
447  item->text = &(item->parentElement->text.text[item->textOffset]); }
448  else {
449  item->element = item->element->next;
450  item->mode = xDataXML_itemModeText;
451  if( item->element == NULL ) {
452  if( item->textOffset < item->parentElement->text.length ) {
453  item->textLength = item->parentElement->text.length - item->textOffset; }
454  else {
455  item->mode = xDataXML_itemModeEnd;
456  } }
457  else {
458  item->textLength = item->element->textOffset - item->textOffset;
459  }
460  }
461  }
462  return( item->mode );
463 }
464 /*
465 ************************************************************
466 */
468 
469  int i;
470 
471  for( i = 0; i < attributes->number; i++ ) {
472  if( !strcmp( attributes->attributes[i].name, name ) ) return( 1 );
473  }
474  return( 0 );
475 }
476 /*
477 ************************************************************
478 */
480 
481  return( xDataXML_isAttributeInList( &(element->attributes), name ) );
482 }
483 /*
484 ************************************************************
485 */
486 char *xDataXML_getAttributesValue( xDataXML_attributionList *attributes, char const *name ) {
487 
488  int i;
489 
490  for( i = 0; i < attributes->number; i++ ) {
491  if( !strcmp( attributes->attributes[i].name, name ) ) return( attributes->attributes[i].value );
492  }
493  return( NULL );
494 }
495 /*
496 ************************************************************
497 */
498 char const *xDataXML_getAttributesValueInElement( xDataXML_element *element, char const *name ) {
499 
500  return( (char const *) xDataXML_getAttributesValue( &(element->attributes), name ) );
501 }
502 /*
503 ************************************************************
504 */
506 
507  return( attributes->number );
508 }
509 /*
510 ************************************************************
511 */
513 
514  if( index >= attributes->number ) return( NULL );
515  return( &(attributes->attributes[index]) );
516 }
517 /*
518 ************************************************************
519 */
521 
523  xDT->ID = NULL;
524  xDT->element = element;
525  xDT->toData = NULL;
526  xDT->toString = NULL;
527  xDT->release = NULL;
528  xDT->indexPresent = 1; /* The following describes the meaning of present variables. */
529  xDT->startPresent = 1; /* If < 0, an error occured in converting value to an integer. */
530  xDT->endPresent = 1; /* If > 0, not present as an attribute. */
531  xDT->lengthPresent = 1; /* Else, if 0, present and converted without an error. */
532  xDT->index = -1;
533  xDT->start = -1;
534  xDT->end = -1;
535  xDT->length = -1;
536  xDT->data = NULL;
537  return( 0 );
538 }
539 /*
540 ************************************************************
541 */
543  xDataTOM_Int *length ) {
544 
545  if( element->xDataTypeInfo.ID == NULL ) {
547  "element %s is not xData", element->fullName );
548  return( 1 );
549  }
550  *index = element->xDataTypeInfo.index;
551  *start = element->xDataTypeInfo.start;
552  *end = element->xDataTypeInfo.end;
553  *length = element->xDataTypeInfo.length;
554  return( 0 );
555 }
556 /*
557 ************************************************************
558 */
560 
561  xDataXMLType *xDT = &(element->xDataTypeInfo);
562  void *smrUser = xDataXML_get_smrUserInterfaceFromElement( element );
563 
564  xDT->index = -1;
565  xDT->start = -1;
566  xDT->end = -1;
567  xDT->length = -1;
568  if( ( xDT->indexPresent = xDataXML_convertAttributeTo_xDataTOM_Int( smr, element, "index", &(xDT->index), 0 ) ) < 0 ) return( 1 );
569  if( ( xDT->startPresent = xDataXML_convertAttributeTo_xDataTOM_Int( smr, element, "start", &(xDT->start), 0 ) ) < 0 ) return( 1 );
570  if( ( xDT->endPresent = xDataXML_convertAttributeTo_xDataTOM_Int( smr, element, "end", &(xDT->end), 0 ) ) < 0 ) return( 1 );
571  if( ( xDT->lengthPresent = xDataXML_convertAttributeTo_xDataTOM_Int( smr, element, "length", &(xDT->length), 0 ) ) < 0 ) return( 1 );
572  if( ( xDT->endPresent > 0 ) ) {
573  if( xDT->lengthPresent > 0 ) {
574  smr_setReportError3p( smr, smrUser, xDataTOM_smrLibraryID, 1, "missing length (or end) in xData" );
575  return( 1 );
576  }
577  xDT->end = xDT->length; }
578  else {
579  if( xDT->lengthPresent > 0 ) xDT->length = xDT->end;
580  }
581 
582  if( xDT->startPresent > 0 ) xDT->start = 0;
583  if( xDT->start < 0 ) {
584  smr_setReportError3( smr, smrUser, xDataTOM_smrLibraryID, 1, "start = %d < 0", xDT->start );
585  return( 1 );
586  }
587  if( xDT->end < xDT->start ) {
588  smr_setReportError3( smr, smrUser, xDataTOM_smrLibraryID, 1, "start = %d >= end = %d", xDT->start, xDT->end );
589  return( 1 );
590  }
591  if( xDT->length < 0 ) {
592  smr_setReportError3( smr, smrUser, xDataTOM_smrLibraryID, 1, "length = %d < 0", xDT->length );
593  return( 1 );
594  }
595 
596  return( 0 );
597 }
598 /*
599 ************************************************************
600 */
602 /*
603 * Returns 1 if no such attribute, -1 if error converting to xDataTOM_Int and 0 if successful.
604 */
605  char const *value;
606  char *e;
607 
608  if( ( value = xDataXML_getAttributesValueInElement( element, name ) ) == NULL ) {
610  "missing required attribute '%s'", name );
611  return( 1 );
612  }
613  *n = (xDataTOM_Int) strtoll( value, &e, 10 );
614  if( *e != 0 ) {
616  "could not convert attribute %s's value = %s to an integer", name, value );
617  return( -1 );
618  }
619  return( 0 );
620 }
621 /*
622 ************************************************************
623 */
624 int xDataXML_convertAttributeToDouble( statusMessageReporting *smr, xDataXML_element *element, char const *name, double *d, int required ) {
625 /*
626 * Returns 1 if no such attribute, -1 if error converting to double and 0 if successful.
627 */
628  char const *value;
629  char *e;
630 
631  if( ( value = xDataXML_getAttributesValueInElement( element, name ) ) == NULL ) {
633  "missing required attribute '%s'", name );
634  return( 1 );
635  }
636  *d = strtod( value, &e );
637  if( *e != 0 ) {
639  "could not convert attribute %s's values = %s to a double", name, value );
640  return( -1 );
641  }
642  return( 0 );
643 }
644 /*
645 ************************************************************
646 */
647 int xDataXML_numberOfElementsByTagName( statusMessageReporting * /*smr*/, xDataXML_element *element, char const *tagName ) {
648 
649  int n = 0;
650  xDataXML_element *child;
651 
652  for( child = xDataXML_getFirstElement( element ); child != NULL; child = xDataXML_getNextElement( child ) ) if( !strcmp( child->name, tagName ) ) n++;
653  return( n );
654 }
655 /*
656 ************************************************************
657 */
659 
660  int n = xDataXML_numberOfElementsByTagName( smr, element, tagName );
661  size_t size;
662  xDataXML_element *child;
664  xDataXML_elementList *list = NULL;
665 
666 
667  size = sizeof( xDataXML_elementList ) + n * sizeof( xDataXML_elementListItem );
668  if( ( list = (xDataXML_elementList *) smr_malloc2( smr, size, 0, "list" ) ) != NULL ) {
669  list->n = n;
670  p = list->items = (xDataXML_elementListItem *) &(list[1]);
671  for( child = xDataXML_getFirstElement( element ); child != NULL; child = xDataXML_getNextElement( child ) ) {
672  if( !strcmp( child->name, tagName ) ) {
673  p->element = child;
674  p->sortString = NULL;
675  p++;
676  }
677  }
678  }
679  return( list );
680 }
681 /*
682 ************************************************************
683 */
685 
686  xDataXML_elementList *list;
687  xDataXML_element *xData = NULL;
688 
689  if( ( list = xDataXML_getElementsByTagName( smr, element, name ) ) != NULL ) {
690  if( list->n == 0 ) {
692  1, "element %s does not have sub-element named %s", element->fullName, name ); }
693  else if( list->n > 1 ) {
695  "element %s contains more than one sub-element named %s", element->fullName, name ); }
696  else {
697  xData = list->items[0].element;
698  }
699  xDataXML_freeElementList( smr, list );
700  }
701  return( xData );
702 }
703 /*
704 ************************************************************
705 */
707 
708  smr_freeMemory( (void **) &list );
709 }
710 /*
711 ************************************************************
712 */
714 /*
715 * Returned string must be freed by calling routine.
716 */
717  int size;
718  char *s, *name;
719 
720  name = element->name;
721  size = (int) strlen( name ) + 1;
722  if( ( s = xDataXML_getTraceback2( smr, element->parentRoot, size ) ) != NULL ) {
723  strcat( s, "/" );
724  strcat( s, name );
725  }
726  return( s );
727 }
728 /*
729 ************************************************************
730 */
731 static char *xDataXML_getTraceback2( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, int n ) {
732 
733  int size;
734  char *s, *name;
735 
736  if( parentRoot->parentRoot == NULL ) {
737  s = (char *) smr_malloc2( smr, n + 1, 0, "traceback string" );
738  *s = 0; }
739  else {
740  name = parentRoot->parentElement->name;
741  size = (int) strlen( name ) + 1;
742  n += size;
743  if( ( s = xDataXML_getTraceback2( smr, parentRoot->parentRoot, n ) ) != NULL ) {
744  strcat( s, "/" );
745  strcat( s, name );
746  }
747  }
748  return( s );
749 }
750 /*
751 ************************************************************
752 */
753 int xDataXML_is_xDataType( statusMessageReporting *smr, xDataXMLType *xDT, char const * const ID, int setMsg ) {
754 
755  if( xDT->ID == NULL ) {
757  "element %s not xData object", xDT->element->fullName ); }
758  else if( xDT->ID != ID ) {
760  "Element %s is not xData object of ID %s but %s", xDT->element->fullName, ID, xDT->ID );
761  }
762  return( xDT->ID == ID );
763 }
764 /*
765 ************************************************************
766 */
768 
769  return( doc->fileName );
770 }
771 /*
772 ************************************************************
773 */
775 
776  return( doc->realFileName );
777 }
778 /*
779 ************************************************************
780 */
781 static int xDataXML_setFileName( statusMessageReporting *smr, xDataXML_document *doc, char const *fileName ) {
782 
783  char realPath[PATH_MAX+1];
784 
785  smr_freeMemory( (void **) &(doc->fileName) );
786  smr_freeMemory( (void **) &(doc->realFileName) );
787  if( fileName != NULL ) {
788  if( ( doc->fileName = smr_allocateCopyString2( smr, fileName, "fileName" ) ) == NULL ) return( 1 );
789  if( realpath( fileName, realPath ) != NULL ) {
790  if( ( doc->realFileName = smr_allocateCopyString2( smr, realPath, "realFileName" ) ) == NULL ) return( 1 );
791  }
792  }
793  return( 0 );
794 }
795 /*
796 ************************************************************
797 */
799 
800  xDataXML_rootElement* root = element->parentRoot;
801 
802  while( root->parentRoot != NULL ) root = root->parentRoot; // Loop checking, 11.06.2015, T. Koi
803  return( root->xData_doc );
804 }
805 /*
806 ************************************************************
807 */
809 
810  if( doc == NULL ) return( NULL );
811  return( &(doc->smrUserInterface ) );
812 }
813 /*
814 ************************************************************
815 */
817 
819 }
820 /*
821 ************************************************************
822 */
824 
826  doc->smrUserInterface.doc = doc;
827  return( 0 );
828 }
829 /*
830 ************************************************************
831 */
833 
835  doc->smrUserInterface.doc = NULL;
836  return( 0 );
837 }
838 /*
839 ************************************************************
840 */
841 static char *xDataXML_smrUserInterface( void *userData ) {
842 
843  xDataXML_smr *smrUserInterface = (xDataXML_smr *) userData;
844  xDataXML_rootElement *currentRoot = smrUserInterface->doc->currentRoot;
845 
846  if( currentRoot->parentElement != NULL ) {
847  return( smr_allocateFormatMessage( "\nat line %d and column %d of file %s\nin element %s", currentRoot->parentElement->docInfo.line,
848  currentRoot->parentElement->docInfo.column, smrUserInterface->doc->fileName, currentRoot->parentElement->fullName ) ); }
849  else if( smrUserInterface->doc->fileName != NULL ) {
850  return( smr_allocateFormatMessage( "\nof file %s", smrUserInterface->doc->fileName ) );
851  }
852  return( smr_allocateFormatMessage( "\nat line %d and column %d\nin element %s", currentRoot->parentElement->docInfo.line,
853  currentRoot->parentElement->docInfo.column, currentRoot->parentElement->fullName ) );
854 }
855 /*
856 ************************************************************
857 */
858 int xDataXML_stringTo_xDataTOM_Int( statusMessageReporting *smr, void *smrUserInterface, char const *c, xDataTOM_Int *value, char const *endings, char **e ) {
859 
860  char const *s;
861  char tmp[64];
862  int status = 1, n = sizeof( tmp );
863 
864  for( s = c; *s != 0; s++ ) if( !isspace( *s ) ) break;
865  *value = (xDataTOM_Int) strtoll( s, e, 10 );
866  if( *e == s ) {
867  smr_setReportError3(smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "could not convert \"%s\" to an integer", xDataXML_shortStringForMessage( n, tmp, c ));}
868  else {
869  if( *endings == 0 ) while( isspace( **e ) ) (*e)++; // Loop checking, 11.06.2015, T. Koi
870  if( **e == 0 ) {
871  status = 0; }
872  else {
873  if( *endings == 0 ) {
874  smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "integer string \"%s\" does not end with a '\\0'",
875  xDataXML_shortStringForMessage( n, tmp, c ) ); }
876  else {
877  if( strchr( endings, **e ) == NULL ) {
878  smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "integer string \"%s\" does not end with a white space or a '\\0\'",
879  xDataXML_shortStringForMessage( n, tmp, c ) ); }
880  else {
881  status = 0;
882  }
883  }
884  }
885  }
886  return( status );
887 }
888 /*
889 ************************************************************
890 */
891 int xDataXML_stringTo_double( statusMessageReporting *smr, void *smrUserInterface, char const *c, double *value, char const *endings, char **e ) {
892 
893  char const *s;
894  char tmp[64];
895  int status = 1, n = sizeof( tmp );
896 
897  for( s = c; *s != 0; s++ ) if( !isspace( *s ) ) break;
898  *value = strtod( s, e );
899  if( *e == s ) {
900  smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "could not convert \"%s\" to an double",
901  xDataXML_shortStringForMessage( n, tmp, c ));}
902  else {
903  if( *endings == 0 ) while( isspace( **e ) ) (*e)++; // Loop checking, 11.06.2015, T. Koi
904  if( **e == 0 ) {
905  status = 0; }
906  else {
907  if( *endings == 0 ) {
908  smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "double string \"%s\" does not end with a '\\0'",
909  xDataXML_shortStringForMessage( n, tmp, c ) ); }
910  else {
911  if( strchr( endings, **e ) == NULL ) {
912  smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "double string \"%s\" does not end with a white space or a '\\0\'",
913  xDataXML_shortStringForMessage( n, tmp, c ) ); }
914  else {
915  status = 0;
916  }
917  }
918  }
919  }
920  return( status );
921 }
922 /*
923 ************************************************************
924 */
925 int xDataXML_addToAccessed( statusMessageReporting * /*smr*/, xDataXML_element *element, int increment ) {
926 
927  element->accessed += increment;
928  return( element->accessed );
929 }
930 /*
931 ************************************************************
932 */
934 
935  return( element->accessed );
936 }
937 /*
938 ************************************************************
939 */
940 static char const *xDataXML_shortStringForMessage( size_t size, char *Out, char const *In ) {
941 
942  if( strlen( In ) > size ) {
943  strncpy( Out, In, size - 5 );
944  Out[size-5] = 0;
945  strcat( Out, " ..." );
946  return( Out );
947  }
948  return( In );
949 }
950 /*
951 ************************************************************
952 */
954 
955  int i, status = 0;
956  xDataTOM_element *TOMChild;
957  xDataXML_element *XMLChild;
958  xDataXML_attribute *attribute;
959  char const *xDataValue = xDataXML_getAttributesValueInElement( XE, "xData" );
960 
961  if( !smr_isOk( smr ) ) return( 1 );
962  if( ( TOMChild = xDataTOM_addElementInElement( smr, TE, XE->index, XE->name ) ) == NULL ) return( 1 );
963  for( i = 0; 1; i++ ) {
964  if( ( attribute = xDataXML_attributeByIndex( &(XE->attributes), i ) ) == NULL ) break;
965  if( xDataTOME_addAttribute( smr, TOMChild, attribute->name, attribute->value ) != 0 ) return( 1 );
966  }
967 
968  if( !strcmp( XE->name, xDataTOM_KalbachMann_ID ) ) {
969  xDataValue = xDataTOM_KalbachMann_ID;
970  }
971 
972  if( xDataValue == NULL ) {
973  for( XMLChild = xDataXML_getFirstElement( XE ); ( status == 0 ) && ( XMLChild != NULL ); XMLChild = xDataXML_getNextElement( XMLChild ) ) {
974  status = xDataXML_constructTOM( smr, TOMChild, XMLChild );
975  } }
976  else {
977  if( strcmp( xDataValue, xDataTOM_XYs_ID ) == 0 ) {
978  status = xDataXML_XYsToTOM( smr, XE, TOMChild ); }
979  else if( strcmp( xDataValue, xDataTOM_regionsXYs_ID ) == 0 ) {
980  status = xDataXML_regionsXYsToTOM( smr, XE, TOMChild ); }
981  else if( strcmp( xDataValue, xDataTOM_W_XYs_ID ) == 0 ) {
982  status = xDataXML_W_XYsToTOM( smr, XE, TOMChild ); }
983  else if( strcmp( xDataValue, xDataTOM_V_W_XYs_ID ) == 0 ) {
984  status = xDataXML_V_W_XYsToTOM( smr, XE, TOMChild ); }
985  else if( strcmp( xDataValue, xDataTOM_W_XYs_LegendreSeries_ID ) == 0 ) {
986  status = xDataXML_W_XYs_LegendreSeriesToTOM( smr, XE, TOMChild ); }
987  else if( strcmp( xDataValue, xDataTOM_regionsW_XYs_LegendreSeries_ID ) == 0 ) {
988  status = xDataXML_regionsW_XYs_LegendreSeriesToTOM( smr, XE, TOMChild ); }
989  else if( strcmp( xDataValue, xDataTOM_V_W_XYs_LegendreSeries_ID ) == 0 ) {
990  status = xDataXML_V_W_XYs_LegendreSeriesToTOM( smr, XE, TOMChild ); }
991  else if( strcmp( xDataValue, xDataTOM_KalbachMann_ID ) == 0 ) {
992  status = xDataXML_KalbachMannToTOM( smr, XE, TOMChild ); }
993  else if( strcmp( xDataValue, xDataTOM_polynomial_ID ) == 0 ) {
994  status = xDataXML_polynomialToTOM( smr, XE, TOMChild ); }
995  else {
996  printf( "Unsupported xData type '%s' in element '%s'\n", xDataValue, XE->name );
997 #if 0
999  "Unsupported xData type = \"%s\"", xDataValue );
1000  status = 1;
1001 #endif
1002  }
1003  }
1004  return( status );
1005 }
1006 /*
1007 ************************************************************
1008 */
1009 void *xDataXML_initializeData( statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE, char const *ID, size_t size ) {
1010 
1011  xDataTOM_xDataInfo *xDI = &(TE->xDataInfo);
1012 
1013  if( xData_initializeData( smr, TE, ID, size ) == NULL ) return( NULL );
1014  if( xDataXML_axesElememtToTOM( smr, XE, &(xDI->axes) ) != 0 ) smr_freeMemory( (void **) &(xDI->data) );
1015  return( xDI->data );
1016 }
1017 
1018 #if defined __cplusplus
1019 }
1020 #endif