Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
xDataTOM_importXML.cc
Go to the documentation of this file.
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
20typedef SSIZE_T ssize_t;
21#else
22#include <unistd.h>
23#endif
24
26
27#if defined __cplusplus
28namespace GIDI {
29using namespace GIDI;
30#endif
31
32#ifndef PATH_MAX
33#define PATH_MAX 4096
34#endif
35
36static xDataXML_document *xDataXML_mallocDoc( statusMessageReporting *smr );
37static int xDataXML_initializeDoc( statusMessageReporting *smr, xDataXML_document *doc );
38static int xDataXML_endXMLParsing( statusMessageReporting *smr, xDataXML_document *doc );
39static void *xDataXML_freeElement( statusMessageReporting *smr, xDataXML_element *element );
40static void xDataXML_freeElementItems( statusMessageReporting *smr, xDataXML_element *element );
41static int xDataXML_parse( xDataXML_document *doc, char const *s );
42static void XMLCALL xDataXML_parseStartElement( void *userData, char const *name, char const **attris );
43static void XMLCALL xDataXML_parseEndElement( void *userData, char const *name );
44static void XMLCALL xDataXML_parseCharacterData( void *userData, XML_Char const *s, int len );
45static void xDataXML_initializeRootElement( xDataXML_document *doc, xDataXML_rootElement *re, xDataXML_element *parentElement, int depth );
46static int xDataXML_parseInitializeText( xDataXML_document *doc, xDataXML_text *text );
47static int xDataXML_addElementToRoot( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, char const *name, char const **attris );
48static enum xDataXML_errorCodes xDataXML_parseGetCurrentPosition( xDataXML_document *doc, xDataXML_docInfo *docInfo );
49static int xDataXML_init_xDataTypeNone( xDataXMLType *xDT, xDataXML_element *element );
50static char *xDataXML_getTraceback( statusMessageReporting *smr, xDataXML_element *element );
51static char *xDataXML_getTraceback2( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, int n );
52static int xDataXML_setFileName( statusMessageReporting *smr, xDataXML_document *doc, char const *fileName );
53
54static int xDataXML_smrUserInterfaceInitialize( xDataXML_document *doc );
55static int xDataXML_smrUserInterfaceFree( xDataXML_document *doc );
56static char *xDataXML_smrUserInterface( void *userData );
57static char const *xDataXML_shortStringForMessage( size_t size, char *Out, char const *In );
58
59static int xDataXML_constructTOM( statusMessageReporting *smr, xDataTOM_element *TE, xDataXML_element *element );
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
82Err:
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;
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*/
130static xDataXML_document *xDataXML_mallocDoc( statusMessageReporting *smr ) {
131
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*/
142static int xDataXML_initializeDoc( statusMessageReporting *smr, xDataXML_document *doc ) {
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;
151 xDataXML_smrUserInterfaceInitialize( doc );
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);
159 XML_SetElementHandler( doc->xmlParser, xDataXML_parseStartElement, xDataXML_parseEndElement );
160 XML_SetCharacterDataHandler( doc->xmlParser, xDataXML_parseCharacterData );
161 }
162 return( !smr_isOk( smr ) );
163}
164/*
165************************************************************
166*/
167static int xDataXML_endXMLParsing( statusMessageReporting *smr, xDataXML_document *doc ) {
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 }
180 doc->xmlParser = NULL;
182 }
183 return( 0 );
184}
185/*
186************************************************************
187*/
189
190 xDataXML_endXMLParsing( smr, doc );
191 doc->root.children = (xDataXML_element *) xDataXML_freeElement( smr, doc->root.children );
192 smr_freeMemory( (void **) &(doc->fileName) );
193 smr_freeMemory( (void **) &(doc->realFileName) );
194 xDataXML_smrUserInterfaceFree( doc );
195 smr_freeMemory( (void **) &doc );
196 return( NULL );
197}
198/*
199************************************************************
200*/
201static void *xDataXML_freeElement( statusMessageReporting *smr, xDataXML_element *element ) {
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*/
215static void xDataXML_freeElementItems( statusMessageReporting *smr, xDataXML_element *element ) {
216
217 element->childrenRoot.children = (xDataXML_element *) xDataXML_freeElement( smr, element->childrenRoot.children );
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*/
228static 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*/
237static void XMLCALL xDataXML_parseStartElement( void *userData, char const *name, char const **attris ) {
238
240
241 if( !smr_isOk( doc->smr ) ) return;
242 xDataXML_addElementToRoot( doc->smr, doc->currentRoot, name, attris );
243}
244/*
245************************************************************
246*/
247static void XMLCALL xDataXML_parseEndElement( void *userData, char const * /*name*/ ) {
248
250
251 doc->currentRoot->currentChild = NULL;
253}
254/*
255************************************************************
256*/
257static void XMLCALL xDataXML_parseCharacterData( void *userData, XML_Char const *s, int len ) {
258/*
259* Always terminates text with a 0.
260*/
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*/
286static 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*/
300static int xDataXML_parseInitializeText( xDataXML_document *doc, xDataXML_text *text ) {
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*/
311static 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*/
397static enum xDataXML_errorCodes xDataXML_parseGetCurrentPosition( xDataXML_document *doc, xDataXML_docInfo *docInfo ) {
398
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*/
416/*
417************************************************************
418*/
420
421 item->parentElement = element;
422 item->element = xDataXML_getFirstElement( element );
423 if( item->element == NULL ) {
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;
451 if( item->element == NULL ) {
452 if( item->textOffset < item->parentElement->text.length ) {
453 item->textLength = item->parentElement->text.length - item->textOffset; }
454 else {
456 } }
457 else {
458 item->textLength = item->element->textOffset - item->textOffset;
459 }
460 }
461 }
462 return( item->mode );
463}
464/*
465************************************************************
466*/
467int xDataXML_isAttributeInList( xDataXML_attributionList *attributes, char const *name ) {
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*/
479int xDataXML_isAttributeInElement( xDataXML_element *element, char const *name ) {
480
481 return( xDataXML_isAttributeInList( &(element->attributes), name ) );
482}
483/*
484************************************************************
485*/
486char *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*/
498char 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*/
520static int xDataXML_init_xDataTypeNone( xDataXMLType *xDT, xDataXML_element *element ) {
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*/
624int 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*/
647int 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
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*/
713static char *xDataXML_getTraceback( statusMessageReporting *smr, xDataXML_element *element ) {
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*/
731static 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*/
753int 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*/
781static 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*/
823static int xDataXML_smrUserInterfaceInitialize( xDataXML_document *doc ) {
824
825 doc->smrUserInterface.smrUserInterface = xDataXML_smrUserInterface;
826 doc->smrUserInterface.doc = doc;
827 return( 0 );
828}
829/*
830************************************************************
831*/
832static int xDataXML_smrUserInterfaceFree( xDataXML_document *doc ) {
833
835 doc->smrUserInterface.doc = NULL;
836 return( 0 );
837}
838/*
839************************************************************
840*/
841static 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*/
858int 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*/
891int 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*/
925int 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*/
940static 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*/
953static int xDataXML_constructTOM( statusMessageReporting *smr, xDataTOM_element *TE, xDataXML_element *XE ) {
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*/
1009void *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
#define PATH_MAX
Definition: MCGIDI_map.cc:12
XML_ParserCreate(const XML_Char *encoding)
Definition: xmlparse.cc:677
#define XML_STATUS_ERROR
Definition: expat.h:47
XML_GetErrorCode(XML_Parser parser)
Definition: xmlparse.cc:1841
XML_SetUserData(XML_Parser parser, void *userData)
Definition: xmlparse.cc:1230
XML_ParserFree(XML_Parser parser)
Definition: xmlparse.cc:1136
XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end)
Definition: xmlparse.cc:1279
@ XML_ERROR_NONE
Definition: expat.h:55
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
Definition: xmlparse.cc:1506
XML_ErrorString(enum XML_Error code)
Definition: xmlparse.cc:1934
XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler)
Definition: xmlparse.cc:1300
char XML_Char
#define XMLCALL
const char * name(G4int ptype)
#define smr_setReportError2(smr, libraryID, code, fmt,...)
#define smr_setReportError2p(smr, libraryID, code, fmt)
#define smr_setReportError3(smr, userInterface, libraryID, code, fmt,...)
#define smr_realloc2(smr, old, size, forItem)
#define smr_allocateCopyString2(smr, s, forItem)
void * smr_freeMemory(void **p)
#define smr_setReportError3p(smr, userInterface, libraryID, code, fmt)
int smr_isOk(statusMessageReporting *smr)
char * smr_allocateFormatMessage(char const *fmt,...)
#define smr_malloc2(smr, size, zero, forItem)
xDataTOM_element root
Definition: xDataTOM.h:193
xDataTOM_xDataInfo xDataInfo
Definition: xDataTOM.h:187
xDataTOM_axes axes
Definition: xDataTOM.h:153
xDTXML_releaseFunction release
enum xDataXML_xDataType status
xDTXML_toDataFunction toData
xDataXML_element * element
xDTXML_toStringFunction toString
statusMessageReporting * smr
xDataXML_rootElement * currentRoot
enum xDataXML_errorCodes error
xDataXML_elementListItem * items
xDataXML_rootElement childrenRoot
xDataXML_attributionList attributes
xDataXML_rootElement * parentRoot
xDataXML_element * element
enum xDataXML_itemMode mode
xDataXML_element * parentElement
xDataXML_rootElement * parentRoot
smr_userInterface smrUserInterface
xDataXML_document * doc
xDataTOM_TOM * xDataTOM_mallocTOM(statusMessageReporting *smr)
Definition: xDataTOM.cc:54
int xDataTOME_addAttribute(statusMessageReporting *smr, xDataTOM_element *element, char const *name, char const *value)
Definition: xDataTOM.cc:279
xDataTOM_element * xDataTOM_addElementInElement(statusMessageReporting *smr, xDataTOM_element *parent, int index, char const *name)
Definition: xDataTOM.cc:188
int xDataTOM_setFileNameTOM(statusMessageReporting *smr, xDataTOM_TOM *doc, const char *fileName)
Definition: xDataTOM.cc:94
int xDataTOM_Int
Definition: xDataTOM.h:16
void * xData_initializeData(statusMessageReporting *smr, xDataTOM_element *TE, char const *ID, size_t size)
Definition: xDataTOM.cc:479
void * xDataTOM_freeTOM(statusMessageReporting *smr, xDataTOM_TOM **TOM)
Definition: xDataTOM.cc:78
char const * xDataXML_getFileName(xDataXML_document *doc)
enum xDataXML_itemMode xDataXML_getNextItem(xDataXML_item *item)
void * xDataXML_initializeData(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE, char const *ID, size_t size)
int xDataXML_KalbachMannToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
int xDataXML_regionsW_XYs_LegendreSeriesToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
int xDataXML_getAccessed(statusMessageReporting *smr, xDataXML_element *element)
int xDataXML_polynomialToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
xDataXML_elementList * xDataXML_getElementsByTagName(statusMessageReporting *smr, xDataXML_element *element, char const *tagName)
int xDataXML_W_XYs_LegendreSeriesToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
void * xDataXML_freeDoc(statusMessageReporting *smr, xDataXML_document *doc)
void xDataXML_freeElementList(statusMessageReporting *smr, xDataXML_elementList *list)
int xDataXML_is_xDataType(statusMessageReporting *smr, xDataXMLType *xDT, char const *const type, int setMsg)
int xDataXML_stringTo_double(statusMessageReporting *smr, void *smrUserInterface, char const *c, double *value, char const *endings, char **e)
int xDataXML_XYsToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
int xDataXML_V_W_XYs_LegendreSeriesToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
@ xDataXML_statusError
@ xDataXML_statusParsing
@ xDataXML_statusCompleted
void * xDataXML_get_smrUserInterfaceFromElement(xDataXML_element *element)
struct xDataXML_elementList_s xDataXML_elementList
xDataXML_element * xDataXML_getNextElement(xDataXML_element *element)
char * xDataXML_getAttributesValue(xDataXML_attributionList *attributes, char const *name)
int xDataXML_W_XYsToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
int xDataXML_addToAccessed(statusMessageReporting *smr, xDataXML_element *element, int increment)
@ xDataXML_errFileError
@ xDataXML_errXMLParser
@ xDataXML_errXML_ParserCreate
int xDataXML_attributeListLength(xDataXML_attributionList *attributes)
int xDataXML_parseIsError(xDataXML_document *doc)
xDataTOM_Int xDataXML_convertAttributeTo_xDataTOM_Int(statusMessageReporting *smr, xDataXML_element *element, char const *name, xDataTOM_Int *n, int required)
xDataTOM_TOM * xDataXML_importFile(statusMessageReporting *smr, char const *fileName)
xDataXML_element * xDataXML_getDocumentsElement(xDataXML_document *doc)
char const * xDataXML_getRealFileName(xDataXML_document *doc)
struct xDataXML_attribute_s xDataXML_attribute
int xDataXML_getCommonData(statusMessageReporting *smr, xDataXML_element *element, xDataTOM_Int *index, xDataTOM_Int *start, xDataTOM_Int *end, xDataTOM_Int *length)
char const * xDataXML_getAttributesValueInElement(xDataXML_element *element, char const *name)
@ xDataXML_xDataType_Ok
int xDataXML_stringTo_xDataTOM_Int(statusMessageReporting *smr, void *smrUserInterface, char const *c, xDataTOM_Int *value, char const *endings, char **e)
xDataXML_element * xDataXML_getFirstElement(xDataXML_element *element)
xDataXML_document * xDataXML_getElementsDocument(xDataXML_element *element)
int xDataXML_isAttributeInElement(xDataXML_element *element, char const *name)
int xDataXML_xDataTypeConvertAttributes(statusMessageReporting *smr, xDataXML_element *element)
xDataXML_element * xDataXML_getOneElementByTagName(statusMessageReporting *smr, xDataXML_element *element, char *name, int required)
int xDataXML_regionsXYsToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
int xDataXML_axesElememtToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_axes *axes)
@ xDataXML_itemModeText
@ xDataXML_itemModeElement
@ xDataXML_itemModeEnd
void * xDataXML_get_smrUserInterfaceFromDocument(xDataXML_document *doc)
int xDataXML_numberOfElementsByTagName(statusMessageReporting *smr, xDataXML_element *element, char const *tagName)
int xDataXML_convertAttributeToDouble(statusMessageReporting *smr, xDataXML_element *element, char const *name, double *d, int required)
enum xDataXML_itemMode xDataXML_getFirstItem(xDataXML_element *element, xDataXML_item *item)
xDataXML_attribute * xDataXML_attributeByIndex(xDataXML_attributionList *attributes, int index)
int xDataXML_V_W_XYsToTOM(statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE)
int xDataXML_isAttributeInList(xDataXML_attributionList *attributes, char const *name)
xDataXML_document * xDataXML_importFile2(statusMessageReporting *smr, char const *fileName)
char const * xDataTOM_KalbachMann_ID
char const * xDataTOM_V_W_XYs_ID
char const * xDataTOM_regionsW_XYs_LegendreSeries_ID
char const * xDataTOM_polynomial_ID
char const * xDataTOM_W_XYs_ID
char const * xDataTOM_regionsXYs_ID
char const * xDataTOM_W_XYs_LegendreSeries_ID
char const * xDataTOM_XYs_ID
Definition: xDataTOM_XYs.cc:14
char const * xDataTOM_V_W_XYs_LegendreSeries_ID
int xDataTOM_smrLibraryID
Definition: xDataTOM.cc:34
XML_Size XMLCALL XML_GetCurrentColumnNumber(XML_Parser parser)
Definition: xmlparse.cc:1886
#define userData
Definition: xmlparse.cc:572
XML_Size XMLCALL XML_GetCurrentLineNumber(XML_Parser parser)
Definition: xmlparse.cc:1876
#define buffer
Definition: xmlparse.cc:628