00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef EXCEPTIONIMPL_H
00020 #define EXCEPTIONIMPL_H
00021
00022
00023
00024
00025 #include "smbios/compat.h"
00026
00027 #include <map>
00028 #include <string>
00029 #include <sstream>
00030 #include <exception>
00031
00032
00033 #include "smbios/types.h"
00034 #include "smbios/IException.h"
00035
00036
00037 #include "smbios/config/abi_prefix.hpp"
00038
00039 #define DEFINE_EXCEPTION_EX( excName, ns, superclass ) \
00040 class excName : public smbios::Exception< ns :: superclass > \
00041 { \
00042 public: \
00043 ~excName() throw() {}; \
00044 excName( const std::string initMessage ) : smbios::Exception< ns :: superclass >(initMessage) {} ;\
00045 excName( const excName &src ) : smbios::Exception< ns :: superclass >(src) {} ;\
00046 excName( ) : smbios::Exception< ns :: superclass >() {} ;\
00047 }
00048
00049
00050
00051
00052 namespace smbios
00053 {
00054
00055 template <class S>
00056 class Exception : public S
00057 {
00058 public:
00059
00060 virtual ~Exception() throw() { deAllocateMaps(); };
00061
00062 Exception( const std::string initMessage ) : S(), messageStr( initMessage ), outputStr("") { allocateMaps(); };
00063 Exception( ) : S(), messageStr( "" ), outputStr("") { allocateMaps(); };
00064 Exception( const Exception<S> &source );
00065
00066 Exception<S> &operator =( const Exception<S> &source );
00067
00068 virtual const char *what() const throw() ;
00069 virtual std::string getParameterString( const std::string &name ) const;
00070 virtual u32 getParameterNumber( const std::string &name ) const;
00071
00072 virtual void setMessageString( const std::string &newMsgString );
00073 virtual void setParameter( const std::string &name, const std::string &value );
00074 virtual void setParameter( const std::string &name, const u32 value );
00075 private:
00076 void allocateMaps();
00077 void deAllocateMaps();
00078 std::string messageStr;
00079 mutable std::string outputStr;
00080
00081
00082
00083 void * ptrStrMap;
00084 void * ptrNumMap;
00085
00086 };
00087
00088
00089 template <class S>
00090 Exception<S>::Exception( const Exception<S> &source )
00091 : S(), messageStr( source.messageStr ), outputStr("")
00092 {
00093 allocateMaps();
00094
00095
00096 std::map< std::string, std::string > r_ptrStrMap =
00097 *reinterpret_cast< std::map< std::string, std::string > * >(ptrStrMap);
00098
00099 std::map< std::string, u32 > r_ptrNumMap =
00100 *reinterpret_cast< std::map< std::string, u32 > * >(ptrNumMap);
00101
00102 std::map< std::string, std::string > r_ptrStrMapSource =
00103 *reinterpret_cast< std::map< std::string, std::string > * >(source.ptrStrMap);
00104
00105 std::map< std::string, u32 > r_ptrNumMapSource =
00106 *reinterpret_cast< std::map< std::string, u32 > * >(source.ptrNumMap);
00107
00108
00109 std::map< std::string, u32 >::iterator iter = r_ptrNumMapSource.begin();
00110 while ( iter != r_ptrNumMapSource.end() )
00111 {
00112 setParameter( iter->first, iter->second );
00113 ++iter;
00114 }
00115
00116 std::map< std::string, std::string >::iterator iterStr = r_ptrStrMapSource.begin();
00117 while ( iterStr != r_ptrStrMapSource.end() )
00118 {
00119 setParameter( iterStr->first, iterStr->second );
00120 ++iterStr;
00121 }
00122 }
00123
00124
00125 template <class S>
00126 Exception<S> &Exception<S>::operator =( const Exception<S> &source )
00127 {
00128 messageStr = source.messageStr;
00129 outputStr = "";
00130
00131 deAllocateMaps();
00132 allocateMaps();
00133
00134
00135 std::map< std::string, std::string > r_ptrStrMap =
00136 *reinterpret_cast< std::map< std::string, std::string > * >(ptrStrMap);
00137
00138 std::map< std::string, u32 > r_ptrNumMap =
00139 *reinterpret_cast< std::map< std::string, u32 > * >(ptrNumMap);
00140
00141 std::map< std::string, std::string > r_ptrStrMapSource =
00142 *reinterpret_cast< std::map< std::string, std::string > * >(source.ptrStrMap);
00143
00144 std::map< std::string, u32 > r_ptrNumMapSource =
00145 *reinterpret_cast< std::map< std::string, u32 > * >(source.ptrNumMap);
00146
00147
00148 std::map< std::string, u32 >::iterator iter = r_ptrNumMapSource.begin();
00149 while ( iter != r_ptrNumMapSource.end() )
00150 {
00151 setParameter( iter->first, iter->second );
00152 ++iter;
00153 }
00154
00155 std::map< std::string, std::string >::iterator iterStr = r_ptrStrMapSource.begin();
00156 while ( iterStr != r_ptrStrMapSource.end() )
00157 {
00158 setParameter( iterStr->first, iterStr->second );
00159 ++iterStr;
00160 }
00161
00162 return *this;
00163 }
00164
00165 template <class S>
00166 void Exception<S>::allocateMaps()
00167 {
00168
00169 try
00170 {
00171 std::map< std::string, std::string > *r_ptrStrMap =
00172 new std::map< std::string, std::string >;
00173
00174 ptrStrMap = reinterpret_cast<void*>(r_ptrStrMap);
00175
00176 std::map< std::string, u32 > *r_ptrNumMap =
00177 new std::map< std::string, u32 >;
00178
00179 ptrNumMap = reinterpret_cast<void*>(r_ptrNumMap);
00180 }
00181 catch( const std::exception & )
00182 {
00183
00184 deAllocateMaps();
00185 throw;
00186 }
00187 }
00188
00189 template <class S>
00190 void Exception<S>::deAllocateMaps()
00191 {
00192 if( ptrStrMap )
00193 {
00194 std::map< std::string, std::string > *r_ptrStrMap =
00195 reinterpret_cast< std::map< std::string, std::string > * >(ptrStrMap);
00196 delete r_ptrStrMap;
00197 }
00198 ptrStrMap = 0;
00199
00200 if( ptrNumMap )
00201 {
00202 std::map< std::string, u32 > *r_ptrNumMap =
00203 reinterpret_cast< std::map< std::string, u32 > * >(ptrNumMap);
00204 delete r_ptrNumMap;
00205 }
00206 ptrNumMap = 0;
00207 }
00208
00209
00210
00211
00212
00213
00214 template <class S>
00215 const char * Exception<S>::what() const throw()
00216 {
00217 outputStr = messageStr;
00218
00219 size_t strLen = outputStr.length();
00220 size_t pos = 0;
00221 while(pos < strLen)
00222 {
00223 std::string varName = "";
00224 size_t replaceLen = 0;
00225 char varType;
00226 size_t endVar = 0;
00227 std::ostringstream rep;
00228
00229 pos = outputStr.find( "%", pos );
00230 if( pos >= strLen )
00231 break;
00232
00233
00234 if( pos == strLen-1 )
00235 break;
00236
00237
00238 if( outputStr[pos+1] == '%' )
00239 {
00240 outputStr.replace(pos, 2, "%");
00241 goto next_pos;
00242 }
00243
00244 if( outputStr[pos+1] != '(' )
00245 {
00246
00247
00248 goto next_pos;
00249 }
00250
00251 endVar = outputStr.find( ")", pos );
00252 if( endVar >= strLen )
00253 {
00254
00255 goto next_pos;
00256 }
00257
00258
00259 if( endVar == strLen-1 )
00260 break;
00261
00262 varType = outputStr[endVar + 1];
00263
00264 replaceLen = endVar - pos + 2;
00265 varName = outputStr.substr( pos+2, replaceLen - 4 );
00266
00267
00268 if( replaceLen > 32 )
00269 goto next_pos;
00270
00271 switch( varType )
00272 {
00273 case 'i':
00274 rep << getParameterNumber(varName);
00275 outputStr.replace( pos, replaceLen, rep.str() );
00276 goto loop_end;
00277 case 's':
00278 outputStr.replace( pos, replaceLen, getParameterString(varName));
00279 goto loop_end;
00280 }
00281
00282 next_pos:
00283 ++pos;
00284
00285 loop_end:
00286 strLen = outputStr.length();
00287 }
00288
00289 return outputStr.c_str();
00290 }
00291
00292 template <class S>
00293 void Exception<S>::setMessageString( const std::string &newStr )
00294 {
00295 messageStr = newStr;
00296 }
00297
00298
00299 template <class S>
00300 void Exception<S>::setParameter( const std::string &name, const std::string &value)
00301 {
00302 std::map< std::string, std::string > *r_ptrStrMap =
00303 reinterpret_cast< std::map< std::string, std::string > * >(ptrStrMap);
00304
00305 (*r_ptrStrMap)[ name ] = value;
00306 }
00307
00308 template <class S>
00309 void Exception<S>::setParameter( const std::string &name, const u32 value)
00310 {
00311 std::map< std::string, u32 > *r_ptrNumMap =
00312 reinterpret_cast< std::map< std::string, u32 > * >(ptrNumMap);
00313
00314 (*r_ptrNumMap)[ name ] = value;
00315 }
00316
00317
00318 template <class S>
00319 u32 Exception<S>::getParameterNumber( const std::string &name ) const
00320 {
00321 std::map< std::string, u32 > r_ptrNumMap =
00322 *reinterpret_cast< std::map< std::string, u32 > * >(ptrNumMap);
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 return r_ptrNumMap[ name ];
00333 }
00334
00335 template <class S>
00336 std::string Exception<S>::getParameterString( const std::string &name ) const
00337 {
00338 std::map< std::string, std::string > r_ptrStrMap =
00339 *reinterpret_cast< std::map< std::string, std::string > * >(ptrStrMap);
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 return r_ptrStrMap[ name ];
00350 }
00351
00352
00353
00354
00355
00360 DEFINE_EXCEPTION_EX( NotImplementedImpl, smbios, NotImplemented );
00361
00366 DEFINE_EXCEPTION_EX( InternalErrorImpl, smbios, InternalError );
00367
00369 DEFINE_EXCEPTION_EX( PermissionExceptionImpl, smbios, PermissionException );
00370 }
00371
00372
00373 #include "smbios/config/abi_suffix.hpp"
00374
00375 #endif