00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "GaudiKernel/Property.h"
00020 #include "GaudiKernel/PropertyCallbackFunctor.h"
00021
00022
00023
00024 #include <iostream>
00025 #include <stdexcept>
00026
00027
00028
00029
00030
00031
00032
00033 static
00034 std::istream&
00035 valueFromStreamHelper( std::istream& i, Property& p );
00036
00037 static
00038 std::ostream&
00039 nameValueAsStreamHelper( std::ostream& o, const Property& p, size_t vSize );
00040
00041 static char getFirstNonBlank(std::istream& i) {
00042 char delim;
00043 while ((delim=i.get()) == ' ' ) {
00044 if ( i.fail() ) {
00045 throw Property::bad_call();
00046 }
00047 }
00048 if ( delim != '"' && delim != '\'' ) i.putback(delim);
00049 return delim;
00050 }
00051
00052 template <class T>
00053 static void getQuotedItem( std::istream& i, T& temp ) {
00054 char c = getFirstNonBlank(i);
00055 i >> temp;
00056 if ( c == '"' ) {
00057 while ((c=i.get()) != '"' && !i.fail() >= 0 ) {}
00058 }
00059 else if ( c == '\'' ) {
00060 while ((c=i.get()) != '\'' && !i.fail() >= 0 ) {}
00061 }
00062 }
00063
00064 template <>
00065 static void getQuotedItem( std::istream& i, std::string& temp ) {
00066 char c = getFirstNonBlank(i);
00067 if ( c != '"' && c != '\'' ) {
00068 i >> temp;
00069 }
00070 else {
00071 if( c == '"' ) {
00072 while ( (c=i.get()) != '"' && !i.fail()) {
00073 temp += c;
00074 }
00075 }
00076 else if( c == '\'' ) {
00077 while ( (c=i.get()) != '\'' && !i.fail()) {
00078 temp += c;
00079 }
00080 }
00081 }
00082 }
00083
00084
00085
00086
00088
00090
00091 Property::nameFromStream( std::istream& i ) {
00092 i >> m_name;
00093 m_name = m_name.substr( 1, m_name.length() - 3 );
00094 i.ignore();
00095 return i;
00096 }
00097
00099
00101 std::istream&
00102 Property::nameAndValueFromStream( std::istream& i ) {
00103 nameFromStream( i );
00104 valueFromStream( i );
00105 return i;
00106 }
00107
00108
00110
00112 template< class T, class VT >
00113 std::istream&
00114 SimpleProperty< T, VT >::nameAndValueFromStream( std::istream& i ) {
00115 return Property::nameAndValueFromStream( i );
00116 }
00117
00118 template< class T, class VT >
00119 std::istream&
00120 SimpleProperty< T, VT >::valueFromStream( std::istream& i ) {
00121 T value;
00122
00123 i >> value;
00124 if ( !set( value ) ) {
00125 throw std::out_of_range( "Value not verified" );
00126 }
00127 return i;
00128 }
00129
00131
00133 template< class T, class VT >
00134 std::ostream&
00135 SimpleProperty< T, VT >::nameAndValueAsStream( std::ostream& o ) const {
00136 return o << "\"" << m_name << "\": " << m_value;
00137 }
00138
00140
00142 template< class T, class VT >
00143 Property*
00144 SimpleProperty< T, VT >::cloneRef() const {
00145 return new SimplePropertyRef< T, VT >( m_name, m_value, m_verifier );
00146 }
00147
00148 template< class T, class VT >
00149 bool
00150 SimpleProperty< T, VT >::assign( const Property& p ) {
00151 typedef SimpleProperty< T > TypedProperty;
00152 typedef SimplePropertyRef< T > TypedPropertyRef;
00153
00154 if( p.isRef() ) {
00155 const TypedPropertyRef& tp = dynamic_cast< const TypedPropertyRef& > ( p );
00156 return set( tp.value() );
00157 } else {
00158 const TypedProperty& tp = dynamic_cast< const TypedProperty& > ( p );
00159 return set( tp.value() );
00160 }
00161 }
00162
00163 template< class T, class VT >
00164 bool
00165 SimpleProperty< T, VT >::load( Property& p ) const {
00166 typedef SimpleProperty< T > TypedProperty;
00167 typedef SimplePropertyRef< T > TypedPropertyRef;
00168
00169 if( p.isRef() ) {
00170 TypedPropertyRef& tp = dynamic_cast< TypedPropertyRef& > ( p );
00171 return tp.set( m_value );
00172 } else {
00173 TypedProperty& tp = dynamic_cast< TypedProperty& > ( p );
00174 return tp.set( m_value );
00175 }
00176 }
00177
00179
00181 template< class T, class VT >
00182 std::ostream&
00183 SimpleProperty< T, VT >::valueElementAsStream( std::ostream& o, size_t ) const {
00184 throw bad_call();
00185 return o;
00186 }
00187
00188 template< class T, class VT >
00189 std::istream&
00190 SimpleProperty< T, VT >::valueElementFromStream( std::istream& i ) {
00191 throw bad_call();
00192 return i;
00193 }
00194
00195
00196
00197
00199
00201
00202 template<>
00203 std::istream&
00204 SimpleProperty< std::string,
00205 BoundedVerifier< std::string > >::valueFromStream( std::istream& i ) {
00206 std::string value;
00207 getQuotedItem(i, value);
00208 if ( !set( value ) ) {
00209 throw std::out_of_range( "Value not verified" );
00210 }
00211 return i;
00212 }
00213
00215
00217
00218 template<>
00219 std::ostream&
00220 SimpleProperty< std::string,
00221 BoundedVerifier< std::string > >::nameAndValueAsStream( std::ostream& o ) const {
00222 return o << "\"" << m_name << "\": " << "\"" << m_value << "\"";
00223 }
00224
00225
00226
00227
00229
00231
00232 std::istream&
00233 SimplePropertyRef< T, VT >::nameAndValueFromStream( std::istream& i ) {
00234 return Property::nameAndValueFromStream( i );
00235 }
00236
00237 template< class T, class VT >
00238 std::istream&
00239 SimplePropertyRef< T, VT >::valueFromStream( std::istream& i ) {
00240 T value;
00241
00242 i >> value;
00243 if ( !set( value ) ) {
00244 throw std::out_of_range( "Value not verified" );
00245 }
00246 return i;
00247 }
00248
00250
00252 template< class T, class VT >
00253 std::ostream&
00254 SimplePropertyRef< T, VT >::nameAndValueAsStream( std::ostream& o ) const {
00255 return o << "\"" << m_name << "\": " << value();
00256 }
00257
00259
00261 template< class T, class VT >
00262 Property*
00263 SimplePropertyRef< T, VT >::cloneRef() const {
00264 return new SimplePropertyRef< T, VT >( m_name, m_value, m_verifier );
00265 }
00266
00267 template< class T, class VT >
00268 bool
00269 SimplePropertyRef< T, VT >::assign( const Property& p ) {
00270 typedef SimpleProperty< T > TypedProperty;
00271 typedef SimplePropertyRef< T > TypedPropertyRef;
00272
00273 if( p.isRef() ) {
00274 const TypedPropertyRef& tp = dynamic_cast< const TypedPropertyRef& > ( p );
00275 return set( tp.value() );
00276 } else {
00277 const TypedProperty& tp = dynamic_cast< const TypedProperty& > ( p );
00278 return set( tp.value() );
00279 }
00280 }
00281
00282 template< class T, class VT >
00283 bool
00284 SimplePropertyRef< T, VT >::load( Property& p ) const {
00285 typedef SimpleProperty< T > TypedProperty;
00286 typedef SimplePropertyRef< T > TypedPropertyRef;
00287
00288 if( p.isRef() ) {
00289 TypedPropertyRef& tp = dynamic_cast< TypedPropertyRef& > ( p );
00290 return tp.set( m_value );
00291 } else {
00292 TypedProperty& tp = dynamic_cast< TypedProperty& > ( p );
00293 return tp.set( m_value );
00294 }
00295 }
00296
00298
00300 template< class T, class VT >
00301 std::ostream&
00302 SimplePropertyRef< T, VT >::valueElementAsStream( std::ostream& o, size_t ) const {
00303 throw bad_call();
00304 return o;
00305 }
00306
00307 template< class T, class VT >
00308 std::istream&
00309 SimplePropertyRef< T, VT >::valueElementFromStream( std::istream& i ) {
00310 throw bad_call();
00311 return i;
00312 }
00313
00314
00315
00316
00318
00320
00321 template<>
00322 std::istream&
00323 SimplePropertyRef< std::string,
00324 NullVerifier< std::string > >::valueFromStream( std::istream& i ) {
00325 std::string value;
00326 getQuotedItem(i, value);
00327 if ( !set( value ) ) {
00328 throw std::out_of_range( "Value not verified" );
00329 }
00330 return i;
00331 }
00332
00334
00336
00337 template<>
00338 std::ostream&
00339 SimplePropertyRef< std::string,
00340 NullVerifier< std::string > >::nameAndValueAsStream( std::ostream& o ) const {
00341 return o << "\"" << m_name << "\": " << "\"" << m_value << "\"";
00342 }
00343
00345
00347
00348 template<>
00349 std::istream&
00350 SimplePropertyRef< std::string,
00351 BoundedVerifier< std::string > >::valueFromStream( std::istream& i ) {
00352 std::string value;
00353 i >> value;
00354 value = value.substr( 1, value.length() - 2 );
00355 if ( !set( value ) ) {
00356 throw std::out_of_range( "Value not verified" );
00357 }
00358 return i;
00359 }
00360
00362
00364
00365 template<>
00366 std::ostream&
00367 SimplePropertyRef< std::string,
00368 BoundedVerifier< std::string > >::nameAndValueAsStream( std::ostream& o ) const {
00369 return o << "\"" << m_name << "\": " << "\"" << m_value << "\"";
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 #define UNQUOTEDELEMENTOUTPUT return o << m_value[ix];
00381 #define QUOTEDELEMENTOUTPUT return o << "\"" << m_value[ix] << "\"";
00382 #define UNQUOTEDELEMENTINPUT i >> temp;
00383
00384 #define QUOTEDELEMENTINPUT getQuotedItem(i, temp);
00385
00386 #define ARRAYPROPERTIES(TYPENAME,BASETYPE,QUOTESTYLE) \
00387 template<> \
00388 std::ostream& \
00389 TYPENAME##ArrayProperty::nameAndValueAsStream( std::ostream& o ) const \
00390 { \
00391 return nameValueAsStreamHelper( o, *this, value().size() ); \
00392 } \
00393 \
00394 template<> \
00395 std::istream& \
00396 TYPENAME##ArrayProperty::valueFromStream( std::istream& i ) \
00397 { \
00398 m_value.clear(); \
00399 std::istream& result = valueFromStreamHelper( i, *this ); \
00400 if ( 0 != m_updateCallback ) ( *m_updateCallback )( *this ); \
00401 return result; \
00402 } \
00403 \
00404 template<> \
00405 std::istream& \
00406 TYPENAME##ArrayProperty::nameAndValueFromStream( std::istream& i ) \
00407 { \
00408 m_name.erase(); \
00409 m_value.clear(); \
00410 nameFromStream( i ); \
00411 return valueFromStream( i ); \
00412 } \
00413 \
00414 template<> \
00415 std::ostream& \
00416 TYPENAME##ArrayProperty::valueElementAsStream( std::ostream& o, size_t ix ) const \
00417 { \
00418 QUOTESTYLE##ELEMENTOUTPUT \
00419 } \
00420 \
00421 template<> \
00422 std::istream& \
00423 TYPENAME##ArrayProperty::valueElementFromStream( std::istream& i ) \
00424 { \
00425 BASETYPE temp; \
00426 QUOTESTYLE##ELEMENTINPUT \
00427 m_value.push_back( temp ); \
00428 return i; \
00429 } \
00430 \
00431 \
00432 \
00433 typedef SimplePropertyRef< std::vector< BASETYPE >, \
00434 BoundedVerifier< std::vector< BASETYPE > > > \
00435 Cloned##TYPENAME##ArrayPropertyRef; \
00436 template<> \
00437 std::ostream& \
00438 Cloned##TYPENAME##ArrayPropertyRef::nameAndValueAsStream( std::ostream& o ) const \
00439 { \
00440 return nameValueAsStreamHelper( o, *this, value().size() ); \
00441 } \
00442 \
00443 template<> \
00444 std::istream& \
00445 Cloned##TYPENAME##ArrayPropertyRef::valueFromStream( std::istream& i ) \
00446 { \
00447 m_value.clear(); \
00448 std::istream& result = valueFromStreamHelper( i, *this ); \
00449 if ( 0 != m_updateCallback ) ( *m_updateCallback )( *this ); \
00450 return result; \
00451 } \
00452 \
00453 template<> \
00454 std::istream& \
00455 Cloned##TYPENAME##ArrayPropertyRef::nameAndValueFromStream( std::istream& i ) \
00456 { \
00457 m_name.erase(); \
00458 m_value.clear(); \
00459 nameFromStream( i ); \
00460 return valueFromStream( i ); \
00461 } \
00462 \
00463 template<> \
00464 std::ostream& \
00465 Cloned##TYPENAME##ArrayPropertyRef::valueElementAsStream( std::ostream& o, size_t ix ) const \
00466 { \
00467 QUOTESTYLE##ELEMENTOUTPUT \
00468 } \
00469 \
00470 template<> \
00471 std::istream& \
00472 Cloned##TYPENAME##ArrayPropertyRef::valueElementFromStream( std::istream& i ) \
00473 { \
00474 BASETYPE temp; \
00475 QUOTESTYLE##ELEMENTINPUT \
00476 m_value.push_back( temp ); \
00477 return i; \
00478 } \
00479
00480
00481 ARRAYPROPERTIES(Boolean,bool,UNQUOTED)
00482 ARRAYPROPERTIES(Char,char,UNQUOTED)
00483 ARRAYPROPERTIES(SignedChar,signed char,UNQUOTED)
00484 ARRAYPROPERTIES(UnsignedChar,unsigned char,UNQUOTED)
00485 ARRAYPROPERTIES(Short,short,UNQUOTED)
00486 ARRAYPROPERTIES(UnsignedShort,unsigned short,UNQUOTED)
00487 ARRAYPROPERTIES(Integer,int,UNQUOTED)
00488 ARRAYPROPERTIES(UnsignedInteger,unsigned int,UNQUOTED)
00489 ARRAYPROPERTIES(Long,long,UNQUOTED)
00490 ARRAYPROPERTIES(UnsignedLong,unsigned long,UNQUOTED)
00491 ARRAYPROPERTIES(Float,float,UNQUOTED)
00492 ARRAYPROPERTIES(Double,double,UNQUOTED)
00493 ARRAYPROPERTIES(LongDouble,long double,UNQUOTED)
00494
00495 ARRAYPROPERTIES(String,std::string,QUOTED)
00496 #undef ARRAYPROPERTIES
00497
00498
00499
00500
00501
00502
00503
00504
00505 #define ARRAYPROPERTYREFS(TYPENAME,BASETYPE,QUOTESTYLE) \
00506 \
00507 \
00508 template<> \
00509 std::ostream& \
00510 TYPENAME##ArrayPropertyRef::nameAndValueAsStream( std::ostream& o ) const \
00511 { \
00512 return nameValueAsStreamHelper( o, *this, value().size() ); \
00513 } \
00514 \
00515 template<> \
00516 std::istream& \
00517 TYPENAME##ArrayPropertyRef::valueFromStream( std::istream& i ) \
00518 { \
00519 m_value.clear(); \
00520 std::istream& result = valueFromStreamHelper( i, *this ); \
00521 if ( 0 != m_updateCallback ) ( *m_updateCallback )( *this ); \
00522 return result; \
00523 } \
00524 \
00525 template<> \
00526 std::istream& \
00527 TYPENAME##ArrayPropertyRef::nameAndValueFromStream( std::istream& i ) \
00528 { \
00529 m_name.erase(); \
00530 m_value.clear(); \
00531 nameFromStream( i ); \
00532 return valueFromStream( i ); \
00533 } \
00534 \
00535 template<> \
00536 std::ostream& \
00537 TYPENAME##ArrayPropertyRef::valueElementAsStream( std::ostream& o, size_t ix ) const \
00538 { \
00539 QUOTESTYLE##ELEMENTOUTPUT \
00540 } \
00541 \
00542 template<> \
00543 std::istream& \
00544 TYPENAME##ArrayPropertyRef::valueElementFromStream( std::istream& i ) \
00545 { \
00546 BASETYPE temp; \
00547 QUOTESTYLE##ELEMENTINPUT \
00548 m_value.push_back( temp ); \
00549 return i; \
00550 } \
00551
00552
00553 ARRAYPROPERTYREFS(Boolean,bool,UNQUOTED)
00554 ARRAYPROPERTYREFS(Char,char,UNQUOTED)
00555 ARRAYPROPERTYREFS(SignedChar,signed char,UNQUOTED)
00556 ARRAYPROPERTYREFS(UnsignedChar,unsigned char,UNQUOTED)
00557 ARRAYPROPERTYREFS(Short,short,UNQUOTED)
00558 ARRAYPROPERTYREFS(UnsignedShort,unsigned short,UNQUOTED)
00559 ARRAYPROPERTYREFS(Integer,int,UNQUOTED)
00560 ARRAYPROPERTYREFS(UnsignedInteger,unsigned int,UNQUOTED)
00561 ARRAYPROPERTYREFS(Long,long,UNQUOTED)
00562 ARRAYPROPERTYREFS(UnsignedLong,unsigned long,UNQUOTED)
00563 ARRAYPROPERTYREFS(Float,float,UNQUOTED)
00564 ARRAYPROPERTYREFS(Double,double,UNQUOTED)
00565 ARRAYPROPERTYREFS(LongDouble,long double,UNQUOTED)
00566
00567 ARRAYPROPERTYREFS(String,std::string,QUOTED)
00568 #undef ARRAYPROPERTYREFS
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 static
00580 std::istream&
00581 valueFromStreamHelper( std::istream& i, Property& p )
00582 {
00583 char c;
00584
00585 i.ignore();
00586 i.get( c );
00587 while ( ']' != c && !i.fail() ) {
00588 i.putback( c );
00589 p.valueElementFromStream( i );
00590 i.get( c );
00591 if ( ',' == c ) {
00592 i.get( c );
00593 }
00594 }
00595 return i;
00596 };
00597
00598 static
00599 std::ostream&
00600 nameValueAsStreamHelper( std::ostream& o, const Property& p, size_t vSize )
00601 {
00602 if ( 0 == vSize ) {
00603 o << "\"" << p.name() << "\": []";
00604 }
00605 else {
00606 o << "\"" << p.name() << "\": [";
00607 for ( size_t ix = 0; ix < vSize; ++ix ) {
00608 p.valueElementAsStream( o, ix );
00609 o << ( ( vSize == ( ix+1 ) )
00610 ? "]"
00611 : ", " );
00612 }
00613 }
00614 return o;
00615 };
00616
00617
00618
00619
00620
00621
00622 #ifdef WIN32
00623
00624 #pragma warning ( disable : 4660 )
00625 #endif // WIN32
00626
00627 template class SimpleProperty< bool >;
00628 template class SimpleProperty< char >;
00629 template class SimpleProperty< signed char >;
00630 template class SimpleProperty< unsigned char >;
00631 template class SimpleProperty< short >;
00632 template class SimpleProperty< unsigned short >;
00633 template class SimpleProperty< int >;
00634 template class SimpleProperty< unsigned int >;
00635 template class SimpleProperty< long >;
00636 template class SimpleProperty< unsigned long >;
00637 template class SimpleProperty< float >;
00638 template class SimpleProperty< double >;
00639 template class SimpleProperty< long double >;
00640
00641 template class SimpleProperty< std::string >;
00642
00643 template class SimplePropertyRef< bool >;
00644 template class SimplePropertyRef< char >;
00645 template class SimplePropertyRef< signed char >;
00646 template class SimplePropertyRef< unsigned char >;
00647 template class SimplePropertyRef< short >;
00648 template class SimplePropertyRef< unsigned short >;
00649 template class SimplePropertyRef< int >;
00650 template class SimplePropertyRef< unsigned int >;
00651 template class SimplePropertyRef< long >;
00652 template class SimplePropertyRef< unsigned long >;
00653 template class SimplePropertyRef< float >;
00654 template class SimplePropertyRef< double >;
00655 template class SimplePropertyRef< long double >;
00656
00657 template class SimplePropertyRef< std::string >;
00658
00659 template class SimpleProperty< std::vector< bool > >;
00660 template class SimpleProperty< std::vector< char > >;
00661 template class SimpleProperty< std::vector< signed char > >;
00662 template class SimpleProperty< std::vector< unsigned char > >;
00663 template class SimpleProperty< std::vector< short > >;
00664 template class SimpleProperty< std::vector< unsigned short > >;
00665 template class SimpleProperty< std::vector< int > >;
00666 template class SimpleProperty< std::vector< unsigned int > >;
00667 template class SimpleProperty< std::vector< long > >;
00668 template class SimpleProperty< std::vector< unsigned long > >;
00669 template class SimpleProperty< std::vector< float > >;
00670 template class SimpleProperty< std::vector< double > >;
00671 template class SimpleProperty< std::vector< long double > >;
00672
00673 template class SimpleProperty< std::vector< std::string > >;
00674
00675 template class SimplePropertyRef< std::vector< bool > >;
00676 template class SimplePropertyRef< std::vector< char > >;
00677 template class SimplePropertyRef< std::vector< signed char > >;
00678 template class SimplePropertyRef< std::vector< unsigned char > >;
00679 template class SimplePropertyRef< std::vector< short > >;
00680 template class SimplePropertyRef< std::vector< unsigned short > >;
00681 template class SimplePropertyRef< std::vector< int > >;
00682 template class SimplePropertyRef< std::vector< unsigned int > >;
00683 template class SimplePropertyRef< std::vector< long > >;
00684 template class SimplePropertyRef< std::vector< unsigned long > >;
00685 template class SimplePropertyRef< std::vector< float > >;
00686 template class SimplePropertyRef< std::vector< double > >;
00687 template class SimplePropertyRef< std::vector< long double > >;
00688
00689 template class SimplePropertyRef< std::vector< std::string > >;
00690
00691 #ifdef WIN32
00692
00693 #pragma warning ( default : 4660 )
00694 #endif // WIN32
00695