filters

value.cpp
1/* Swinder - Portable library for spreadsheet
2 Copyright (C) 2003 Ariya Hidayat <ariya@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA
18*/
19
20#include "value.h"
21#include "ustring.h"
22
23#include <iostream>
24
25namespace Swinder
26{
27
28// helper class for Value
29class ValueData
30{
31 public:
32
33 Value::Type type;
34
35 // someday move to use union to reduce memory consumption
36 bool b;
37 int i;
38 double f;
39 UString s;
40
41 // create empty data
42 ValueData(){
43 count = 0;
44 b = false;
45 i = 0;
46 f = 0.0;
47 s = UString::null;
48 type = Value::Empty;
49 ref();
50 };
51
52 // destroys data
53 ~ValueData(){
54 if( this == s_null ) s_null = 0;
55 }
56
57 void ref(){ count++; }
58
59 // static empty data to be shared
60 static ValueData* null()
61 { if( !s_null) s_null = new ValueData; else s_null->ref(); return s_null; }
62
63 // decrease reference count
64 void unref()
65 { --count; if( !count ) delete this; }
66
67 // true if it's null (which is shared)
68 bool isNull(){ return this == s_null; }
69
70 unsigned count; // reference count
71
72 private:
73
74 static ValueData* s_null;
75
76};
77
78}
79
80using namespace Swinder;
81
82// to be shared between all empty value
83ValueData* ValueData::s_null = 0;
84
85// static things
86Value ks_value_empty;
87Value ks_error_div0;
88Value ks_error_na;
89Value ks_error_name;
90Value ks_error_null;
91Value ks_error_num;
92Value ks_error_ref;
93Value ks_error_value;
94
95// create an empty value
97{
98 d = ValueData::null();
99}
100
101// destructor
103{
104 d->unref();
105}
106
107// create value of certain type
108Value::Value( Value::Type _type )
109{
110 d = new ValueData;
111 d->type = _type;
112}
113
114// copy constructor
115Value::Value( const Value& _value )
116{
117 d = ValueData::null();
118 assign( _value );
119}
120
121// assignment operator
122Value& Value::operator=( const Value& _value )
123{
124 return assign( _value );
125}
126
127// create a boolean value
129{
130 d = ValueData::null();
131 setValue( b );
132}
133
134// create an integer value
136{
137 d = ValueData::null();
138 setValue ( i );
139}
140
141// create a floating-point value
142Value::Value( double f )
143{
144 d = ValueData::null();
145 setValue( f );
146}
147
148// create a string value
150{
151 d = ValueData::null();
152 setValue( s );
153}
154
155// assign value from other
156// shallow copy: only copy the data pointer
157Value& Value::assign( const Value& _value )
158{
159 d->unref();
160 d = _value.d;
161 d->ref();
162 return *this;
163}
164
165// return type of the value
166Value::Type Value::type() const
167{
168 return d ? d->type : Empty;
169}
170
171// set the value to boolean
172void Value::setValue( bool b )
173{
174 detach();
175 d->type = Boolean;
176 d->b = b;
177}
178
179// get the value as boolean
181{
182 bool result = false;
183
184 if( type() == Value::Boolean )
185 result = d->b;
186
187 return result;
188}
189
190// set the value to integer
191void Value::setValue( int i )
192{
193 detach();
194 d->type = Integer;
195 d->i = i;
196}
197
198// get the value as integer
200{
201 int result = 0;
202
203 if( type() == Value::Integer )
204 result = d->i;
205
206 if( type() == Value::Float )
207 result = static_cast<int>(d->f);
208
209 return result;
210}
211
212void Value::setValue( const Value& v )
213{
214 assign( v );
215}
216
217// set the value as floating-point
218void Value::setValue( double f )
219{
220 detach();
221 d->type = Float;
222 d->f = f;
223}
224
225// get the value as floating-point
226double Value::asFloat() const
227{
228 double result = 0.0;
229
230 if( type() == Value::Float )
231 result = d->f;
232
233 if( type() == Value::Integer )
234 result = static_cast<double>(d->i);
235
236 return result;
237}
238
239// set the value as string
240void Value::setValue( const UString& s )
241{
242 detach();
243 d->type = String;
244 d->s = s;
245}
246
247// get the value as string
249{
250 UString result;
251
252 if( type() == Value::String )
253 result = d->s;
254
255 return result;
256}
257
258// set error message
259void Value::setError( const UString& msg )
260{
261 detach();
262 d->type = Error;
263 d->s = msg;
264}
265
266// get error message
268{
269 UString result;
270
271 if( type() == Value::Error )
272 result = d->s;
273
274 return result;
275}
276
277// reference to empty value
279{
280 return ks_value_empty;
281}
282
283// reference to #DIV/0! error
285{
286 if( !ks_error_div0.isError() )
287 ks_error_div0.setError( UString("#DIV/0!") );
288 return ks_error_div0;
289}
290
291// reference to #N/A error
293{
294 if( !ks_error_na.isError() )
295 ks_error_na.setError( UString("#N/A") );
296 return ks_error_na;
297}
298
299// reference to #NAME? error
301{
302 if( !ks_error_name.isError() )
303 ks_error_name.setError( UString("#NAME?") );
304 return ks_error_name;
305}
306
307// reference to #NUM! error
309{
310 if( !ks_error_num.isError() )
311 ks_error_num.setError( UString("#NUM!") );
312 return ks_error_num;
313}
314
315// reference to #NULL! error
317{
318 if( !ks_error_null.isError() )
319 ks_error_null.setError( UString("#NULL!") );
320 return ks_error_null;
321}
322
323// reference to #REF! error
325{
326 if( !ks_error_ref.isError() )
327 ks_error_ref.setError( UString("#REF!") );
328 return ks_error_ref;
329}
330
331// reference to #VALUE! error
333{
334 if( !ks_error_value.isError() )
335 ks_error_value.setError( UString("#VALUE!") );
336 return ks_error_value;
337}
338
339// detach, create deep copy of ValueData
341{
342 if( d->isNull() || ( d->count > 1 ) )
343 {
344 ValueData* n;
345 n = new ValueData;
346
347 n->type = d->type;
348 switch( n->type )
349 {
350 case Empty: break;
351 case Boolean: n->b = d->b; break;
352 case Integer: n->i = d->i; break;
353 case Float: n->f = d->f; break;
354 case String: n->s = d->s; break;
355 case Error: n->s = d->s; break;
356 default: break;
357 }
358
359 d->unref();
360 d = n;
361 }
362}
363
364std::ostream& Swinder::operator<<( std::ostream& s, Swinder::Value value )
365{
366 switch( value.type() )
367 {
368 case Value::Empty:
369 s << "Empty";
370 break;
371 case Value::Boolean:
372 s << "Boolean: " << (value.asBoolean()?"True":"False");
373 break;
374 case Value::Integer:
375 s << "Integer: " << value.asInteger();
376 break;
377 case Value::Float:
378 s << "Float: " << value.asFloat();
379 break;
380 case Value::String:
381 s << "String: " << value.asString().ascii();
382 break;
383 case Value::Error:
384 s << "Error: " << value.errorMessage().ascii();
385 break;
386 default:
387 break;
388 };
389
390 return s;
391}
char * ascii() const
Convert the Unicode string to plain ASCII chars chopping of any higher bytes.
static UString null
Static instance of a null string.
Provides a wrapper for cell value.
Definition value.h:43
UString errorMessage() const
Returns error message associated with this value.
Definition value.cpp:267
static const Value & empty()
Returns constant reference to empty value.
Definition value.cpp:278
static const Value & errorDIV0()
Returns constant reference to DIV/0!
Definition value.cpp:284
static const Value & errorNULL()
Returns constant reference to NULL!
Definition value.cpp:316
virtual ~Value()
Destroys the value.
Definition value.cpp:102
void setError(const UString &msg)
Sets this value to hold error message.
Definition value.cpp:259
static const Value & errorNAME()
Returns constant reference to NAME?
Definition value.cpp:300
Value & assign(const Value &_value)
Assigns from another value.
Definition value.cpp:157
static const Value & errorNUM()
Returns constant reference to NUM!
Definition value.cpp:308
Type type() const
Returns the type of the value.
Definition value.cpp:166
static const Value & errorREF()
Returns constant reference to REF!
Definition value.cpp:324
double asFloat() const
Returns the floating-point value of this value.
Definition value.cpp:226
Value & operator=(const Value &_value)
Assigns from another value.
Definition value.cpp:122
UString asString() const
Returns the string value of this value.
Definition value.cpp:248
Value()
Creates an empty value, i.e holds nothing.
Definition value.cpp:96
static const Value & errorVALUE()
Returns constant reference to VALUE!
Definition value.cpp:332
void detach()
Detaches itself from shared value data, i.e make a private, deep copy of the data.
Definition value.cpp:340
bool asBoolean() const
Returns the boolean value of this value.
Definition value.cpp:180
static const Value & errorNA()
Returns constant reference to N/A error.
Definition value.cpp:292
int asInteger() const
Returns the integer value of this value.
Definition value.cpp:199