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 }
KDE Home | KDE Accessibility Home | Description of Access Keys