KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

971 lines
21KB

  1. /* This file is part of the KDE project
  2. Copyright (C) 2003,2004 Ariya Hidayat <ariya@kde.org>
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public
  5. License as published by the Free Software Foundation; either
  6. version 2 of the License.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public License
  12. along with this library; see the file COPYING.LIB. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  14. * Boston, MA 02110-1301, USA.
  15. */
  16. #include "kspread_value.h"
  17. #include <kdebug.h>
  18. #include <tqstring.h>
  19. #include <tqtextstream.h>
  20. #include <float.h>
  21. #include <math.h>
  22. #include <limits.h>
  23. using namespace KSpread;
  24. // helper struct for array implementation
  25. // this struct holds one piece of an array of size CHUNK_COLS x CHUNK_ROWS
  26. // or less
  27. struct arrayChunk {
  28. arrayChunk (int c, int r) {
  29. cols = c; rows = r;
  30. ptr = new Value* [c*r];
  31. for (int i = 0; i < c*r; ++i) ptr[i] = 0;
  32. }
  33. ~arrayChunk () {
  34. if (!ptr) return;
  35. unsigned count = cols * rows;
  36. for (unsigned i = 0; i < count; i++)
  37. delete ptr[i];
  38. delete [] ptr;
  39. }
  40. arrayChunk( const arrayChunk& ac )
  41. {
  42. operator=( ac );
  43. }
  44. arrayChunk& operator= ( const arrayChunk& ac )
  45. {
  46. cols = ac.cols; rows = ac.rows;
  47. ptr = new Value* [cols*rows];
  48. unsigned count = cols * rows;
  49. for( unsigned i = 0; i < count; i++ )
  50. if( ac.ptr[i] )
  51. ptr[i] = new Value( *ac.ptr[i] );
  52. else
  53. ptr[i] = 0;
  54. return *this;
  55. }
  56. Value **ptr;
  57. unsigned cols, rows;
  58. };
  59. #define CHUNK_COLS 128
  60. #define CHUNK_ROWS 128
  61. // helper class for array implementation
  62. class ValueArray
  63. {
  64. public:
  65. arrayChunk **chunks;
  66. unsigned columns;
  67. unsigned rows;
  68. unsigned chunkCols, chunkRows;
  69. ValueArray(): chunks(0), columns(0), rows(0), chunkCols(0), chunkRows(0) {};
  70. ~ValueArray()
  71. {
  72. clear();
  73. };
  74. ValueArray( const ValueArray& va )
  75. : chunks(0), columns(0), rows(0), chunkCols(0), chunkRows(0)
  76. {
  77. operator=( va );
  78. }
  79. ValueArray& operator= ( const ValueArray& va )
  80. {
  81. init( va.columns, va.rows );
  82. unsigned count = chunkCols * chunkRows;
  83. for( unsigned i = 0; i < count; i++ )
  84. if( va.chunks[i] )
  85. chunks[i] = new arrayChunk (*va.chunks[i]);
  86. else
  87. chunks[i] = 0;
  88. return *this;
  89. }
  90. void clear()
  91. {
  92. int c = columns / CHUNK_COLS;
  93. int r = rows / CHUNK_ROWS;
  94. if (columns % CHUNK_COLS != 0) c++;
  95. if (rows % CHUNK_ROWS != 0) r++;
  96. if( !chunks ) return;
  97. unsigned count = c*r;
  98. if( !count ) return;
  99. for (unsigned i = 0; i < count; i++)
  100. delete chunks[i];
  101. delete [] chunks;
  102. chunks = 0;
  103. columns = rows = chunkCols = chunkRows = 0;
  104. }
  105. void init( unsigned c, unsigned r )
  106. {
  107. if (chunks) clear();
  108. columns = c; rows = r;
  109. int cc = columns / CHUNK_COLS;
  110. int rr = rows / CHUNK_ROWS;
  111. if (columns % CHUNK_COLS != 0) cc++;
  112. if (rows % CHUNK_ROWS != 0) rr++;
  113. chunkCols = cc;
  114. chunkRows = rr;
  115. unsigned count = cc*rr;
  116. chunks = new arrayChunk* [count];
  117. for( unsigned i = 0; i < count; i++ )
  118. chunks[i] = 0;
  119. }
  120. Value* at( unsigned c, unsigned r ) const
  121. {
  122. if( !chunks ) return 0;
  123. if( c >= columns ) return 0;
  124. if( r >= rows ) return 0;
  125. int col = c / CHUNK_COLS;
  126. int row = r / CHUNK_ROWS;
  127. int cpos = c % CHUNK_COLS;
  128. int rpos = r % CHUNK_ROWS;
  129. arrayChunk *chunk = chunks[row * chunkCols + col];
  130. if (!chunk) return 0;
  131. return chunk->ptr[rpos * chunk->cols + cpos];
  132. };
  133. void set( unsigned c, unsigned r, Value* v )
  134. {
  135. if (!chunks) return;
  136. if( c >= columns ) return;
  137. if( r >= rows ) return;
  138. unsigned col = c / CHUNK_COLS;
  139. unsigned row = r / CHUNK_ROWS;
  140. unsigned cpos = c % CHUNK_COLS;
  141. unsigned rpos = r % CHUNK_ROWS;
  142. arrayChunk *chunk = chunks[row * chunkCols + col];
  143. if (!chunk) {
  144. unsigned cc = (col==chunkCols-1) ? (columns % CHUNK_COLS) : CHUNK_COLS;
  145. unsigned rr = (row==chunkRows-1) ? (rows % CHUNK_ROWS) : CHUNK_ROWS;
  146. chunk = new arrayChunk (cc, rr);
  147. chunks[row * chunkCols + col] = chunk;
  148. }
  149. delete chunk->ptr[rpos * chunk->cols + cpos];
  150. chunk->ptr[rpos * chunk->cols + cpos] = v;
  151. }
  152. bool operator==( const ValueArray& other ) const
  153. {
  154. if ( columns != other.columns || rows != other.rows )
  155. return false;
  156. for ( unsigned r = 0; r < rows; ++r )
  157. for ( unsigned c = 0; c < columns; ++c ) {
  158. Value* v1 = at( c, r );
  159. Value* v2 = other.at( c, r );
  160. if ( ( v1 && !v2 ) || ( !v1 && v2 ) )
  161. return false;
  162. if ( !( v1 && v2 && *v1 == *v2 ) )
  163. return false;
  164. }
  165. return true;
  166. }
  167. };
  168. // helper class for Value
  169. class KSpread::ValueData
  170. {
  171. public:
  172. Value::Type type:4;
  173. Value::Format format:4;
  174. // reference count, at least one when object exists
  175. unsigned int count:24;
  176. union
  177. {
  178. bool b;
  179. long i;
  180. double f;
  181. TQString* ps;
  182. ValueArray* pa;
  183. };
  184. // create empty data
  185. ValueData(): type( Value::Empty ),
  186. format (Value::fmt_None), count( 1 ), ps( 0 ) { };
  187. // destroys data
  188. ~ValueData(){ if( this == s_null ) s_null = 0;
  189. if( type == Value::Array ) delete pa;
  190. if( type == Value::String ) delete ps;
  191. if( type == Value::Error ) delete ps;
  192. }
  193. // static empty data to be shared
  194. static ValueData* null()
  195. { if( !s_null) s_null = new ValueData; else s_null->ref(); return s_null; }
  196. // increase reference count
  197. void ref() { count++; }
  198. // decrease reference count
  199. void unref()
  200. { --count; if( !count ) delete this; }
  201. // true if it's null (which is shared)
  202. bool isNull(){ return this == s_null; }
  203. /** set most probable formatting based on the type */
  204. void setFormatByType ();
  205. private:
  206. static ValueData* s_null;
  207. };
  208. void KSpread::ValueData::setFormatByType ()
  209. {
  210. switch (type) {
  211. case Value::Empty:
  212. format = Value::fmt_None;
  213. break;
  214. case Value::Boolean:
  215. format = Value::fmt_Boolean;
  216. break;
  217. case Value::Integer:
  218. format = Value::fmt_Number;
  219. break;
  220. case Value::Float:
  221. format = Value::fmt_Number;
  222. break;
  223. case Value::String:
  224. format = Value::fmt_String;
  225. break;
  226. case Value::Array:
  227. format = Value::fmt_None;
  228. break;
  229. case Value::CellRange:
  230. format = Value::fmt_None;
  231. break;
  232. case Value::Error:
  233. format = Value::fmt_String;
  234. break;
  235. };
  236. }
  237. // to be shared between all empty value
  238. ValueData* ValueData::s_null = 0;
  239. // static things
  240. Value ks_value_empty;
  241. Value ks_error_div0;
  242. Value ks_error_na;
  243. Value ks_error_name;
  244. Value ks_error_null;
  245. Value ks_error_num;
  246. Value ks_error_ref;
  247. Value ks_error_value;
  248. // create an empty value
  249. Value::Value()
  250. {
  251. d = ValueData::null();
  252. }
  253. // destructor
  254. Value::~Value()
  255. {
  256. d->unref();
  257. }
  258. // create value of certain type
  259. Value::Value( Value::Type _type )
  260. {
  261. d = new ValueData;
  262. d->type = _type;
  263. d->setFormatByType ();
  264. }
  265. // copy constructor
  266. Value::Value( const Value& _value )
  267. {
  268. d = ValueData::null();
  269. assign( _value );
  270. }
  271. // assignment operator
  272. Value& Value::operator=( const Value& _value )
  273. {
  274. return assign( _value );
  275. }
  276. // comparison operator - returns true only if strictly identical, unlike equal()/compare()
  277. bool Value::operator==( const Value& v ) const
  278. {
  279. const ValueData* n = v.d;
  280. if ( (uint)d->type != n->type )
  281. return false;
  282. switch( d->type )
  283. {
  284. case Empty: return true;
  285. case Boolean: return n->b == d->b;
  286. case Integer: return n->i == d->i;
  287. case Float: return compare( n->f, d->f ) == 0;
  288. case String: return *n->ps == *d->ps;
  289. case Array: return *n->pa == *d->pa;
  290. case Error: return *n->ps == *d->ps;
  291. default: break;
  292. }
  293. kdWarning() << "Unhandled type in Value::operator==: " << d->type << endl;
  294. return false;
  295. }
  296. // create a boolean value
  297. Value::Value( bool b )
  298. {
  299. d = ValueData::null();
  300. setValue( b );
  301. }
  302. // create an integer value
  303. Value::Value( long i )
  304. {
  305. d = ValueData::null();
  306. setValue ( i );
  307. }
  308. // create an integer value
  309. Value::Value( int i )
  310. {
  311. d = ValueData::null();
  312. setValue ( i );
  313. }
  314. // create a floating-point value
  315. Value::Value( double f )
  316. {
  317. d = ValueData::null();
  318. setValue( f );
  319. }
  320. // create a string value
  321. Value::Value( const TQString& s )
  322. {
  323. d = ValueData::null();
  324. setValue( s );
  325. }
  326. // create a string value
  327. Value::Value (const char *s)
  328. {
  329. d = ValueData::null();
  330. setValue (TQString (s));
  331. }
  332. // create a floating-point value from date/time
  333. Value::Value( const TQDateTime& dt )
  334. {
  335. d = ValueData::null();
  336. setValue( dt );
  337. }
  338. // create a floating-point value from time
  339. Value::Value( const TQTime& dt )
  340. {
  341. d = ValueData::null();
  342. setValue( dt );
  343. }
  344. // create a floating-point value from date
  345. Value::Value( const TQDate& dt )
  346. {
  347. d = ValueData::null();
  348. setValue( dt );
  349. }
  350. // create an array value
  351. Value::Value( unsigned columns, unsigned rows )
  352. {
  353. d = new ValueData;
  354. d->type = Array;
  355. d->format = fmt_None;
  356. d->pa = new ValueArray;
  357. d->pa->init( columns, rows );
  358. }
  359. // assign value from other
  360. // shallow copy: only copy the data pointer
  361. Value& Value::assign( const Value& _value )
  362. {
  363. d->unref();
  364. d = _value.d;
  365. d->ref();
  366. return *this;
  367. }
  368. // return type of the value
  369. Value::Type Value::type() const
  370. {
  371. return d ? d->type : Empty;
  372. }
  373. // set the value to boolean
  374. void Value::setValue( bool b )
  375. {
  376. detach();
  377. d->type = Boolean;
  378. d->b = b;
  379. d->format = fmt_Boolean;
  380. }
  381. // get the value as boolean
  382. bool Value::asBoolean() const
  383. {
  384. bool result = false;
  385. if( type() == Value::Boolean )
  386. result = d->b;
  387. return result;
  388. }
  389. // set the value to integer
  390. void Value::setValue( long i )
  391. {
  392. detach();
  393. d->type = Integer;
  394. d->i = i;
  395. d->format = fmt_Number;
  396. }
  397. // set the value to integer
  398. void Value::setValue( int i )
  399. {
  400. detach();
  401. d->type = Integer;
  402. d->i = static_cast<long>( i );
  403. d->format = fmt_Number;
  404. }
  405. // get the value as integer
  406. long Value::asInteger() const
  407. {
  408. long result = 0;
  409. if( type() == Value::Integer )
  410. result = d->i;
  411. if( type() == Value::Float )
  412. result = static_cast<long>(d->f);
  413. return result;
  414. }
  415. void Value::setValue( const Value& v )
  416. {
  417. assign( v );
  418. }
  419. // set the value as floating-point
  420. void Value::setValue( double f )
  421. {
  422. detach();
  423. d->type = Float;
  424. d->f = f;
  425. d->format = fmt_Number;
  426. }
  427. // get the value as floating-point
  428. double Value::asFloat() const
  429. {
  430. double result = 0.0;
  431. if( type() == Value::Float )
  432. result = d->f;
  433. if( type() == Value::Integer )
  434. result = static_cast<double>(d->i);
  435. return result;
  436. }
  437. // set the value as string
  438. void Value::setValue( const TQString& s )
  439. {
  440. detach();
  441. d->type = String;
  442. d->ps = new TQString( s );
  443. d->format = fmt_String;
  444. }
  445. // get the value as string
  446. TQString Value::asString() const
  447. {
  448. TQString result;
  449. if( type() == Value::String )
  450. if( d->ps )
  451. result = TQString( *d->ps );
  452. return result;
  453. }
  454. // set error message
  455. void Value::setError( const TQString& msg )
  456. {
  457. detach();
  458. d->type = Error;
  459. d->ps = new TQString( msg );
  460. }
  461. // get error message
  462. TQString Value::errorMessage() const
  463. {
  464. TQString result;
  465. if( type() == Value::Error )
  466. if( d->ps )
  467. result = TQString( *d->ps );
  468. return result;
  469. }
  470. // set the value as date/time
  471. // NOTE: date/time is stored as serial number
  472. // Day 61 means 1st of March, 1900
  473. void Value::setValue( const TQDateTime& dt )
  474. {
  475. // reference is 31 Dec, 1899 midnight
  476. TQDate refDate( 1899, 12, 31 );
  477. TQTime refTime( 0, 0 );
  478. int i = refDate.daysTo( dt.date() ) + 1;
  479. i += refTime.secsTo( dt.time() ) / 86400;
  480. setValue( i );
  481. d->format = fmt_DateTime;
  482. }
  483. void Value::setValue( const TQTime& time )
  484. {
  485. // reference time is midnight
  486. TQTime refTime( 0, 0 );
  487. int i = refTime.msecsTo( time ) /* / 86400000 */;
  488. setValue( i );
  489. d->format = fmt_Time;
  490. }
  491. void Value::setValue( const TQDate& date )
  492. {
  493. // reference date is 31 Dec, 1899
  494. TQDate refDate = TQDate( 1899, 12, 31 );
  495. int i = refDate.daysTo( date ) + 1;
  496. setValue( i );
  497. d->format = fmt_Date;
  498. }
  499. // get the value as date/time
  500. TQDateTime Value::asDateTime() const
  501. {
  502. return TQDateTime( asDate(), asTime() );
  503. }
  504. // get the value as date
  505. TQDate Value::asDate() const
  506. {
  507. TQDate dt( 1899, 12, 30 );
  508. int i = asInteger();
  509. dt = dt.addDays( i );
  510. return dt;
  511. }
  512. // get the value as time
  513. TQTime Value::asTime() const
  514. {
  515. TQTime dt;
  516. int i = asInteger();
  517. dt = dt.addMSecs(i) /*( f * 86400 * 1000 )*/;
  518. return dt;
  519. }
  520. Value::Format Value::format() const
  521. {
  522. return d ? d->format : fmt_None;
  523. }
  524. void Value::setFormat (Value::Format fmt)
  525. {
  526. detach();
  527. d->format = fmt;
  528. }
  529. Value Value::element( unsigned column, unsigned row ) const
  530. {
  531. if( (uint)d->type != Array ) return *this;
  532. if( !d->pa ) return *this;
  533. Value* v = d->pa->at (column % columns(), row % rows());
  534. return v ? Value( *v ) : empty();
  535. }
  536. void Value::setElement( unsigned column, unsigned row, const Value& v )
  537. {
  538. if( (uint)d->type != Array ) return;
  539. if( !d->pa ) return;
  540. detach();
  541. d->pa->set( column, row, new Value( v ) );
  542. }
  543. unsigned Value::columns() const
  544. {
  545. if( (uint)d->type != Array ) return 1;
  546. if( !d->pa ) return 1;
  547. return d->pa->columns;
  548. }
  549. unsigned Value::rows() const
  550. {
  551. if( (uint)d->type != Array ) return 1;
  552. if( !d->pa ) return 1;
  553. return d->pa->rows;
  554. }
  555. // reference to empty value
  556. const Value& Value::empty()
  557. {
  558. return ks_value_empty;
  559. }
  560. // reference to #DIV/0! error
  561. const Value& Value::errorDIV0()
  562. {
  563. if( !ks_error_div0.isError() )
  564. ks_error_div0.setError( "#DIV/0!" );
  565. return ks_error_div0;
  566. }
  567. // reference to #N/A error
  568. const Value& Value::errorNA()
  569. {
  570. if( !ks_error_na.isError() )
  571. ks_error_na.setError( "#N/A" );
  572. return ks_error_na;
  573. }
  574. // reference to #NAME? error
  575. const Value& Value::errorNAME()
  576. {
  577. if( !ks_error_name.isError() )
  578. ks_error_name.setError( "#NAME?" );
  579. return ks_error_name;
  580. }
  581. // reference to #NUM! error
  582. const Value& Value::errorNUM()
  583. {
  584. if( !ks_error_num.isError() )
  585. ks_error_num.setError( "#NUM!" );
  586. return ks_error_num;
  587. }
  588. // reference to #NULL! error
  589. const Value& Value::errorNULL()
  590. {
  591. if( !ks_error_null.isError() )
  592. ks_error_null.setError( "#NULL!" );
  593. return ks_error_null;
  594. }
  595. // reference to #REF! error
  596. const Value& Value::errorREF()
  597. {
  598. if( !ks_error_ref.isError() )
  599. ks_error_ref.setError( "#REF!" );
  600. return ks_error_ref;
  601. }
  602. // reference to #VALUE! error
  603. const Value& Value::errorVALUE()
  604. {
  605. if( !ks_error_value.isError() )
  606. ks_error_value.setError( "#VALUE!" );
  607. return ks_error_value;
  608. }
  609. // detach, create deep copy of ValueData
  610. void Value::detach()
  611. {
  612. if( d->isNull() || ( d->count > 1 ) )
  613. {
  614. ValueData* n;
  615. n = new ValueData;
  616. n->type = d->type;
  617. switch( n->type )
  618. {
  619. case Empty: break;
  620. case Boolean: n->b = d->b; break;
  621. case Integer: n->i = d->i; break;
  622. case Float: n->f = d->f; break;
  623. case String: n->ps = new TQString( *d->ps ); break;
  624. case Array: n->pa = new ValueArray; *n->pa = (*d->pa); break;
  625. case Error: n->ps = new TQString( *d->ps ); break;
  626. default: break;
  627. }
  628. d->unref();
  629. d = n;
  630. }
  631. }
  632. int Value::compare( double v1, double v2 )
  633. {
  634. double v3 = v1 - v2;
  635. if( v3 > DBL_EPSILON ) return 1;
  636. if( v3 < -DBL_EPSILON ) return -1;
  637. return 0;
  638. }
  639. bool Value::isZero( double v )
  640. {
  641. return fabs( v ) < DBL_EPSILON;
  642. }
  643. bool Value::isZero() const
  644. {
  645. if( !isNumber() ) return false;
  646. return isZero( asFloat() );
  647. }
  648. bool Value::allowComparison( const Value& v ) const
  649. {
  650. Value::Type t1 = d->type;
  651. Value::Type t2 = v.type();
  652. if( ( t1 == Empty ) && ( t2 == Empty ) ) return true;
  653. if( ( t1 == Empty ) && ( t2 == String ) ) return true;
  654. if( ( t1 == Boolean ) && ( t2 == Boolean ) ) return true;
  655. if( ( t1 == Boolean ) && ( t2 == Integer ) ) return true;
  656. if( ( t1 == Boolean ) && ( t2 == Float ) ) return true;
  657. if( ( t1 == Boolean ) && ( t2 == String ) ) return true;
  658. if( ( t1 == Integer ) && ( t2 == Boolean ) ) return true;
  659. if( ( t1 == Integer ) && ( t2 == Integer ) ) return true;
  660. if( ( t1 == Integer ) && ( t2 == Float ) ) return true;
  661. if( ( t1 == Integer ) && ( t2 == String ) ) return true;
  662. if( ( t1 == Float ) && ( t2 == Boolean ) ) return true;
  663. if( ( t1 == Float ) && ( t2 == Integer ) ) return true;
  664. if( ( t1 == Float ) && ( t2 == Float ) ) return true;
  665. if( ( t1 == Float ) && ( t2 == String ) ) return true;
  666. if( ( t1 == String ) && ( t2 == Empty ) ) return true;
  667. if( ( t1 == String ) && ( t2 == Boolean ) ) return true;
  668. if( ( t1 == String ) && ( t2 == Integer ) ) return true;
  669. if( ( t1 == String ) && ( t2 == Float ) ) return true;
  670. if( ( t1 == String ) && ( t2 == String ) ) return true;
  671. // errors can be compared too ...
  672. if ((t1 == Error) && (t2 == Error)) return true;
  673. return false;
  674. }
  675. // compare values. looks strange in order to be compatible with Excel
  676. int Value::compare( const Value& v ) const
  677. {
  678. Value::Type t1 = d->type;
  679. Value::Type t2 = v.type();
  680. // errors always less than everything else
  681. if( ( t1 == Error ) && ( t2 != Error ) )
  682. return -1;
  683. if( ( t2 == Error ) && ( t1 != Error ) )
  684. return 1;
  685. // comparing errors only yields 0 if they are the same
  686. if( ( t1 == Error ) && ( t2 == Error ) )
  687. return errorMessage() != v.errorMessage();
  688. // empty == empty
  689. if( ( t1 == Empty ) && ( t2 == Empty ) )
  690. return 0;
  691. // empty value is always less than string
  692. // (except when the string is empty)
  693. if( ( t1 == Empty ) && ( t2 == String ) )
  694. return( v.asString().isEmpty() ) ? 0 : -1;
  695. // boolean vs boolean
  696. if( ( t1 == Boolean ) && ( t2 == Boolean ) )
  697. {
  698. bool p = asBoolean();
  699. bool q = v.asBoolean();
  700. if( p ) return q ? 0 : 1;
  701. else return q ? -1 : 0;
  702. }
  703. // boolean is always greater than integer
  704. if( ( t1 == Boolean ) && ( t2 == Integer ) )
  705. return 1;
  706. // boolean is always greater than float
  707. if( ( t1 == Boolean ) && ( t2 == Float ) )
  708. return 1;
  709. // boolean is always greater than string
  710. if( ( t1 == Boolean ) && ( t2 == String ) )
  711. return 1;
  712. // integer is always less than boolean
  713. if( ( t1 == Integer ) && ( t2 == Boolean ) )
  714. return -1;
  715. // integer vs integer
  716. if( ( t1 == Integer ) && ( t2 == Integer ) )
  717. {
  718. long p = asInteger();
  719. long q = v.asInteger();
  720. return ( p == q ) ? 0 : ( p < q ) ? -1 : 1;
  721. }
  722. // integer vs float
  723. if( ( t1 == Integer ) && ( t2 == Float ) )
  724. return compare( asFloat(), v.asFloat() );
  725. // integer is always less than string
  726. if( ( t1 == Integer ) && ( t2 == String ) )
  727. return -1;
  728. // float is always less than boolean
  729. if( ( t1 == Float ) && ( t2 == Boolean ) )
  730. return -1;
  731. // float vs integer
  732. if( ( t1 == Float ) && ( t2 == Integer ) )
  733. return compare( asFloat(), v.asFloat() );
  734. // float vs float
  735. if( ( t1 == Float ) && ( t2 == Float ) )
  736. return compare( asFloat(), v.asFloat() );
  737. // float is always less than string
  738. if( ( t1 == Float ) && ( t2 == String ) )
  739. return -1;
  740. // string is always greater than empty value
  741. // (except when the string is empty)
  742. if( ( t1 == String ) && ( t2 == Empty ) )
  743. return( asString().isEmpty() ) ? 0 : 1;
  744. // string is always less than boolean
  745. if( ( t1 == String ) && ( t2 == Boolean ) )
  746. return -1;
  747. // string is always greater than integer
  748. if( ( t1 == String ) && ( t2 == Integer ) )
  749. return 1;
  750. // string is always greater than float
  751. if( ( t1 == String ) && ( t2 == Float ) )
  752. return 1;
  753. // The-Real-String comparison
  754. if( ( t1 == String ) && ( t2 == String ) )
  755. return asString().compare( v.asString() );
  756. // Undefined, actually allowComparison would return false
  757. return 0;
  758. }
  759. bool Value::equal( const Value& v ) const
  760. {
  761. if (!allowComparison (v)) return false;
  762. return compare( v ) == 0;
  763. }
  764. bool Value::less( const Value& v ) const
  765. {
  766. if (!allowComparison (v)) return false;
  767. return compare( v ) < 0;
  768. }
  769. bool Value::greater( const Value& v ) const
  770. {
  771. if (!allowComparison (v)) return false;
  772. return compare( v ) > 0;
  773. }
  774. TQTextStream& operator<<( TQTextStream& ts, Value::Type type )
  775. {
  776. switch( type )
  777. {
  778. case Value::Empty: ts << "Empty"; break;
  779. case Value::Boolean: ts << "Boolean"; break;
  780. case Value::Integer: ts << "Integer"; break;
  781. case Value::Float: ts << "Float"; break;
  782. case Value::String: ts << "String"; break;
  783. case Value::Array: ts << "Array"; break;
  784. case Value::Error: ts << "Error"; break;
  785. default: ts << "Unknown!"; break;
  786. };
  787. return ts;
  788. }
  789. TQTextStream& operator<<( TQTextStream& ts, Value value )
  790. {
  791. ts << value.type();
  792. switch( value.type() )
  793. {
  794. case Value::Empty: break;
  795. case Value::Boolean:
  796. ts << ": ";
  797. if (value.asBoolean()) ts << "TRUE";
  798. else ts << "FALSE"; break;
  799. case Value::Integer:
  800. ts << ": " << value.asInteger(); break;
  801. case Value::Float:
  802. ts << ": " << value.asFloat(); break;
  803. case Value::String:
  804. ts << ": " << value.asString(); break;
  805. case Value::Error:
  806. ts << "(" << value.errorMessage() << ")"; break;
  807. default: break;
  808. }
  809. return ts;
  810. }