filters
value.cpp
00001 /* Swinder - Portable library for spreadsheet 00002 Copyright (C) 2003 Ariya Hidayat <ariya@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 * Boston, MA 02110-1301, USA 00018 */ 00019 00020 #include "value.h" 00021 #include "ustring.h" 00022 00023 #include <iostream> 00024 00025 namespace Swinder 00026 { 00027 00028 // helper class for Value 00029 class ValueData 00030 { 00031 public: 00032 00033 Value::Type type; 00034 00035 // someday move to use union to reduce memory consumption 00036 bool b; 00037 int i; 00038 double f; 00039 UString s; 00040 00041 // create empty data 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 // destroys data 00053 ~ValueData(){ 00054 if( this == s_null ) s_null = 0; 00055 } 00056 00057 void ref(){ count++; } 00058 00059 // static empty data to be shared 00060 static ValueData* null() 00061 { if( !s_null) s_null = new ValueData; else s_null->ref(); return s_null; } 00062 00063 // decrease reference count 00064 void unref() 00065 { --count; if( !count ) delete this; } 00066 00067 // true if it's null (which is shared) 00068 bool isNull(){ return this == s_null; } 00069 00070 unsigned count; // reference count 00071 00072 private: 00073 00074 static ValueData* s_null; 00075 00076 }; 00077 00078 } 00079 00080 using namespace Swinder; 00081 00082 // to be shared between all empty value 00083 ValueData* ValueData::s_null = 0; 00084 00085 // static things 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 // create an empty value 00096 Value::Value() 00097 { 00098 d = ValueData::null(); 00099 } 00100 00101 // destructor 00102 Value::~Value() 00103 { 00104 d->unref(); 00105 } 00106 00107 // create value of certain type 00108 Value::Value( Value::Type _type ) 00109 { 00110 d = new ValueData; 00111 d->type = _type; 00112 } 00113 00114 // copy constructor 00115 Value::Value( const Value& _value ) 00116 { 00117 d = ValueData::null(); 00118 assign( _value ); 00119 } 00120 00121 // assignment operator 00122 Value& Value::operator=( const Value& _value ) 00123 { 00124 return assign( _value ); 00125 } 00126 00127 // create a boolean value 00128 Value::Value( bool b ) 00129 { 00130 d = ValueData::null(); 00131 setValue( b ); 00132 } 00133 00134 // create an integer value 00135 Value::Value( int i ) 00136 { 00137 d = ValueData::null(); 00138 setValue ( i ); 00139 } 00140 00141 // create a floating-point value 00142 Value::Value( double f ) 00143 { 00144 d = ValueData::null(); 00145 setValue( f ); 00146 } 00147 00148 // create a string value 00149 Value::Value( const UString& s ) 00150 { 00151 d = ValueData::null(); 00152 setValue( s ); 00153 } 00154 00155 // assign value from other 00156 // shallow copy: only copy the data pointer 00157 Value& Value::assign( const Value& _value ) 00158 { 00159 d->unref(); 00160 d = _value.d; 00161 d->ref(); 00162 return *this; 00163 } 00164 00165 // return type of the value 00166 Value::Type Value::type() const 00167 { 00168 return d ? d->type : Empty; 00169 } 00170 00171 // set the value to boolean 00172 void Value::setValue( bool b ) 00173 { 00174 detach(); 00175 d->type = Boolean; 00176 d->b = b; 00177 } 00178 00179 // get the value as boolean 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 // set the value to integer 00191 void Value::setValue( int i ) 00192 { 00193 detach(); 00194 d->type = Integer; 00195 d->i = i; 00196 } 00197 00198 // get the value as integer 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 // set the value as floating-point 00218 void Value::setValue( double f ) 00219 { 00220 detach(); 00221 d->type = Float; 00222 d->f = f; 00223 } 00224 00225 // get the value as floating-point 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 // set the value as string 00240 void Value::setValue( const UString& s ) 00241 { 00242 detach(); 00243 d->type = String; 00244 d->s = s; 00245 } 00246 00247 // get the value as string 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 // set error message 00259 void Value::setError( const UString& msg ) 00260 { 00261 detach(); 00262 d->type = Error; 00263 d->s = msg; 00264 } 00265 00266 // get error message 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 // reference to empty value 00278 const Value& Value::empty() 00279 { 00280 return ks_value_empty; 00281 } 00282 00283 // reference to #DIV/0! error 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 // reference to #N/A error 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 // reference to #NAME? error 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 // reference to #NUM! error 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 // reference to #NULL! error 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 // reference to #REF! error 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 // reference to #VALUE! error 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 // detach, create deep copy of ValueData 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 }

