filters
value.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "value.h"
00021 #include "ustring.h"
00022
00023 #include <iostream>
00024
00025 namespace Swinder
00026 {
00027
00028
00029 class ValueData
00030 {
00031 public:
00032
00033 Value::Type type;
00034
00035
00036 bool b;
00037 int i;
00038 double f;
00039 UString s;
00040
00041
00042 ValueData(){
00043 count = 0;
00044 b = false;
00045 i = 0;
00046 f = 0.0;
00047 s = UString::null;
00048 type = Value::Empty;
00049 ref();
00050 };
00051
00052
00053 ~ValueData(){
00054 if( this == s_null ) s_null = 0;
00055 }
00056
00057 void ref(){ count++; }
00058
00059
00060 static ValueData* null()
00061 { if( !s_null) s_null = new ValueData; else s_null->ref(); return s_null; }
00062
00063
00064 void unref()
00065 { --count; if( !count ) delete this; }
00066
00067
00068 bool isNull(){ return this == s_null; }
00069
00070 unsigned count;
00071
00072 private:
00073
00074 static ValueData* s_null;
00075
00076 };
00077
00078 }
00079
00080 using namespace Swinder;
00081
00082
00083 ValueData* ValueData::s_null = 0;
00084
00085
00086 Value ks_value_empty;
00087 Value ks_error_div0;
00088 Value ks_error_na;
00089 Value ks_error_name;
00090 Value ks_error_null;
00091 Value ks_error_num;
00092 Value ks_error_ref;
00093 Value ks_error_value;
00094
00095
00096 Value::Value()
00097 {
00098 d = ValueData::null();
00099 }
00100
00101
00102 Value::~Value()
00103 {
00104 d->unref();
00105 }
00106
00107
00108 Value::Value( Value::Type _type )
00109 {
00110 d = new ValueData;
00111 d->type = _type;
00112 }
00113
00114
00115 Value::Value( const Value& _value )
00116 {
00117 d = ValueData::null();
00118 assign( _value );
00119 }
00120
00121
00122 Value& Value::operator=( const Value& _value )
00123 {
00124 return assign( _value );
00125 }
00126
00127
00128 Value::Value( bool b )
00129 {
00130 d = ValueData::null();
00131 setValue( b );
00132 }
00133
00134
00135 Value::Value( int i )
00136 {
00137 d = ValueData::null();
00138 setValue ( i );
00139 }
00140
00141
00142 Value::Value( double f )
00143 {
00144 d = ValueData::null();
00145 setValue( f );
00146 }
00147
00148
00149 Value::Value( const UString& s )
00150 {
00151 d = ValueData::null();
00152 setValue( s );
00153 }
00154
00155
00156
00157 Value& Value::assign( const Value& _value )
00158 {
00159 d->unref();
00160 d = _value.d;
00161 d->ref();
00162 return *this;
00163 }
00164
00165
00166 Value::Type Value::type() const
00167 {
00168 return d ? d->type : Empty;
00169 }
00170
00171
00172 void Value::setValue( bool b )
00173 {
00174 detach();
00175 d->type = Boolean;
00176 d->b = b;
00177 }
00178
00179
00180 bool Value::asBoolean() const
00181 {
00182 bool result = false;
00183
00184 if( type() == Value::Boolean )
00185 result = d->b;
00186
00187 return result;
00188 }
00189
00190
00191 void Value::setValue( int i )
00192 {
00193 detach();
00194 d->type = Integer;
00195 d->i = i;
00196 }
00197
00198
00199 int Value::asInteger() const
00200 {
00201 int result = 0;
00202
00203 if( type() == Value::Integer )
00204 result = d->i;
00205
00206 if( type() == Value::Float )
00207 result = static_cast<int>(d->f);
00208
00209 return result;
00210 }
00211
00212 void Value::setValue( const Value& v )
00213 {
00214 assign( v );
00215 }
00216
00217
00218 void Value::setValue( double f )
00219 {
00220 detach();
00221 d->type = Float;
00222 d->f = f;
00223 }
00224
00225
00226 double Value::asFloat() const
00227 {
00228 double result = 0.0;
00229
00230 if( type() == Value::Float )
00231 result = d->f;
00232
00233 if( type() == Value::Integer )
00234 result = static_cast<double>(d->i);
00235
00236 return result;
00237 }
00238
00239
00240 void Value::setValue( const UString& s )
00241 {
00242 detach();
00243 d->type = String;
00244 d->s = s;
00245 }
00246
00247
00248 UString Value::asString() const
00249 {
00250 UString result;
00251
00252 if( type() == Value::String )
00253 result = d->s;
00254
00255 return result;
00256 }
00257
00258
00259 void Value::setError( const UString& msg )
00260 {
00261 detach();
00262 d->type = Error;
00263 d->s = msg;
00264 }
00265
00266
00267 UString Value::errorMessage() const
00268 {
00269 UString result;
00270
00271 if( type() == Value::Error )
00272 result = d->s;
00273
00274 return result;
00275 }
00276
00277
00278 const Value& Value::empty()
00279 {
00280 return ks_value_empty;
00281 }
00282
00283
00284 const Value& Value::errorDIV0()
00285 {
00286 if( !ks_error_div0.isError() )
00287 ks_error_div0.setError( UString("#DIV/0!") );
00288 return ks_error_div0;
00289 }
00290
00291
00292 const Value& Value::errorNA()
00293 {
00294 if( !ks_error_na.isError() )
00295 ks_error_na.setError( UString("#N/A") );
00296 return ks_error_na;
00297 }
00298
00299
00300 const Value& Value::errorNAME()
00301 {
00302 if( !ks_error_name.isError() )
00303 ks_error_name.setError( UString("#NAME?") );
00304 return ks_error_name;
00305 }
00306
00307
00308 const Value& Value::errorNUM()
00309 {
00310 if( !ks_error_num.isError() )
00311 ks_error_num.setError( UString("#NUM!") );
00312 return ks_error_num;
00313 }
00314
00315
00316 const Value& Value::errorNULL()
00317 {
00318 if( !ks_error_null.isError() )
00319 ks_error_null.setError( UString("#NULL!") );
00320 return ks_error_null;
00321 }
00322
00323
00324 const Value& Value::errorREF()
00325 {
00326 if( !ks_error_ref.isError() )
00327 ks_error_ref.setError( UString("#REF!") );
00328 return ks_error_ref;
00329 }
00330
00331
00332 const Value& Value::errorVALUE()
00333 {
00334 if( !ks_error_value.isError() )
00335 ks_error_value.setError( UString("#VALUE!") );
00336 return ks_error_value;
00337 }
00338
00339
00340 void Value::detach()
00341 {
00342 if( d->isNull() || ( d->count > 1 ) )
00343 {
00344 ValueData* n;
00345 n = new ValueData;
00346
00347 n->type = d->type;
00348 switch( n->type )
00349 {
00350 case Empty: break;
00351 case Boolean: n->b = d->b; break;
00352 case Integer: n->i = d->i; break;
00353 case Float: n->f = d->f; break;
00354 case String: n->s = d->s; break;
00355 case Error: n->s = d->s; break;
00356 default: break;
00357 }
00358
00359 d->unref();
00360 d = n;
00361 }
00362 }
00363
00364 std::ostream& Swinder::operator<<( std::ostream& s, Swinder::Value value )
00365 {
00366 switch( value.type() )
00367 {
00368 case Value::Empty:
00369 s << "Empty";
00370 break;
00371 case Value::Boolean:
00372 s << "Boolean: " << (value.asBoolean()?"True":"False");
00373 break;
00374 case Value::Integer:
00375 s << "Integer: " << value.asInteger();
00376 break;
00377 case Value::Float:
00378 s << "Float: " << value.asFloat();
00379 break;
00380 case Value::String:
00381 s << "String: " << value.asString().ascii();
00382 break;
00383 case Value::Error:
00384 s << "Error: " << value.errorMessage().ascii();
00385 break;
00386 default:
00387 break;
00388 };
00389
00390 return s;
00391 }
|