1
//=============================================================================
3
// File : KviKvsVariant.cpp
4
// Creation date : Tue 07 Oct 2003 04:01:19 by Szymon Stefanek
6
// This file is part of the KVIrc IRC client distribution
7
// Copyright (C) 2003-2010 Szymon Stefanek <pragma at kvirc dot net>
9
// This program is FREE software. You can redistribute it and/or
10
// modify it under the terms of the GNU General Public License
11
// as published by the Free Software Foundation; either version 2
12
// of the License, or (at your opinion) any later version.
14
// This program is distributed in the HOPE that it will be USEFUL,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
// See the GNU General Public License for more details.
19
// You should have received a copy of the GNU General Public License
20
// along with this program. If not, write to the Free Software Foundation,
21
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
//=============================================================================
25
#include "KviKvsVariant.h"
26
#include "KviKvsArrayCast.h"
27
#include "KviKvsHash.h"
28
#include "KviKvsArray.h"
32
int KviKvsVariantComparison::compareIntString(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
36
if(pV1->m_pData->m_u.iInt == 0)
38
if(pV2->m_pData->m_u.pString->isEmpty())
39
return KviKvsVariantComparison::Equal;
42
if(pV2->asReal(dReal))
44
if(((kvs_real_t)pV1->m_pData->m_u.iInt) == dReal)
45
return KviKvsVariantComparison::Equal;
46
if(((kvs_real_t)pV1->m_pData->m_u.iInt) > dReal)
47
return KviKvsVariantComparison::FirstGreater;
48
return KviKvsVariantComparison::SecondGreater;
51
// compare as strings instead
53
pV1->asString(szString);
54
return -1 * szString.compare(*(pV2->m_pData->m_u.pString),Qt::CaseInsensitive);
57
int KviKvsVariantComparison::compareIntReal(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
59
if(((kvs_real_t)pV1->m_pData->m_u.iInt) == *(pV2->m_pData->m_u.pReal))
60
return KviKvsVariantComparison::Equal;
61
if(((kvs_real_t)pV1->m_pData->m_u.iInt) > *(pV2->m_pData->m_u.pReal))
62
return KviKvsVariantComparison::FirstGreater;
63
return KviKvsVariantComparison::SecondGreater;
66
int KviKvsVariantComparison::compareIntBool(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
68
if(pV1->m_pData->m_u.iInt == 0)
69
return pV2->m_pData->m_u.bBoolean ? KviKvsVariantComparison::SecondGreater : KviKvsVariantComparison::Equal;
70
return pV2->m_pData->m_u.bBoolean ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::FirstGreater;
73
int KviKvsVariantComparison::compareIntHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
75
if(pV1->m_pData->m_u.iInt == 0)
76
return pV2->m_pData->m_u.pHash->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
77
return KviKvsVariantComparison::FirstGreater;
80
int KviKvsVariantComparison::compareIntArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
82
if(pV1->m_pData->m_u.iInt == 0)
83
return pV2->m_pData->m_u.pArray->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
84
return KviKvsVariantComparison::FirstGreater;
87
int KviKvsVariantComparison::compareIntHObject(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
89
if(pV1->m_pData->m_u.iInt == 0.0)
90
return (pV2->m_pData->m_u.hObject == (kvs_hobject_t)0) ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::FirstGreater;
91
return KviKvsVariantComparison::SecondGreater;
94
int KviKvsVariantComparison::compareRealHObject(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
96
if(*(pV1->m_pData->m_u.pReal) == 0.0)
97
return (pV2->m_pData->m_u.hObject == (kvs_hobject_t)0) ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::FirstGreater;
98
return KviKvsVariantComparison::SecondGreater;
101
int KviKvsVariantComparison::compareRealString(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
105
if(*(pV1->m_pData->m_u.pReal) == 0.0)
107
if(pV2->m_pData->m_u.pString->isEmpty())
108
return KviKvsVariantComparison::Equal;
111
if(pV2->asReal(dReal))
113
if(*(pV1->m_pData->m_u.pReal) == dReal)
114
return KviKvsVariantComparison::Equal;
115
if(*(pV1->m_pData->m_u.pReal) > dReal)
116
return KviKvsVariantComparison::FirstGreater;
117
return KviKvsVariantComparison::SecondGreater;
120
// compare as strings instead
122
pV1->asString(szString);
123
return -1 * szString.compare(*(pV2->m_pData->m_u.pString),Qt::CaseInsensitive);
126
int KviKvsVariantComparison::compareRealBool(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
128
if(*(pV1->m_pData->m_u.pReal) == 0.0)
129
return pV2->m_pData->m_u.bBoolean ? KviKvsVariantComparison::SecondGreater : KviKvsVariantComparison::Equal;
130
return pV2->m_pData->m_u.bBoolean ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::FirstGreater;
133
int KviKvsVariantComparison::compareRealHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
135
if(*(pV1->m_pData->m_u.pReal) == 0)
136
return pV2->m_pData->m_u.pHash->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
137
return KviKvsVariantComparison::FirstGreater;
140
int KviKvsVariantComparison::compareRealArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
142
if(*(pV1->m_pData->m_u.pReal) == 0)
143
return pV2->m_pData->m_u.pArray->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
144
return KviKvsVariantComparison::FirstGreater;
147
int KviKvsVariantComparison::compareStringHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
149
if(pV1->m_pData->m_u.pString->isEmpty())
151
return pV2->m_pData->m_u.pHash->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
153
return KviKvsVariantComparison::FirstGreater;
156
int KviKvsVariantComparison::compareStringArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
158
if(pV1->m_pData->m_u.pString->isEmpty())
160
return pV2->m_pData->m_u.pArray->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
162
return KviKvsVariantComparison::FirstGreater;
165
int KviKvsVariantComparison::compareStringHObject(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
169
if(pV2->m_pData->m_u.hObject == (kvs_hobject_t)0)
171
if(pV1->m_pData->m_u.pString->isEmpty())
172
return KviKvsVariantComparison::Equal;
174
if(pV1->asReal(dReal))
177
return KviKvsVariantComparison::Equal;
181
return KviKvsVariantComparison::FirstGreater;
184
int KviKvsVariantComparison::compareBoolString(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
186
if(pV2->isEqualToNothing())
187
return pV1->m_pData->m_u.bBoolean ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
189
return pV1->m_pData->m_u.bBoolean ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::FirstGreater;
192
int KviKvsVariantComparison::compareBoolHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
194
if(pV1->m_pData->m_u.bBoolean)
195
return pV2->m_pData->m_u.pHash->isEmpty() ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
197
return pV2->m_pData->m_u.pHash->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
200
int KviKvsVariantComparison::compareBoolArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
202
if(pV1->m_pData->m_u.bBoolean)
203
return pV2->m_pData->m_u.pArray->isEmpty() ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
205
return pV2->m_pData->m_u.pArray->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
208
int KviKvsVariantComparison::compareBoolHObject(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
210
if(pV1->m_pData->m_u.bBoolean)
211
return pV2->m_pData->m_u.hObject == ((kvs_hobject_t)0) ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
213
return pV2->m_pData->m_u.hObject == ((kvs_hobject_t)0) ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
216
int KviKvsVariantComparison::compareArrayHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
218
if(pV1->m_pData->m_u.pArray->size() > pV2->m_pData->m_u.pHash->size())
219
return KviKvsVariantComparison::FirstGreater;
220
if(pV1->m_pData->m_u.pArray->size() == pV2->m_pData->m_u.pHash->size())
221
return KviKvsVariantComparison::Equal;
222
return KviKvsVariantComparison::SecondGreater;
225
int KviKvsVariantComparison::compareHObjectHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
227
if(pV2->m_pData->m_u.pHash->isEmpty())
228
return pV1->m_pData->m_u.hObject == ((kvs_hobject_t)0) ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
229
return pV1->m_pData->m_u.hObject == ((kvs_hobject_t)0) ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
232
int KviKvsVariantComparison::compareHObjectArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
234
if(pV2->m_pData->m_u.pArray->isEmpty())
235
return pV1->m_pData->m_u.hObject == ((kvs_hobject_t)0) ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
236
return pV1->m_pData->m_u.hObject == ((kvs_hobject_t)0) ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
240
KviKvsVariant::KviKvsVariant()
245
KviKvsVariant::KviKvsVariant(QString * pString, bool bEscape)
247
m_pData = new KviKvsVariantData;
248
m_pData->m_eType = KviKvsVariantData::String;
249
m_pData->m_uRefs = 1;
250
m_pData->m_u.pString = pString;
252
KviQString::escapeKvs(m_pData->m_u.pString);
255
KviKvsVariant::KviKvsVariant(const QString & szString, bool bEscape)
257
m_pData = new KviKvsVariantData;
258
m_pData->m_eType = KviKvsVariantData::String;
259
m_pData->m_uRefs = 1;
260
m_pData->m_u.pString = new QString(szString);
262
KviQString::escapeKvs(m_pData->m_u.pString);
265
KviKvsVariant::KviKvsVariant(const char * pcString, bool bEscape)
267
m_pData = new KviKvsVariantData;
268
m_pData->m_eType = KviKvsVariantData::String;
269
m_pData->m_uRefs = 1;
270
m_pData->m_u.pString = new QString(QString::fromUtf8(pcString));
272
KviQString::escapeKvs(m_pData->m_u.pString);
275
KviKvsVariant::KviKvsVariant(KviKvsArray * pArray)
277
m_pData = new KviKvsVariantData;
278
m_pData->m_eType = KviKvsVariantData::Array;
279
m_pData->m_uRefs = 1;
280
m_pData->m_u.pArray = pArray;
283
KviKvsVariant::KviKvsVariant(KviKvsHash * pHash)
285
m_pData = new KviKvsVariantData;
286
m_pData->m_eType = KviKvsVariantData::Hash;
287
m_pData->m_uRefs = 1;
288
m_pData->m_u.pHash = pHash;
291
KviKvsVariant::KviKvsVariant(kvs_real_t * pReal)
293
m_pData = new KviKvsVariantData;
294
m_pData->m_eType = KviKvsVariantData::Real;
295
m_pData->m_uRefs = 1;
296
m_pData->m_u.pReal = pReal;
299
KviKvsVariant::KviKvsVariant(kvs_real_t dReal)
301
m_pData = new KviKvsVariantData;
302
m_pData->m_eType = KviKvsVariantData::Real;
303
m_pData->m_uRefs = 1;
304
m_pData->m_u.pReal = new kvs_real_t;
305
*(m_pData->m_u.pReal) = dReal;
308
KviKvsVariant::KviKvsVariant(bool bBoolean)
310
m_pData = new KviKvsVariantData;
311
m_pData->m_eType = KviKvsVariantData::Boolean;
312
m_pData->m_uRefs = 1;
313
m_pData->m_u.bBoolean = bBoolean;
316
KviKvsVariant::KviKvsVariant(kvs_int_t iInt, bool)
318
m_pData = new KviKvsVariantData;
319
m_pData->m_eType = KviKvsVariantData::Integer;
320
m_pData->m_uRefs = 1;
321
m_pData->m_u.iInt = iInt;
324
KviKvsVariant::KviKvsVariant(kvs_hobject_t hObject)
326
m_pData = new KviKvsVariantData;
327
m_pData->m_eType = KviKvsVariantData::HObject;
328
m_pData->m_uRefs = 1;
329
m_pData->m_u.hObject = hObject;
332
KviKvsVariant::KviKvsVariant(const KviKvsVariant & variant)
334
m_pData = variant.m_pData;
339
#define DELETE_VARIANT_CONTENTS \
340
switch(m_pData->m_eType) \
342
case KviKvsVariantData::Array: \
343
delete m_pData->m_u.pArray; \
345
case KviKvsVariantData::Hash: \
346
delete m_pData->m_u.pHash; \
348
case KviKvsVariantData::String: \
349
delete m_pData->m_u.pString; \
351
case KviKvsVariantData::Real: \
352
delete m_pData->m_u.pReal; \
354
default: /* make gcc happy */ break; \
357
#define DETACH_CONTENTS \
360
if(m_pData->m_uRefs <= 1) \
362
DELETE_VARIANT_CONTENTS \
365
m_pData->m_uRefs--; \
369
#define RENEW_VARIANT_DATA \
372
if(m_pData->m_uRefs > 1) \
374
m_pData->m_uRefs--; \
375
m_pData = new KviKvsVariantData; \
376
m_pData->m_uRefs = 1; \
378
DELETE_VARIANT_CONTENTS \
381
m_pData = new KviKvsVariantData; \
382
m_pData->m_uRefs = 1; \
385
KviKvsVariant::~KviKvsVariant()
390
void KviKvsVariant::setString(QString * pString)
393
m_pData->m_eType = KviKvsVariantData::String;
394
m_pData->m_u.pString = pString;
397
void KviKvsVariant::setString(const QString & szString)
400
m_pData->m_eType = KviKvsVariantData::String;
401
m_pData->m_u.pString = new QString(szString);
404
void KviKvsVariant::setReal(kvs_real_t dReal)
407
m_pData->m_eType = KviKvsVariantData::Real;
408
m_pData->m_u.pReal = new kvs_real_t;
409
*(m_pData->m_u.pReal) = dReal;
412
void KviKvsVariant::setHObject(kvs_hobject_t hObject)
415
m_pData->m_eType = KviKvsVariantData::HObject;
416
m_pData->m_u.hObject = hObject;
419
void KviKvsVariant::setBoolean(bool bBoolean)
422
m_pData->m_eType = KviKvsVariantData::Boolean;
423
m_pData->m_u.bBoolean = bBoolean;
426
void KviKvsVariant::setReal(kvs_real_t * pReal)
429
m_pData->m_eType = KviKvsVariantData::Real;
430
m_pData->m_u.pReal = pReal;
433
void KviKvsVariant::setInteger(kvs_int_t iInt)
436
m_pData->m_eType = KviKvsVariantData::Integer;
437
m_pData->m_u.iInt = iInt;
440
void KviKvsVariant::setArray(KviKvsArray * pArray)
443
m_pData->m_eType = KviKvsVariantData::Array;
444
m_pData->m_u.pArray = pArray;
447
void KviKvsVariant::setHash(KviKvsHash * pHash)
450
m_pData->m_eType = KviKvsVariantData::Hash;
451
m_pData->m_u.pHash = pHash;
454
void KviKvsVariant::setNothing()
458
if(m_pData->m_uRefs <= 1)
460
DELETE_VARIANT_CONTENTS
470
bool KviKvsVariant::isEmpty() const
474
switch(m_pData->m_eType)
476
case KviKvsVariantData::String:
477
return m_pData->m_u.pString->isEmpty();
479
case KviKvsVariantData::Array:
480
return m_pData->m_u.pArray->isEmpty();
482
case KviKvsVariantData::Hash:
483
return m_pData->m_u.pHash->isEmpty();
485
case KviKvsVariantData::HObject:
486
return m_pData->m_u.hObject == 0;
488
default: /* make gcc happy */ break;
493
bool KviKvsVariant::asBoolean() const
497
switch(m_pData->m_eType)
499
case KviKvsVariantData::Boolean:
500
return m_pData->m_u.bBoolean;
502
case KviKvsVariantData::String:
504
if(m_pData->m_u.pString->isEmpty())
507
// check integer or real values
509
kvs_int_t iVal = (kvs_int_t)KviQString::toI64(*(m_pData->m_u.pString),&bOk);
512
kvs_real_t dVal = m_pData->m_u.pString->toDouble(&bOk);
514
return (dVal != 0.0);
515
// non number, non empty
519
case KviKvsVariantData::Integer:
520
return m_pData->m_u.iInt;
522
case KviKvsVariantData::Real:
523
return *(m_pData->m_u.pReal) != 0.0;
525
case KviKvsVariantData::Array:
526
return !(m_pData->m_u.pArray->isEmpty());
528
case KviKvsVariantData::Hash:
529
return !(m_pData->m_u.pHash->isEmpty());
531
case KviKvsVariantData::HObject:
532
return m_pData->m_u.hObject;
534
default: /* make gcc happy */ break;
536
qDebug("WARNING: invalid variant type %d in KviKvsVariant::asBoolean()",m_pData->m_eType);
540
bool KviKvsVariant::asHObject(kvs_hobject_t & hObject) const
544
// nothing evaluates to a null object
548
switch(m_pData->m_eType)
550
case KviKvsVariantData::HObject:
551
hObject = m_pData->m_u.hObject;
554
case KviKvsVariantData::Integer:
555
if(m_pData->m_u.iInt == 0)
562
case KviKvsVariantData::String:
563
if(*(m_pData->m_u.pString) == "0")
570
case KviKvsVariantData::Boolean:
571
if(!(m_pData->m_u.bBoolean))
576
default: /* make gcc happy */ break;
581
bool KviKvsVariant::asNumber(KviKvsNumber & number) const
588
number.m_u.iInt = m_pData->m_u.iInt;
589
number.m_type = KviKvsNumber::Integer;
595
number.m_u.dReal = *(m_pData->m_u.pReal);
596
number.m_type = KviKvsNumber::Real;
600
if(asInteger(number.m_u.iInt))
602
number.m_type = KviKvsNumber::Integer;
606
if(asReal(number.m_u.dReal))
608
number.m_type = KviKvsNumber::Real;
614
void KviKvsVariant::castToNumber(KviKvsNumber & number) const
619
number.m_type = KviKvsNumber::Integer;
625
number.m_u.iInt = m_pData->m_u.iInt;
626
number.m_type = KviKvsNumber::Integer;
632
number.m_u.dReal = *(m_pData->m_u.pReal);
633
number.m_type = KviKvsNumber::Real;
637
if(asInteger(number.m_u.iInt))
639
number.m_type = KviKvsNumber::Integer;
643
if(asReal(number.m_u.dReal))
645
number.m_type = KviKvsNumber::Real;
648
castToInteger(number.m_u.iInt);
649
number.m_type = KviKvsNumber::Integer;
652
void KviKvsVariant::castToArray(KviKvsArrayCast * pCast) const
656
pCast->set(new KviKvsArray(),true);
660
switch(m_pData->m_eType)
662
case KviKvsVariantData::Array:
663
pCast->set(m_pData->m_u.pArray,false);
665
case KviKvsVariantData::Hash:
667
KviPointerHashTableIterator<QString,KviKvsVariant> it(*(m_pData->m_u.pHash->dict()));
668
KviKvsArray * pArray = new KviKvsArray();
670
while(KviKvsVariant * pVariant = it.current())
672
pArray->set(idx,new KviKvsVariant(*pVariant));
676
pCast->set(pArray,true);
682
KviKvsArray * pArray = new KviKvsArray();
683
pArray->set(0,new KviKvsVariant(*this));
684
pCast->set(pArray,true);
690
void KviKvsVariant::convertToArray()
694
setArray(new KviKvsArray());
698
switch(m_pData->m_eType)
700
case KviKvsVariantData::Array:
703
case KviKvsVariantData::Hash:
705
KviPointerHashTableIterator<QString,KviKvsVariant> it(*(m_pData->m_u.pHash->dict()));
706
KviKvsArray * pArray = new KviKvsArray();
708
while(KviKvsVariant * pVariant = it.current())
710
pArray->set(idx,new KviKvsVariant(*pVariant));
720
KviKvsArray * pArray = new KviKvsArray();
721
pArray->set(0,new KviKvsVariant(*this));
728
bool KviKvsVariant::asInteger(kvs_int_t & iVal) const
732
switch(m_pData->m_eType)
734
case KviKvsVariantData::Integer:
735
iVal = m_pData->m_u.iInt;
738
case KviKvsVariantData::String:
741
iVal = (kvs_int_t)KviQString::toI64(*(m_pData->m_u.pString),&bOk);
745
case KviKvsVariantData::Real:
746
// FIXME: this truncates the value!
747
iVal = (kvs_int_t)*(m_pData->m_u.pReal);
750
case KviKvsVariantData::Boolean:
751
iVal = m_pData->m_u.bBoolean ? 1 : 0;
754
//case KviKvsVariantData::HObject: <-- light casts from objects to integer are not valid
755
// iVal = m_pData->m_u.hObject ? 1 : 0;
758
default: /* make gcc happy */
764
void KviKvsVariant::castToInteger(kvs_int_t & iVal) const
771
switch(m_pData->m_eType)
773
case KviKvsVariantData::Integer:
774
iVal = m_pData->m_u.iInt;
776
case KviKvsVariantData::Boolean:
777
iVal = m_pData->m_u.bBoolean ? 1 : 0;
779
case KviKvsVariantData::HObject:
780
iVal = m_pData->m_u.hObject ? 1 : 0;
782
case KviKvsVariantData::String:
785
iVal = (kvs_int_t)KviQString::toI64(*(m_pData->m_u.pString),&bOk);
788
iVal = m_pData->m_u.pString->length();
791
case KviKvsVariantData::Real:
792
// FIXME: this truncates the value!
793
iVal = (kvs_int_t)*(m_pData->m_u.pReal);
795
case KviKvsVariantData::Array:
796
iVal = m_pData->m_u.pArray->size();
798
case KviKvsVariantData::Hash:
799
iVal = m_pData->m_u.pHash->size();
801
default: /* make gcc happy */
807
bool KviKvsVariant::asReal(kvs_real_t & dVal) const
811
switch(m_pData->m_eType)
813
case KviKvsVariantData::Integer:
814
dVal = m_pData->m_u.iInt;
817
case KviKvsVariantData::String:
820
dVal = m_pData->m_u.pString->toDouble(&bOk);
824
case KviKvsVariantData::Real:
825
dVal = *(m_pData->m_u.pReal);
828
case KviKvsVariantData::Boolean:
829
dVal = m_pData->m_u.bBoolean ? 1.0 : 0.0;
832
default: /* by default we make gcc happy */ break;
837
void KviKvsVariant::asString(QString & szBuffer) const
841
szBuffer = QString();
844
switch(m_pData->m_eType)
846
case KviKvsVariantData::String:
847
szBuffer = *(m_pData->m_u.pString);
849
case KviKvsVariantData::Array:
850
szBuffer = QString(); m_pData->m_u.pArray->appendAsString(szBuffer);
852
case KviKvsVariantData::Hash:
853
szBuffer = QString(); m_pData->m_u.pHash->appendAsString(szBuffer);
855
case KviKvsVariantData::Integer:
856
szBuffer.setNum(m_pData->m_u.iInt);
858
case KviKvsVariantData::Real:
859
szBuffer.setNum(*(m_pData->m_u.pReal));
861
case KviKvsVariantData::Boolean:
862
szBuffer.setNum(m_pData->m_u.bBoolean ? 1 : 0); break;
863
case KviKvsVariantData::HObject:
864
if(m_pData->m_u.hObject)
865
szBuffer = QString("object[%1]").arg((long int)m_pData->m_u.hObject,0,16);
867
szBuffer = "null-object";
869
default: /* make gcc happy */ break;
873
void KviKvsVariant::appendAsString(QString & szBuffer) const
877
switch(m_pData->m_eType)
879
case KviKvsVariantData::String:
880
szBuffer.append(*(m_pData->m_u.pString));
882
case KviKvsVariantData::Array:
883
m_pData->m_u.pArray->appendAsString(szBuffer);
885
case KviKvsVariantData::Hash:
886
m_pData->m_u.pHash->appendAsString(szBuffer);
888
case KviKvsVariantData::Integer:
889
KviQString::appendNumber(szBuffer,m_pData->m_u.iInt);
891
case KviKvsVariantData::Real:
892
KviQString::appendNumber(szBuffer,*(m_pData->m_u.pReal));
894
case KviKvsVariantData::Boolean:
895
KviQString::appendNumber(szBuffer,m_pData->m_u.bBoolean ? 1 : 0);
897
case KviKvsVariantData::HObject:
898
szBuffer.append(m_pData->m_u.hObject ? "object" : "null-object");
900
default: /* make gcc happy */ break;
904
void KviKvsVariant::dump(const char * pcPrefix) const
908
qDebug("%s Nothing [this=0x%lx]",pcPrefix,(long unsigned int)this);
911
switch(m_pData->m_eType)
913
case KviKvsVariantData::String:
914
qDebug("%s String(%s) [this=0x%lx]",pcPrefix,m_pData->m_u.pString->toUtf8().data(),(long unsigned int)this);
916
case KviKvsVariantData::Array:
917
qDebug("%s Array(ptr=0x%lx) [this=0x%lx]",pcPrefix,(long unsigned int)m_pData->m_u.pArray,(long unsigned int)this);
919
case KviKvsVariantData::Hash:
920
qDebug("%s Hash(ptr=0x%lx,dict=0x%lx) [this=0x%lx]",pcPrefix,(long unsigned int)m_pData->m_u.pHash,(long unsigned int)m_pData->m_u.pHash->dict(),(long unsigned int)this);
922
case KviKvsVariantData::Integer:
923
qDebug("%s Integer(%d) [this=0x%lx]",pcPrefix,(int) m_pData->m_u.iInt,(long unsigned int)this);
925
case KviKvsVariantData::Real:
926
qDebug("%s Real(%f) [this=0x%lx]",pcPrefix,*(m_pData->m_u.pReal),(long unsigned int)this);
928
case KviKvsVariantData::Boolean:
929
qDebug("%s Boolean(%s) [this=0x%lx]",pcPrefix,m_pData->m_u.bBoolean ? "true" : "false",(long unsigned int)this);
931
case KviKvsVariantData::HObject:
932
qDebug("%s HObject(%lx) [this=0x%lx]",pcPrefix,(long unsigned int)m_pData->m_u.hObject,(long unsigned int)this);
934
default: /* make gcc happy */ break;
938
void KviKvsVariant::copyFrom(const KviKvsVariant * pVariant)
941
m_pData = pVariant->m_pData;
946
void KviKvsVariant::copyFrom(const KviKvsVariant & variant)
949
m_pData = variant.m_pData;
954
void KviKvsVariant::takeFrom(KviKvsVariant * pVariant)
957
m_pData = pVariant->m_pData;
958
pVariant->m_pData = 0;
961
void KviKvsVariant::takeFrom(KviKvsVariant & variant)
964
m_pData = variant.m_pData;
968
void KviKvsVariant::getTypeName(QString & szBuffer) const
972
szBuffer = "nothing";
975
switch(m_pData->m_eType)
977
case KviKvsVariantData::String:
980
case KviKvsVariantData::Hash:
983
case KviKvsVariantData::Array:
986
case KviKvsVariantData::Real:
989
case KviKvsVariantData::Integer:
990
szBuffer = "integer";
992
case KviKvsVariantData::Boolean:
993
szBuffer = "boolean";
995
case KviKvsVariantData::HObject:
996
szBuffer = "hobject";
999
szBuffer = "internal_error";
1004
bool KviKvsVariant::isEqualToNothing() const
1008
switch(m_pData->m_eType)
1010
case KviKvsVariantData::HObject:
1011
return (m_pData->m_u.hObject == (kvs_hobject_t)0);
1013
case KviKvsVariantData::Integer:
1014
return (m_pData->m_u.iInt == 0);
1016
case KviKvsVariantData::Real:
1017
return (*(m_pData->m_u.pReal) == 0.0);
1019
case KviKvsVariantData::String:
1021
if(m_pData->m_u.pString->isEmpty())
1025
return dReal == 0.0;
1029
case KviKvsVariantData::Boolean:
1030
return !m_pData->m_u.bBoolean;
1032
case KviKvsVariantData::Hash:
1033
return m_pData->m_u.pHash->isEmpty();
1035
case KviKvsVariantData::Array:
1036
return m_pData->m_u.pArray->isEmpty();
1045
#define CMP_THISGREATER -1
1047
#define CMP_OTHERGREATER 1
1049
int KviKvsVariant::compare(const KviKvsVariant * pOther, bool bPreferNumeric) const
1052
return isEqualToNothing() ? CMP_EQUAL : CMP_THISGREATER;
1053
if(!pOther->m_pData)
1054
return isEqualToNothing() ? CMP_EQUAL : CMP_THISGREATER;
1056
return pOther->isEqualToNothing() ? CMP_EQUAL : CMP_OTHERGREATER;
1058
switch(m_pData->m_eType)
1060
case KviKvsVariantData::HObject:
1061
switch(pOther->m_pData->m_eType)
1063
case KviKvsVariantData::HObject:
1064
if(m_pData->m_u.hObject == pOther->m_pData->m_u.hObject)
1066
if(m_pData->m_u.hObject == ((kvs_hobject_t)0))
1067
return CMP_OTHERGREATER;
1068
return CMP_THISGREATER;
1070
case KviKvsVariantData::Integer:
1071
return -1 * KviKvsVariantComparison::compareIntHObject(pOther,this);
1073
case KviKvsVariantData::Real:
1074
return -1 * KviKvsVariantComparison::compareRealHObject(pOther,this);
1076
case KviKvsVariantData::String:
1077
return -1 * KviKvsVariantComparison::compareStringHObject(pOther,this);
1079
case KviKvsVariantData::Boolean:
1080
return -1 * KviKvsVariantComparison::compareBoolHObject(pOther,this);
1082
case KviKvsVariantData::Hash:
1083
return KviKvsVariantComparison::compareHObjectHash(this,pOther);
1085
case KviKvsVariantData::Array:
1086
return KviKvsVariantComparison::compareHObjectArray(this,pOther);
1088
default: // just make gcc happy
1092
case KviKvsVariantData::Integer:
1093
switch(pOther->m_pData->m_eType)
1095
case KviKvsVariantData::HObject:
1096
return KviKvsVariantComparison::compareIntHObject(this,pOther);
1098
case KviKvsVariantData::Integer:
1099
if(m_pData->m_u.iInt == pOther->m_pData->m_u.iInt)
1101
if(m_pData->m_u.iInt > pOther->m_pData->m_u.iInt)
1102
return CMP_THISGREATER;
1103
return CMP_OTHERGREATER;
1105
case KviKvsVariantData::Real:
1106
return KviKvsVariantComparison::compareIntReal(this,pOther);
1108
case KviKvsVariantData::String:
1109
return KviKvsVariantComparison::compareIntString(this,pOther);
1111
case KviKvsVariantData::Boolean:
1112
return KviKvsVariantComparison::compareIntBool(this,pOther);
1114
case KviKvsVariantData::Hash:
1115
return KviKvsVariantComparison::compareIntHash(this,pOther);
1117
case KviKvsVariantData::Array:
1118
return KviKvsVariantComparison::compareIntArray(this,pOther);
1120
default: // just make gcc happy
1124
case KviKvsVariantData::Real:
1125
switch(pOther->m_pData->m_eType)
1127
case KviKvsVariantData::HObject:
1128
return KviKvsVariantComparison::compareRealHObject(this,pOther);
1130
case KviKvsVariantData::Integer:
1131
return -1 * KviKvsVariantComparison::compareIntReal(pOther,this);
1133
case KviKvsVariantData::Real:
1134
if(*(m_pData->m_u.pReal) == *(pOther->m_pData->m_u.pReal))
1136
if(*(m_pData->m_u.pReal) > *(pOther->m_pData->m_u.pReal))
1137
return CMP_THISGREATER;
1138
return CMP_OTHERGREATER;
1140
case KviKvsVariantData::String:
1141
return KviKvsVariantComparison::compareRealString(this,pOther);
1143
case KviKvsVariantData::Boolean:
1144
return KviKvsVariantComparison::compareRealBool(this,pOther);
1146
case KviKvsVariantData::Hash:
1147
return KviKvsVariantComparison::compareRealHash(this,pOther);
1149
case KviKvsVariantData::Array:
1150
return KviKvsVariantComparison::compareRealArray(this,pOther);
1152
default: // just make gcc happy
1156
case KviKvsVariantData::String:
1157
switch(pOther->m_pData->m_eType)
1159
case KviKvsVariantData::String:
1162
// prefer numeric comparison
1167
if(pOther->asReal(dReal2))
1169
if(dReal1 == dReal2)
1172
return CMP_THISGREATER;
1173
return CMP_OTHERGREATER;
1177
return -1 * m_pData->m_u.pString->compare(*(pOther->m_pData->m_u.pString),Qt::CaseInsensitive);
1178
case KviKvsVariantData::Real:
1179
return -1 * KviKvsVariantComparison::compareRealString(pOther,this);
1180
case KviKvsVariantData::Integer:
1181
return -1 * KviKvsVariantComparison::compareIntString(pOther,this);
1182
case KviKvsVariantData::Boolean:
1183
return -1 * KviKvsVariantComparison::compareBoolString(pOther,this);
1185
case KviKvsVariantData::Hash:
1186
return KviKvsVariantComparison::compareStringHash(this,pOther);
1188
case KviKvsVariantData::Array:
1189
return KviKvsVariantComparison::compareStringArray(this,pOther);
1191
case KviKvsVariantData::HObject:
1192
return KviKvsVariantComparison::compareStringHObject(this,pOther);
1198
case KviKvsVariantData::Hash:
1199
switch(pOther->m_pData->m_eType)
1201
case KviKvsVariantData::String:
1202
return -1 * KviKvsVariantComparison::compareStringHash(pOther,this);
1203
case KviKvsVariantData::Real:
1204
return -1 * KviKvsVariantComparison::compareRealHash(pOther,this);
1206
case KviKvsVariantData::Integer:
1207
return -1 * KviKvsVariantComparison::compareIntHash(pOther,this);
1209
case KviKvsVariantData::Boolean:
1210
return -1 * KviKvsVariantComparison::compareBoolHash(pOther,this);
1212
case KviKvsVariantData::Hash:
1213
if(m_pData->m_u.pHash->size() > pOther->m_pData->m_u.pHash->size())
1214
return CMP_THISGREATER;
1215
if(m_pData->m_u.pHash->size() == pOther->m_pData->m_u.pHash->size())
1217
return CMP_OTHERGREATER;
1219
case KviKvsVariantData::Array:
1220
return -1 * KviKvsVariantComparison::compareArrayHash(pOther,this);
1222
case KviKvsVariantData::HObject:
1223
return -1 * KviKvsVariantComparison::compareHObjectHash(pOther,this);
1229
case KviKvsVariantData::Array:
1230
switch(pOther->m_pData->m_eType)
1232
case KviKvsVariantData::String:
1233
return -1 * KviKvsVariantComparison::compareStringArray(pOther,this);
1234
case KviKvsVariantData::Real:
1235
return -1 * KviKvsVariantComparison::compareRealArray(pOther,this);
1236
case KviKvsVariantData::Integer:
1237
return -1 * KviKvsVariantComparison::compareIntArray(pOther,this);
1238
case KviKvsVariantData::Boolean:
1239
return -1 * KviKvsVariantComparison::compareBoolArray(pOther,this);
1241
case KviKvsVariantData::Hash:
1242
return KviKvsVariantComparison::compareArrayHash(this,pOther);
1244
case KviKvsVariantData::Array:
1245
if(m_pData->m_u.pArray->size() > pOther->m_pData->m_u.pArray->size())
1246
return CMP_THISGREATER;
1247
if(m_pData->m_u.pArray->size() == pOther->m_pData->m_u.pArray->size())
1249
return CMP_OTHERGREATER;
1251
case KviKvsVariantData::HObject:
1252
return -1 * KviKvsVariantComparison::compareHObjectArray(pOther,this);
1258
case KviKvsVariantData::Boolean:
1259
switch(pOther->m_pData->m_eType)
1261
case KviKvsVariantData::String:
1262
return KviKvsVariantComparison::compareBoolString(this,pOther);
1264
case KviKvsVariantData::Real:
1265
return -1 * KviKvsVariantComparison::compareRealBool(pOther,this);
1267
case KviKvsVariantData::Integer:
1268
return -1 * KviKvsVariantComparison::compareIntBool(pOther,this);
1270
case KviKvsVariantData::Boolean:
1271
if(m_pData->m_u.bBoolean == pOther->m_pData->m_u.bBoolean)
1273
if(m_pData->m_u.bBoolean)
1274
return CMP_THISGREATER;
1275
return CMP_OTHERGREATER;
1277
case KviKvsVariantData::Hash:
1278
return KviKvsVariantComparison::compareBoolHash(this,pOther);
1280
case KviKvsVariantData::Array:
1281
return KviKvsVariantComparison::compareBoolArray(this,pOther);
1283
case KviKvsVariantData::HObject:
1284
return KviKvsVariantComparison::compareBoolHObject(this,pOther);
1290
default: // should never happen anyway
1294
return CMP_THISGREATER; // should never happen
1297
void KviKvsVariant::serializeString(QString & szBuffer)
1299
szBuffer.replace('\\',"\\\\");
1300
szBuffer.replace('\n',"\\n");
1301
szBuffer.replace('\r',"\\r");
1302
szBuffer.replace('\b',"\\b");
1303
szBuffer.replace('\t',"\\t");
1304
szBuffer.replace('\f',"\\f");
1305
szBuffer.replace('/',"\\/");
1306
szBuffer.replace('"',"\\\"");
1307
szBuffer.prepend('"');
1308
szBuffer.append('"');
1311
void KviKvsVariant::serialize(QString & szResult)
1319
switch(m_pData->m_eType)
1321
case KviKvsVariantData::HObject:
1322
//can't serialize objects yet
1324
case KviKvsVariantData::Integer:
1325
szResult.setNum(m_pData->m_u.iInt);
1327
case KviKvsVariantData::Real:
1328
szResult.setNum(*(m_pData->m_u.pReal));
1330
case KviKvsVariantData::String:
1331
szResult = *(m_pData->m_u.pString);
1332
serializeString(szResult);
1334
case KviKvsVariantData::Boolean:
1335
szResult = m_pData->m_u.bBoolean ? "true" : "false";
1337
case KviKvsVariantData::Hash:
1338
m_pData->m_u.pHash->serialize(szResult);
1340
case KviKvsVariantData::Array:
1341
m_pData->m_u.pArray->serialize(szResult);
1343
case KviKvsVariantData::Nothing:
1346
default: // just make gcc happy
1351
KviKvsVariant * KviKvsVariant::unserialize(const QString & szBuffer)
1353
KviKvsVariant * pResult = 0;
1355
const QChar * pAux = (const QChar *)szBuffer.constData();
1357
pResult = unserialize(&pAux);
1361
//strange extra characters?
1370
KviKvsVariant * KviKvsVariant::unserialize(const QChar ** ppAux)
1372
KviKvsVariant * pResult = 0;
1374
while((*ppAux)->isSpace())
1377
switch((*ppAux)->unicode())
1381
pResult = unserializeBool(ppAux,true);
1385
pResult = unserializeBool(ppAux,false);
1389
pResult = unserializeNull(ppAux);
1393
pResult = unserializeArray(ppAux);
1397
pResult = unserializeHash(ppAux);
1401
pResult = unserializeString(ppAux);
1415
pResult = unserializeNumber(ppAux);
1422
while((*ppAux)->isSpace())
1428
KviKvsVariant * KviKvsVariant::unserializeBool(const QChar ** ppAux, bool bBool)
1434
if(KviQString::equalCIN(QString("true"),*ppAux,4))
1440
if(KviQString::equalCIN(QString("false"),*ppAux,5))
1448
return new KviKvsVariant(bBool);
1452
KviKvsVariant * KviKvsVariant::unserializeNull(const QChar ** ppAux)
1454
if(KviQString::equalCIN(QString("null"),*ppAux,4))
1457
return new KviKvsVariant();
1462
KviKvsVariant * KviKvsVariant::unserializeNumber(const QChar ** ppAux)
1466
if((*ppAux)->unicode() == '-')
1472
if(!(*ppAux)->isDigit())
1477
while((*ppAux)->isDigit())
1479
szData.append(**ppAux);
1483
if((*ppAux)->unicode() == '.')
1485
return unserializeReal(ppAux,szData);
1488
return unserializeInteger(ppAux,szData);
1491
KviKvsVariant * KviKvsVariant::unserializeReal(const QChar ** ppAux, QString & szData)
1494
(*ppAux)++; //skip .
1496
while((*ppAux)->isDigit())
1498
szData.append(**ppAux);
1502
if((*ppAux)->unicode() == 'e' || (*ppAux)->unicode() == 'E')
1505
if((*ppAux)->unicode() == '-')
1507
szExponent.append('-');
1510
if((*ppAux)->unicode() == '+')
1512
szExponent.append('+');
1517
while((*ppAux)->isDigit())
1519
szExponent.append(**ppAux);
1524
float fValue = szData.toFloat();
1525
if(!szExponent.isNull())
1527
fValue *= pow(10.0,szExponent.toInt());
1529
return new KviKvsVariant(fValue);
1532
KviKvsVariant * KviKvsVariant::unserializeInteger(const QChar ** ppAux, QString & szData)
1536
if((*ppAux)->unicode() == 'e' || (*ppAux)->unicode() == 'E')
1539
if((*ppAux)->unicode() == '-')
1541
szExponent.append('-');
1544
if((*ppAux)->unicode() == '+')
1546
szExponent.append('+');
1551
while((*ppAux)->isDigit())
1553
szExponent.append(**ppAux);
1558
kvs_int_t iValue = szData.toInt();
1559
if(!szExponent.isNull())
1561
iValue *= (kvs_int_t) pow(10.0,szExponent.toInt());
1563
return new KviKvsVariant(iValue);
1566
KviKvsVariant * KviKvsVariant::unserializeString(const QChar ** ppAux)
1569
unserializeString(ppAux,szBuffer);
1570
return new KviKvsVariant(szBuffer);
1573
void KviKvsVariant::unserializeString(const QChar ** ppAux, QString & szData)
1576
QString szHex; //temp var
1579
while((*ppAux)->unicode())
1581
switch((*ppAux)->unicode())
1591
switch((*ppAux)->unicode())
1594
szData.append('\t');
1597
szData.append('\"');
1603
szData.append('\b');
1606
szData.append('\f');
1609
szData.append('\n');
1612
szData.append('\r');
1615
//4 hexadecmical digits pending...
1618
for(int i=0; i<4 && (*ppAux)->unicode(); i++)
1620
if((*ppAux)->isDigit() ||
1621
((*ppAux)->unicode() >='A' && (*ppAux)->unicode() <='F')|| //ABCDEF
1622
((*ppAux)->unicode() >='a' && (*ppAux)->unicode() <='f')) //abcdef
1624
szHex.append(**ppAux);
1631
szData.append(QChar(szHex.toUInt(0,16)));
1634
//Fallback; incorrect escape
1636
szData.append('\\');
1641
szData.append(**ppAux);
1648
KviKvsVariant * KviKvsVariant::unserializeHash(const QChar ** ppAux)
1650
KviKvsHash * pHash = new KviKvsHash();
1652
KviKvsVariant * pElement = 0;
1658
//skip leading space
1659
while((*ppAux)->isSpace())
1661
//waiting for starting of string
1662
if((*ppAux)->unicode() != '\"')
1664
//strange characters
1668
unserializeString(ppAux,szKey);
1671
//Strange element name
1676
//skip leading space before ':'
1677
while((*ppAux)->isSpace())
1679
//waiting for name-value delimeter
1680
if((*ppAux)->unicode() != ':')
1682
//strange characters
1689
pElement = unserialize(ppAux);
1692
pHash->set(szKey,pElement);
1694
while((*ppAux)->isSpace())
1696
switch((*ppAux)->unicode())
1705
return new KviKvsVariant(pHash);
1721
KviKvsVariant * KviKvsVariant::unserializeArray(const QChar ** ppAux)
1723
KviKvsArray * pArray = new KviKvsArray();
1724
KviKvsVariant * pElement = 0;
1729
pElement = unserialize(ppAux);
1732
pArray->set(i,pElement);
1734
while((*ppAux)->isSpace())
1736
switch((*ppAux)->unicode())
1745
return new KviKvsVariant(pArray);