Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members  

init.C

00001 #include <citrus/config.h>
00002 
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <ctype.h>
00006 #include <unistd.h>
00007 #include <math.h>
00008 
00009 #include <libxml/parserInternals.h>
00010 
00011 #include <citrus/Prefix.H>
00012 #include <citrus/Dimension.H>
00013 #include <citrus/DimensionGroup.H>
00014 #include <citrus/Unit.H>
00015 #include <citrus/UnitSystem.H>
00016 
00017 #define _( a )  (a)
00018 #define SUCKY_CAST  (const char*)
00019 
00027 //#define DBG_STARTELE
00028 //#define DBG_ENDELE
00029 
00030 class UnitConfParserState 
00031 {
00032 public:
00033   UnitConfParserState() ;
00034   ~UnitConfParserState() ;
00035   void startElement( const CHAR* name, const CHAR** attrs ) ;
00036   void endElement( const CHAR* name ) ;
00037   void characters( const CHAR* val, int len ) ;
00038   void startDocument() ;
00039   void endDocument() ;
00040   xmlEntityPtr getEntity( const CHAR* name ) ;
00041   void reset() ;
00042 
00043   enum State {
00044     AtTop,
00045     InUnitConf,
00046     InDimensions,
00047     InPrefixes,
00048     InDimensionGroups,
00049     InUnitSystems,
00050     InDimension,
00051     InPrefix,
00052     InGroup,
00053     InDimPower,
00054     InUnit,
00055     InSystem,
00056     InStdUnit,
00057     Unknown
00058   } ;
00059 
00060 protected:
00061   void terminateBuffer() ;
00062   void copyBufferTo( CHAR*& ) ;
00063   void emptyData( CHAR*& ) ;
00064 
00065   static char* stateNames[] ;
00066   State                         level ;
00067   State                         unknownRecover ;
00068   int                           unknownDepth ;
00069   DimensionGroup*               curGroup ;
00070   UnitSystem*                   curSys ;
00071   vector<DimensionPower>        grpPowers ;
00072   CHAR*                         buffer ;
00073   int                           buflen ;
00074   int                           bufmax ;
00075   bool                          rememberString ;
00076 
00077   CHAR*                         nameData ;
00078   CHAR*                         plurData ;
00079   CHAR*                         symData ;
00080   CHAR                          chrData ;
00081   double                        scale ;
00082   double                        offset ;
00083   int                           power ;
00084   bool                          one ;
00085   bool                          avoid ;
00086   bool                          noPlural ;
00087   bool                          noPrefix ;
00088 } ;
00089 
00090 char* UnitConfParserState::stateNames[] = {
00091     "AtTop",
00092     "InUnitConf",
00093     "InDimensions",
00094     "InPrefixes",
00095     "InDimensionGroups",
00096     "InUnitSystems",
00097     "InDimension",
00098     "InPrefix",
00099     "InGroup",
00100     "InDimPower",
00101     "InUnit",
00102     "InSystem",
00103     "InStdUnit",
00104     "Unknown"
00105 } ;
00106 
00107 xmlEntityPtr dumbGetEntity( void* a, const CHAR* name )
00108 {
00109  UnitConfParserState* u = (UnitConfParserState*)a ;
00110  return u->getEntity( name ) ;
00111 }
00112 
00113 void dumbStartDocument( void* a )
00114 {
00115  UnitConfParserState* u = (UnitConfParserState*)a ;
00116  return u->startDocument() ;
00117 }
00118 
00119 void dumbEndDocument( void* a )
00120 {
00121  UnitConfParserState* u = (UnitConfParserState*)a ;
00122  return u->endDocument() ;
00123 }
00124 
00125 void dumbStartElement( void* a, const CHAR* name, const CHAR** attrs )
00126 {
00127  UnitConfParserState* u = (UnitConfParserState*)a ;
00128  u->startElement( name, attrs ) ;
00129 }
00130 
00131 void dumbEndElement( void* a, const CHAR* name )
00132 {
00133  UnitConfParserState* u = (UnitConfParserState*)a ;
00134  u->endElement( name ) ;
00135 }
00136 
00137 void dumbCharacters( void* a, const CHAR* chr, int len )
00138 {
00139  UnitConfParserState* u = (UnitConfParserState*)a ;
00140  u->characters( chr, len ) ;
00141 }
00142 
00143 static xmlSAXHandler unitConfSAXParser = {
00144    0, /* internalSubset */
00145    0, /* isStandalone */
00146    0, /* hasInternalSubset */
00147    0, /* hasExternalSubset */
00148    0, /* resolveEntity */
00149    (getEntitySAXFunc)&dumbGetEntity, /* getEntity */
00150    0, /* entityDecl */
00151    0, /* notationDecl */
00152    0, /* attributeDecl */
00153    0, /* elementDecl */
00154    0, /* unparsedEntityDecl */
00155    0, /* setDocumentLocator */
00156    (startDocumentSAXFunc)&dumbStartDocument, /* startDocument */
00157    (endDocumentSAXFunc)&dumbEndDocument, /* endDocument */
00158    (startElementSAXFunc)&dumbStartElement, /* startElement */
00159    (endElementSAXFunc)&dumbEndElement, /* endElement */
00160    0, /* reference */
00161    (charactersSAXFunc)&dumbCharacters, /* characters */
00162    0, /* ignorableWhitespace */
00163    0, /* processingInstruction */
00164    0, /*(commentSAXFunc)UnitConfParserState::comment, /* comment */
00165    0, /* (warningSAXFunc)UnitConfParserState::warning, /* warning */
00166    0, /* (errorSAXFunc)UnitConfParserState::error, /* error */
00167    0, /* (fatalErrorSAXFunc)UnitConfParserState::fatalError, /* fatalError */
00168 } ;
00169 
00170 int UnitReadConfig( const char* filename )
00171 {
00172   xmlParserCtxtPtr      ctxt;
00173   UnitConfParserState   ups ;
00174 
00175   ctxt = xmlCreateFileParserCtxt( filename ) ;
00176   if (ctxt == 0)
00177     return -1 ;
00178 
00179   ctxt->sax = &unitConfSAXParser ;
00180   ctxt->userData = &ups ;
00181   xmlParseDocument( ctxt ) ;
00182 
00183   if (!ctxt->wellFormed) {
00184     return -1 ;
00185     // ABORT ABORT ABORT (free memory from state)
00186   }
00187   ctxt->sax = 0 ;
00188   xmlFreeParserCtxt( ctxt ) ;
00189 
00190   return 0 ;
00191 }
00192 
00193 UnitConfParserState::UnitConfParserState()
00194 {
00195   bufmax = 512*sizeof(CHAR) ;
00196   buffer = (CHAR*) malloc( 512*sizeof(CHAR) ) ;
00197 
00198   nameData = 0 ;
00199   plurData = 0 ;
00200   symData  = 0 ;
00201   scale = dtNaN ;
00202   offset = dtNaN ;
00203   power = 0 ;
00204   chrData  = CHAR('\0') ;
00205 
00206   reset() ;
00207 }
00208 
00209 UnitConfParserState::~UnitConfParserState()
00210 {
00211   reset() ;
00212   free( buffer ) ;
00213 }
00214 
00215 void UnitConfParserState::startElement( const CHAR* name,
00216                                         const CHAR** attrs )
00217 {
00218 
00219 #ifdef DBG_STARTELE
00220   fprintf( stderr, "[%s] startElement( %s", stateNames[level], name ) ;
00221   if ( attrs ) {
00222     for (int i=0; attrs[i] ; i+=2 )
00223       fprintf( stderr, ", %s='%s'", attrs[i], attrs[i+1] ) ;
00224   }
00225   fprintf( stderr, " )\n" ) ;
00226 #endif // DBG_STARTELE
00227 
00228   switch( level ) {
00229   case AtTop:
00230     if ( strcmp( SUCKY_CAST name, "unitconf" ) )
00231       fprintf( stderr, _("Expected unitconf as toplevel element, got <%s> tag."), name );
00232     else
00233       level = InUnitConf ;
00234     break ;
00235   case InUnitConf:
00236     if ( strcmp( SUCKY_CAST name, "dimensions" ) == 0 ) {
00237       level = InDimensions ;
00238     } else if ( strcmp( SUCKY_CAST name, "prefixes" ) == 0 ) {
00239       level = InPrefixes ;
00240     } else if ( strcmp( SUCKY_CAST name, "dimensiongroups" ) == 0 ) {
00241       level = InDimensionGroups ;
00242     } else if ( strcmp( SUCKY_CAST name, "unitsystems" ) == 0 ) {
00243       level = InUnitSystems ;
00244     } else {
00245       unknownRecover = level ;
00246       unknownDepth++ ;
00247       level = Unknown ;
00248     }
00249     break ;
00250   case InDimensions:
00251     emptyData( nameData ) ;
00252     chrData = '\0' ;
00253     if ( strcmp( SUCKY_CAST name, "dimension" ) == 0 ) {
00254       level = InDimension ;
00255       if ( attrs ) {
00256         for ( int i=0; attrs[i] ; i+=2 ) {
00257           if ( strcmp( SUCKY_CAST attrs[i], "char" ) == 0 )
00258             chrData = attrs[i+1][0] ;
00259           else
00260             fprintf( stderr, _("Expecting (char), got %s attrib.\n"), attrs[i]);
00261         }
00262       }
00263     } else {
00264       fprintf( stderr, _("Expecting dimension, got %s tag.\n"), name ) ;
00265       unknownRecover = level ;
00266       unknownDepth++ ;
00267       level = Unknown ;
00268     }
00269     break ;
00270   case InPrefixes:
00271     if ( strcmp( SUCKY_CAST name, "prefix" ) == 0 ) {
00272       level = InPrefix ;
00273       avoid = false ;
00274       emptyData( nameData ) ;
00275       emptyData( symData ) ;
00276       power = 0 ;
00277       if ( attrs ) {
00278         for ( int i=0; attrs[i] != 0 ; i++ ) {
00279           if ( strcmp( SUCKY_CAST attrs[i], "exponent" ) == 0 )
00280             power = atoi( SUCKY_CAST attrs[++i] ) ;
00281           else if ( strcmp( SUCKY_CAST attrs[i], "avoid" ) == 0 )
00282             avoid = tolower( attrs[++i][0] ) == 't' ;
00283           else
00284             fprintf( stderr, _("Expecting exponent or avoid, got %s attrib.\n"), attrs[i++] );
00285         }
00286       }
00287     } else {
00288       fprintf( stderr, _("Expecting dimension, got %s tag.\n"), name ) ;
00289       unknownRecover = level ;
00290       unknownDepth++ ;
00291       level = Unknown ;
00292     }
00293     break ;
00294   case InDimensionGroups:
00295     if ( strcmp( SUCKY_CAST name, "group" ) == 0 ) {
00296       level = InGroup ;
00297       grpPowers.clear() ;
00298       curGroup = new DimensionGroup ;
00299       emptyData( nameData ) ;
00300     } else {
00301       fprintf( stderr, _("Expecting group, got %s tag.\n"), name ) ;
00302       unknownRecover = level ;
00303       unknownDepth++ ;
00304       level = Unknown ;
00305     }
00306     break ;
00307   case InGroup:
00308     if ( strcmp( SUCKY_CAST name, "dimpower" ) == 0 ) {
00309       level = InDimPower ;
00310       chrData = '\0' ;
00311       power = 0 ;
00312       for ( int i=0; attrs[i] != 0 ; i++ ) {
00313         if ( strcmp( SUCKY_CAST attrs[i], "dim" ) == 0 )
00314           chrData = attrs[++i][0] ;
00315         else if ( strcmp( SUCKY_CAST attrs[i], "pwr" ) == 0 )
00316           power = atoi( SUCKY_CAST attrs[++i] ) ;
00317         else
00318           fprintf( stderr, _("Expecting dim, or pwr, got %s attrib.\n"), attrs[i++] );
00319       }
00320       // Handle attribs
00321       if ( (chrData=='\0') || !power || !curGroup ) {
00322         fprintf( stderr, _("Not all required attributes set or no group.\n") ) ;
00323       } else {
00324         Dimension* dimn = find_dsym( (char) chrData ) ;
00325         if ( ! dimn ) {
00326           fprintf( stderr, _("Expecting a base dimension symbol, got %c.\n"), 
00327                     chrData ) ;
00328         } else {
00329           grpPowers.push_back( DimensionPower( dimn, power ) ) ;
00330         }
00331       }
00332     } else if ( strcmp( SUCKY_CAST name, "unit" ) == 0 ) {
00333       level = InUnit ;
00334       emptyData( nameData ) ;
00335       emptyData( plurData ) ;
00336       emptyData( symData  ) ;
00337       scale = dtNaN ;
00338       offset = dtNaN ;
00339       noPlural = false ;
00340       noPrefix = false ;
00341       avoid    = false ;
00342       one      = false ;
00343       for ( int i=0; attrs[i] != 0 ; i++ ) {
00344         if ( strcmp( SUCKY_CAST attrs[i], "scale" ) == 0 ) {
00345           scale = atof( SUCKY_CAST attrs[++i] ) ;
00346           //fprintf( stderr, "\t==>Unit(%s, %g)\n", name, scale ) ;
00347         } else if ( strcmp( SUCKY_CAST attrs[i], "offset" ) == 0 )
00348           offset = atof( SUCKY_CAST attrs[++i] ) ;
00349         else if ( strcmp( SUCKY_CAST attrs[i], "noplural" ) == 0 )
00350           noPlural = tolower( attrs[++i][0] ) == 't' ;
00351         else if ( strcmp( SUCKY_CAST attrs[i], "noprefix" ) == 0 )
00352           noPrefix = tolower( attrs[++i][0] ) == 't' ;
00353         else if ( strcmp( SUCKY_CAST attrs[i], "avoid" ) == 0 )
00354           avoid = tolower( attrs[++i][0] ) == 't' ;
00355         else if ( strcmp( SUCKY_CAST attrs[i], "one" ) == 0 )
00356           one = tolower( attrs[++i][0] ) == 't' ;
00357         else if ( strcmp( SUCKY_CAST attrs[i], "args" ) == 0 )
00358           i++ ; // ignore this for now
00359         else
00360           fprintf( stderr, _("Expecting (scale|offset|"
00361                       "noplural|noprefix|avoid|one), got %s attrib.\n"),
00362                                 attrs[i++] );
00363       }
00364     } else if ( (strcmp( SUCKY_CAST name, "name" ) == 0) ||
00365                 (strcmp( SUCKY_CAST name, "alias" ) == 0) ) {
00366       buflen = 0 ;
00367       rememberString = true ;
00368     } else {
00369       fprintf( stderr, _("Expecting dimpower or unit, got %s tag.\n"), name ) ;
00370       unknownRecover = level ;
00371       unknownDepth++ ;
00372       level = Unknown ;
00373     }
00374     break ;
00375   case InUnitSystems:
00376     // not handled yet
00377     if ( strcmp( SUCKY_CAST name, "system" ) == 0 ) {
00378       level = InSystem ;
00379       curSys = new UnitSystem ;
00380       // Handle attribs
00381     } else {
00382       fprintf( stderr, _("Expecting system, got %s tag.\n"), name ) ;
00383       unknownRecover = level ;
00384       unknownDepth++ ;
00385       level = Unknown ;
00386     }
00387     break ;
00388   case InSystem:
00389     if ( strcmp( SUCKY_CAST name, "stdunit" ) == 0 ) {
00390       level = InStdUnit ;
00391       // Handle attribs
00392 
00393     } else if ( ( strcmp( SUCKY_CAST name, "name" ) == 0 ) || 
00394                 ( strcmp( SUCKY_CAST name, "description" ) == 0 ) ||
00395                 ( strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) ) {
00396       rememberString = true ;
00397       buflen = 0 ;
00398     } else {
00399       fprintf( stderr, _("Expecting (stdunit|name|abbrev|description), got %s tag.\n"), name ) ;
00400       unknownRecover = level ;
00401       unknownDepth++ ;
00402       level = Unknown ;
00403     }
00404     break ;
00405   case InPrefix:
00406   case InDimension:
00407   case InUnit:
00408   case InDimPower:
00409   case InStdUnit:
00410     if ( (strcmp( SUCKY_CAST name, "name" ) == 0 ) ||
00411          (strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) ||
00412          (strcmp( SUCKY_CAST name, "description" ) == 0 ) ||
00413          (strcmp( SUCKY_CAST name, "spec" ) == 0 ) ||
00414          (strcmp( SUCKY_CAST name, "group" ) == 0 ) ||
00415          (strcmp( SUCKY_CAST name, "dgroup" ) == 0 ) ||
00416          (strcmp( SUCKY_CAST name, "plural" ) == 0 ) ||
00417          (strcmp( SUCKY_CAST name, "alias" ) == 0 ) ) {
00418       buflen = 0 ;
00419       rememberString = true ;
00420     } else {
00421       fprintf( stderr, _("start %s: Go away, you shouldn't be here.\n"), SUCKY_CAST name ) ;
00422       unknownRecover = level ;
00423       unknownDepth++ ;
00424       level = Unknown ;
00425     }
00426     break ;
00427   case Unknown:
00428     unknownDepth++ ;
00429   }
00430 }
00431 
00432 void UnitConfParserState::endElement( const CHAR* name )
00433 {
00434 #ifdef DBG_ENDELE
00435   fprintf( stderr, "[%s] endElement( %s )\n", stateNames[level], name ) ;
00436 #endif // DBG_ENDELE
00437 
00438   switch (level) {
00439   case AtTop:
00440     fprintf( stderr, _("end %s: Go away, you shouldn't be here.\n"), SUCKY_CAST name ) ;
00441     break ;
00442   case InUnitConf:
00443     level = AtTop ;
00444     break ;
00445   case InPrefix:
00446     if ( strcmp( SUCKY_CAST name, "prefix" ) == 0 ) {
00447       if ( !nameData || !symData || !power )
00448         fprintf( stderr, _("Not all required attributes set.\n") ) ;
00449       else
00450         new Prefix( SUCKY_CAST nameData, SUCKY_CAST symData, power ) ;
00451       level = InPrefixes ;
00452     } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00453       copyBufferTo( nameData ) ;
00454     } else if ( strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) {
00455       copyBufferTo( symData ) ;
00456     }
00457     break ;
00458   case InDimension:
00459     if ( strcmp( SUCKY_CAST name, "dimension" ) == 0 ) {
00460       if ( (!nameData) || (chrData == '\0') ) {
00461         fprintf( stderr, _("Dimension must have a name and a character symbol.\n") ) ;
00462       } else {
00463         //fprintf( stderr, "\t==>Dimension(%s, %c)\n", nameData, chrData ) ;
00464         new Dimension( SUCKY_CAST nameData, (char) chrData ) ;
00465       }
00466       level = InDimensions ;
00467     } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00468       copyBufferTo( nameData ) ;
00469     }
00470     break ;
00471   case InGroup:
00472     if ( strcmp( SUCKY_CAST name, "group" ) == 0 ) {
00473       if ( curGroup ) {
00474         if ( ! curGroup->name() )
00475           fprintf( stderr, _("You must specify a group name.\n") ) ;
00476 
00477         if ( grpPowers.size() > 0 ) {
00478           curGroup->setDimensions( grpPowers ) ;
00479           curGroup = 0 ;
00480         }
00481       }
00482 
00483       level = InDimensionGroups ;
00484     } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00485       copyBufferTo( nameData ) ;
00486       if ( curGroup )
00487         curGroup->name( SUCKY_CAST nameData ) ;
00488     } else if ( strcmp( SUCKY_CAST name, "alias" ) == 0 ) {
00489       terminateBuffer() ;
00490       /*
00491       if ( curGroup )
00492         curGroup->alias( SUCKY_CAST buffer ) ;
00493       */
00494     }
00495     break ;
00496   case InUnit:
00497     if ( strcmp( SUCKY_CAST name, "unit" ) == 0 ) {
00498       if ( !nameData || !curGroup || isnan(scale) ) {
00499         fprintf( stderr, _("Not all required attributes set or no group.\n") ) ;
00500         fprintf( stderr, "nameData=0x%x, symData=0x%x, scale=%g, curGroup=0x%x\n", nameData, symData, scale, curGroup ) ;
00501       } else {
00502         Unit* u ;
00503         if ( symData )
00504           u = new Unit( SUCKY_CAST nameData, SUCKY_CAST symData, 
00505                         scale, curGroup ) ;
00506         else // if no abbreviation, the unit name itself is used.
00507           u = new Unit( SUCKY_CAST nameData, SUCKY_CAST nameData, 
00508                         scale, curGroup ) ;
00509         u->prefix( !noPrefix ) ;
00510         u->avoid( avoid ) ;
00511         u->one( one ) ;
00512         if ( !isnan(offset) )
00513           u->offset( offset ) ;
00514         if ( noPlural ) {
00515           if ( plurData )
00516             fprintf( stderr, _("You cannot specify noplural and a plural form.\n") ) ;
00517           else
00518             u->plural( CITRUS_PLURAL_NONE ) ;
00519         } else {
00520           if ( plurData ) 
00521             u->plural( SUCKY_CAST plurData ) ;
00522         }
00523         if ( strcmp( SUCKY_CAST nameData, "none" ) == 0 )
00524           Unit::s_dimensionless = u ;
00525         emptyData( nameData ) ;
00526         emptyData( plurData ) ;
00527         emptyData( symData ) ;
00528       }
00529 
00530       level = InGroup ;
00531     } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00532       copyBufferTo( nameData ) ;
00533     } else if ( strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) {
00534       copyBufferTo( symData ) ;
00535     } else if ( strcmp( SUCKY_CAST name, "plural" ) == 0 ) {
00536       copyBufferTo( plurData ) ;
00537     }
00538     break ;
00539   case InDimPower:
00540     level = InGroup ;
00541     break ;
00542   case InStdUnit:
00543     if ( strcmp( SUCKY_CAST name, "stdunit" ) == 0 ) {
00544       level = InSystem ;
00545       if ( curSys && nameData && symData ) {
00546         DimensionGroup* dgrp = DimensionGroup::find( SUCKY_CAST nameData ) ;
00547         if ( dgrp )
00548           if ( ! curSys->addSpec( dgrp, SUCKY_CAST symData ) )
00549             fprintf( stderr, "Bad specification for %s (%s=%s)\n",
00550                      curSys->name(), nameData, symData ) ;
00551       }
00552     } else if ( strcmp( SUCKY_CAST name, "dgroup" ) == 0 ) {
00553       copyBufferTo( nameData ) ;      
00554     } else if ( strcmp( SUCKY_CAST name, "spec" ) == 0 ) {
00555       copyBufferTo( symData ) ;
00556     }
00557     break ;
00558   case InSystem:
00559     if ( strcmp( SUCKY_CAST name, "system" ) == 0 ) {
00560       level = InUnitSystems ;
00561       curSys = 0 ;
00562     } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00563       terminateBuffer() ;
00564       if ( curSys )
00565         curSys->name( SUCKY_CAST buffer ) ;
00566     } else if ( strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) {
00567       terminateBuffer() ;
00568       if ( curSys )
00569         curSys->abbr( SUCKY_CAST buffer ) ;
00570     } else if ( strcmp( SUCKY_CAST name, "description" ) == 0 ) {
00571       terminateBuffer() ;
00572       if ( curSys )
00573         curSys->description( SUCKY_CAST buffer ) ;
00574     }
00575     break ;
00576   case InDimensionGroups:
00577   case InDimensions:
00578   case InPrefixes:
00579   case InUnitSystems:
00580     level = InUnitConf ;
00581     break ;
00582   case Unknown:
00583     unknownDepth-- ;
00584     if ( unknownDepth == 0 )
00585       level = unknownRecover ;
00586     break ;
00587   }
00588   rememberString = false ;
00589   buflen = 0 ;
00590 }
00591 
00592 void UnitConfParserState::characters( const CHAR* text, int len )
00593 {
00594   if ( ! rememberString )
00595     return ;
00596 
00597   if ( len > bufmax - buflen ) {
00598     bufmax <<= 1 ;
00599     buffer = (CHAR*) realloc( buffer, sizeof(CHAR)*bufmax ) ;
00600   }
00601   memcpy( buffer + buflen, text, len*sizeof(CHAR) ) ;
00602   buflen += len*sizeof(CHAR) ;
00603 }
00604 
00605 xmlEntityPtr UnitConfParserState::getEntity( const CHAR* name )
00606 {
00607   return xmlGetPredefinedEntity( name ) ;
00608 }
00609 
00610 void UnitConfParserState::startDocument()
00611 {
00612   reset() ;
00613 }
00614 
00615 void UnitConfParserState::endDocument()
00616 {
00617   if ( curGroup )
00618     delete curGroup ;
00619   if ( curSys )
00620     delete curSys ;
00621 }
00622 
00623 void UnitConfParserState::reset()
00624 {
00625   // per document initialization (also called on construction)
00626   level = AtTop ;
00627   unknownRecover = AtTop ;
00628   unknownDepth = 0 ;
00629   curGroup = 0 ;
00630   curSys = 0 ;
00631   buflen = 0 ;
00632   rememberString = false ;
00633   emptyData( nameData ) ;
00634   emptyData( plurData ) ;
00635   emptyData( symData ) ;
00636   power = 0 ;
00637   scale = dtNaN ;
00638   offset = dtNaN ;
00639 }
00640 
00641 void UnitConfParserState::terminateBuffer()
00642 {
00643   if ( buflen == bufmax ) {
00644     bufmax <<= 1 ;
00645     buffer = (CHAR*) realloc( buffer, sizeof(CHAR)*bufmax ) ;
00646   }
00647 
00648   buffer[ buflen ] = CHAR('\0') ;
00649 }
00650 
00651 void UnitConfParserState::copyBufferTo( CHAR*& string )
00652 {
00653   if ( string )
00654     emptyData( string ) ;
00655 
00656   string = new CHAR[ buflen + 1 ] ;
00657   memcpy( string, buffer, buflen ) ;
00658   string[ buflen ] = CHAR('\0') ;
00659 }
00660 
00661 void UnitConfParserState::emptyData( CHAR*& string )
00662 {
00663   if ( string )
00664     delete [] string ;
00665 
00666   string = 0 ;
00667 }
Citrus C++ Reference Manual  20010520