~ubuntu-branches/ubuntu/trusty/kvirc/trusty

« back to all changes in this revision

Viewing changes to src/kvirc/kvs/KviKvsVariant.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kai Wasserbäch, Kai Wasserbäch, Raúl Sánchez Siles
  • Date: 2011-02-12 10:40:21 UTC
  • mfrom: (14.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110212104021-5mh4f75jlku20mnt
The combined "Twisted Experiment" and "Nocturnal Raid" release.

[ Kai Wasserbäch ]
* Synced to upstream's SVN revision 5467.
* debian/rules:
  - Added .PHONY line.
  - Resurrect -DMANUAL_REVISION, got lost somewhere and we build SVN
    revisions again.
  - Replace "-DWITH_NO_EMBEDDED_CODE=YES" with "-DWANT_CRYPTOPP=YES".
  - Change the remaining -DWITH/-DWITHOUT to the new -DWANT syntax.
* debian/control:
  - Removed DMUA, I'm a DD now.
  - Changed my e-mail address.
  - Removed unneeded relationships (no upgrades over two releases are
    supported).
  - Fix Suggests for kvirc-dbg.
  - kvirc-data: Make the "Suggests: kvirc" a Recommends, doesn't make much
    sense to install the -data package without the program.
* debian/source/local-options: Added with "unapply-patches".
* debian/kvirc.lintian-overrides: Updated to work for 4.1.1.
* debian/patches/21_make_shared-mime-info_B-D_superfluous.patch: Updated.
* debian/kvirc-data.install: Added .notifyrc.

[ Raúl Sánchez Siles ]
* Stating the right version where kvirc-data break and replace should happen.
* Fixing link to license file.
* Added French and Portuguese man pages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=============================================================================
 
2
//
 
3
//   File : KviKvsVariant.cpp
 
4
//   Creation date : Tue 07 Oct 2003 04:01:19 by Szymon Stefanek
 
5
//
 
6
//   This file is part of the KVIrc IRC client distribution
 
7
//   Copyright (C) 2003-2010 Szymon Stefanek <pragma at kvirc dot net>
 
8
//
 
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.
 
13
//
 
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.
 
18
//
 
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.
 
22
//
 
23
//=============================================================================
 
24
 
 
25
#include "KviKvsVariant.h"
 
26
#include "KviKvsArrayCast.h"
 
27
#include "KviKvsHash.h"
 
28
#include "KviKvsArray.h"
 
29
 
 
30
#include <math.h>
 
31
 
 
32
int KviKvsVariantComparison::compareIntString(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
33
{
 
34
        kvs_real_t dReal;
 
35
 
 
36
        if(pV1->m_pData->m_u.iInt == 0)
 
37
        {
 
38
                if(pV2->m_pData->m_u.pString->isEmpty())
 
39
                        return KviKvsVariantComparison::Equal;
 
40
        }
 
41
 
 
42
        if(pV2->asReal(dReal))
 
43
        {
 
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;
 
49
        }
 
50
 
 
51
        // compare as strings instead
 
52
        QString szString;
 
53
        pV1->asString(szString);
 
54
        return -1 * szString.compare(*(pV2->m_pData->m_u.pString),Qt::CaseInsensitive);
 
55
}
 
56
 
 
57
int KviKvsVariantComparison::compareIntReal(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
58
{
 
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;
 
64
}
 
65
 
 
66
int KviKvsVariantComparison::compareIntBool(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
67
{
 
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;
 
71
}
 
72
 
 
73
int KviKvsVariantComparison::compareIntHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
74
{
 
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;
 
78
}
 
79
 
 
80
int KviKvsVariantComparison::compareIntArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
81
{
 
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;
 
85
}
 
86
 
 
87
int KviKvsVariantComparison::compareIntHObject(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
88
{
 
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;
 
92
}
 
93
 
 
94
int KviKvsVariantComparison::compareRealHObject(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
95
{
 
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;
 
99
}
 
100
 
 
101
int KviKvsVariantComparison::compareRealString(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
102
{
 
103
        kvs_real_t dReal;
 
104
 
 
105
        if(*(pV1->m_pData->m_u.pReal) == 0.0)
 
106
        {
 
107
                if(pV2->m_pData->m_u.pString->isEmpty())
 
108
                        return KviKvsVariantComparison::Equal;
 
109
        }
 
110
 
 
111
        if(pV2->asReal(dReal))
 
112
        {
 
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;
 
118
        }
 
119
 
 
120
        // compare as strings instead
 
121
        QString szString;
 
122
        pV1->asString(szString);
 
123
        return -1 * szString.compare(*(pV2->m_pData->m_u.pString),Qt::CaseInsensitive);
 
124
}
 
125
 
 
126
int KviKvsVariantComparison::compareRealBool(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
127
{
 
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;
 
131
}
 
132
 
 
133
int KviKvsVariantComparison::compareRealHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
134
{
 
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;
 
138
}
 
139
 
 
140
int KviKvsVariantComparison::compareRealArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
141
{
 
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;
 
145
}
 
146
 
 
147
int KviKvsVariantComparison::compareStringHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
148
{
 
149
        if(pV1->m_pData->m_u.pString->isEmpty())
 
150
        {
 
151
                return pV2->m_pData->m_u.pHash->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
 
152
        }
 
153
        return KviKvsVariantComparison::FirstGreater;
 
154
}
 
155
 
 
156
int KviKvsVariantComparison::compareStringArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
157
{
 
158
        if(pV1->m_pData->m_u.pString->isEmpty())
 
159
        {
 
160
                return pV2->m_pData->m_u.pArray->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
 
161
        }
 
162
        return KviKvsVariantComparison::FirstGreater;
 
163
}
 
164
 
 
165
int KviKvsVariantComparison::compareStringHObject(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
166
{
 
167
        kvs_real_t dReal;
 
168
 
 
169
        if(pV2->m_pData->m_u.hObject == (kvs_hobject_t)0)
 
170
        {
 
171
                if(pV1->m_pData->m_u.pString->isEmpty())
 
172
                        return KviKvsVariantComparison::Equal;
 
173
 
 
174
                if(pV1->asReal(dReal))
 
175
                {
 
176
                        if(dReal == 0)
 
177
                                return KviKvsVariantComparison::Equal;
 
178
                }
 
179
        }
 
180
 
 
181
        return KviKvsVariantComparison::FirstGreater;
 
182
}
 
183
 
 
184
int KviKvsVariantComparison::compareBoolString(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
185
{
 
186
        if(pV2->isEqualToNothing())
 
187
                return pV1->m_pData->m_u.bBoolean ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
 
188
        else
 
189
                return pV1->m_pData->m_u.bBoolean ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::FirstGreater;
 
190
}
 
191
 
 
192
int KviKvsVariantComparison::compareBoolHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
193
{
 
194
        if(pV1->m_pData->m_u.bBoolean)
 
195
                return pV2->m_pData->m_u.pHash->isEmpty() ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
 
196
        else
 
197
                return pV2->m_pData->m_u.pHash->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
 
198
}
 
199
 
 
200
int KviKvsVariantComparison::compareBoolArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
201
{
 
202
        if(pV1->m_pData->m_u.bBoolean)
 
203
                return pV2->m_pData->m_u.pArray->isEmpty() ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
 
204
        else
 
205
                return pV2->m_pData->m_u.pArray->isEmpty() ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
 
206
}
 
207
 
 
208
int KviKvsVariantComparison::compareBoolHObject(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
209
{
 
210
        if(pV1->m_pData->m_u.bBoolean)
 
211
                return pV2->m_pData->m_u.hObject == ((kvs_hobject_t)0) ? KviKvsVariantComparison::FirstGreater : KviKvsVariantComparison::Equal;
 
212
        else
 
213
                return pV2->m_pData->m_u.hObject == ((kvs_hobject_t)0) ? KviKvsVariantComparison::Equal : KviKvsVariantComparison::SecondGreater;
 
214
}
 
215
 
 
216
int KviKvsVariantComparison::compareArrayHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
217
{
 
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;
 
223
}
 
224
 
 
225
int KviKvsVariantComparison::compareHObjectHash(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
226
{
 
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;
 
230
}
 
231
 
 
232
int KviKvsVariantComparison::compareHObjectArray(const KviKvsVariant * pV1, const KviKvsVariant * pV2)
 
233
{
 
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;
 
237
}
 
238
 
 
239
 
 
240
KviKvsVariant::KviKvsVariant()
 
241
{
 
242
        m_pData = 0;
 
243
}
 
244
 
 
245
KviKvsVariant::KviKvsVariant(QString * pString, bool bEscape)
 
246
{
 
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;
 
251
        if(bEscape)
 
252
                KviQString::escapeKvs(m_pData->m_u.pString);
 
253
}
 
254
 
 
255
KviKvsVariant::KviKvsVariant(const QString & szString, bool bEscape)
 
256
{
 
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);
 
261
        if(bEscape)
 
262
                KviQString::escapeKvs(m_pData->m_u.pString);
 
263
}
 
264
 
 
265
KviKvsVariant::KviKvsVariant(const char * pcString, bool bEscape)
 
266
{
 
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));
 
271
        if(bEscape)
 
272
                KviQString::escapeKvs(m_pData->m_u.pString);
 
273
}
 
274
 
 
275
KviKvsVariant::KviKvsVariant(KviKvsArray * pArray)
 
276
{
 
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;
 
281
}
 
282
 
 
283
KviKvsVariant::KviKvsVariant(KviKvsHash * pHash)
 
284
{
 
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;
 
289
}
 
290
 
 
291
KviKvsVariant::KviKvsVariant(kvs_real_t * pReal)
 
292
{
 
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;
 
297
}
 
298
 
 
299
KviKvsVariant::KviKvsVariant(kvs_real_t dReal)
 
300
{
 
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;
 
306
}
 
307
 
 
308
KviKvsVariant::KviKvsVariant(bool bBoolean)
 
309
{
 
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;
 
314
}
 
315
 
 
316
KviKvsVariant::KviKvsVariant(kvs_int_t iInt, bool)
 
317
{
 
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;
 
322
}
 
323
 
 
324
KviKvsVariant::KviKvsVariant(kvs_hobject_t hObject)
 
325
{
 
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;
 
330
}
 
331
 
 
332
KviKvsVariant::KviKvsVariant(const KviKvsVariant & variant)
 
333
{
 
334
        m_pData = variant.m_pData;
 
335
        if(m_pData)
 
336
                m_pData->m_uRefs++;
 
337
}
 
338
 
 
339
#define DELETE_VARIANT_CONTENTS \
 
340
        switch(m_pData->m_eType) \
 
341
        { \
 
342
                case KviKvsVariantData::Array: \
 
343
                        delete m_pData->m_u.pArray; \
 
344
                break; \
 
345
                case KviKvsVariantData::Hash: \
 
346
                        delete m_pData->m_u.pHash; \
 
347
                break; \
 
348
                case KviKvsVariantData::String: \
 
349
                        delete m_pData->m_u.pString; \
 
350
                break; \
 
351
                case KviKvsVariantData::Real: \
 
352
                        delete m_pData->m_u.pReal; \
 
353
                break; \
 
354
                default: /* make gcc happy */ break; \
 
355
        }
 
356
 
 
357
#define DETACH_CONTENTS \
 
358
        if(m_pData) \
 
359
        { \
 
360
                if(m_pData->m_uRefs <= 1) \
 
361
                { \
 
362
                        DELETE_VARIANT_CONTENTS \
 
363
                        delete m_pData; \
 
364
                } else { \
 
365
                        m_pData->m_uRefs--; \
 
366
                } \
 
367
        }
 
368
 
 
369
#define RENEW_VARIANT_DATA \
 
370
        if(m_pData) \
 
371
        { \
 
372
                if(m_pData->m_uRefs > 1) \
 
373
                { \
 
374
                        m_pData->m_uRefs--; \
 
375
                        m_pData = new KviKvsVariantData; \
 
376
                        m_pData->m_uRefs = 1; \
 
377
                } else { \
 
378
                        DELETE_VARIANT_CONTENTS \
 
379
                } \
 
380
        } else { \
 
381
                m_pData = new KviKvsVariantData; \
 
382
                m_pData->m_uRefs = 1; \
 
383
        }
 
384
 
 
385
KviKvsVariant::~KviKvsVariant()
 
386
{
 
387
        DETACH_CONTENTS
 
388
}
 
389
 
 
390
void KviKvsVariant::setString(QString * pString)
 
391
{
 
392
        RENEW_VARIANT_DATA
 
393
        m_pData->m_eType = KviKvsVariantData::String;
 
394
        m_pData->m_u.pString = pString;
 
395
}
 
396
 
 
397
void KviKvsVariant::setString(const QString & szString)
 
398
{
 
399
        RENEW_VARIANT_DATA
 
400
        m_pData->m_eType = KviKvsVariantData::String;
 
401
        m_pData->m_u.pString = new QString(szString);
 
402
}
 
403
 
 
404
void KviKvsVariant::setReal(kvs_real_t dReal)
 
405
{
 
406
        RENEW_VARIANT_DATA
 
407
        m_pData->m_eType = KviKvsVariantData::Real;
 
408
        m_pData->m_u.pReal = new kvs_real_t;
 
409
        *(m_pData->m_u.pReal) = dReal;
 
410
}
 
411
 
 
412
void KviKvsVariant::setHObject(kvs_hobject_t hObject)
 
413
{
 
414
        RENEW_VARIANT_DATA
 
415
        m_pData->m_eType = KviKvsVariantData::HObject;
 
416
        m_pData->m_u.hObject = hObject;
 
417
}
 
418
 
 
419
void KviKvsVariant::setBoolean(bool bBoolean)
 
420
{
 
421
        RENEW_VARIANT_DATA
 
422
        m_pData->m_eType = KviKvsVariantData::Boolean;
 
423
        m_pData->m_u.bBoolean = bBoolean;
 
424
}
 
425
 
 
426
void KviKvsVariant::setReal(kvs_real_t * pReal)
 
427
{
 
428
        RENEW_VARIANT_DATA
 
429
        m_pData->m_eType = KviKvsVariantData::Real;
 
430
        m_pData->m_u.pReal = pReal;
 
431
}
 
432
 
 
433
void KviKvsVariant::setInteger(kvs_int_t iInt)
 
434
{
 
435
        RENEW_VARIANT_DATA
 
436
        m_pData->m_eType = KviKvsVariantData::Integer;
 
437
        m_pData->m_u.iInt = iInt;
 
438
}
 
439
 
 
440
void KviKvsVariant::setArray(KviKvsArray * pArray)
 
441
{
 
442
        RENEW_VARIANT_DATA
 
443
        m_pData->m_eType = KviKvsVariantData::Array;
 
444
        m_pData->m_u.pArray = pArray;
 
445
}
 
446
 
 
447
void KviKvsVariant::setHash(KviKvsHash * pHash)
 
448
{
 
449
        RENEW_VARIANT_DATA
 
450
        m_pData->m_eType = KviKvsVariantData::Hash;
 
451
        m_pData->m_u.pHash = pHash;
 
452
}
 
453
 
 
454
void KviKvsVariant::setNothing()
 
455
{
 
456
        if(m_pData)
 
457
        {
 
458
                if(m_pData->m_uRefs <= 1)
 
459
                {
 
460
                        DELETE_VARIANT_CONTENTS
 
461
                        delete m_pData;
 
462
                } else {
 
463
                        // just detach
 
464
                        m_pData->m_uRefs--;
 
465
                }
 
466
                m_pData = 0;
 
467
        }
 
468
}
 
469
 
 
470
bool KviKvsVariant::isEmpty() const
 
471
{
 
472
        if(!m_pData)
 
473
                return true;
 
474
        switch(m_pData->m_eType)
 
475
        {
 
476
                case KviKvsVariantData::String:
 
477
                        return m_pData->m_u.pString->isEmpty();
 
478
                break;
 
479
                case KviKvsVariantData::Array:
 
480
                        return m_pData->m_u.pArray->isEmpty();
 
481
                break;
 
482
                case KviKvsVariantData::Hash:
 
483
                        return m_pData->m_u.pHash->isEmpty();
 
484
                break;
 
485
                case KviKvsVariantData::HObject:
 
486
                        return m_pData->m_u.hObject == 0;
 
487
                break;
 
488
                default: /* make gcc happy */ break;
 
489
        }
 
490
        return false;
 
491
}
 
492
 
 
493
bool KviKvsVariant::asBoolean() const
 
494
{
 
495
        if(!m_pData)
 
496
                return false;
 
497
        switch(m_pData->m_eType)
 
498
        {
 
499
                case KviKvsVariantData::Boolean:
 
500
                        return m_pData->m_u.bBoolean;
 
501
                break;
 
502
                case KviKvsVariantData::String:
 
503
                {
 
504
                        if(m_pData->m_u.pString->isEmpty())
 
505
                                return false;
 
506
                        
 
507
                        // check integer or real values
 
508
                        bool bOk;
 
509
                        kvs_int_t iVal = (kvs_int_t)KviQString::toI64(*(m_pData->m_u.pString),&bOk);
 
510
                        if(bOk)
 
511
                                return iVal;
 
512
                        kvs_real_t dVal = m_pData->m_u.pString->toDouble(&bOk);
 
513
                        if(bOk)
 
514
                                return (dVal != 0.0);
 
515
                        // non number, non empty
 
516
                        return true;
 
517
                }
 
518
                break;
 
519
                case KviKvsVariantData::Integer:
 
520
                        return m_pData->m_u.iInt;
 
521
                break;
 
522
                case KviKvsVariantData::Real:
 
523
                        return *(m_pData->m_u.pReal) != 0.0;
 
524
                break;
 
525
                case KviKvsVariantData::Array:
 
526
                        return !(m_pData->m_u.pArray->isEmpty());
 
527
                break;
 
528
                case KviKvsVariantData::Hash:
 
529
                        return !(m_pData->m_u.pHash->isEmpty());
 
530
                break;
 
531
                case KviKvsVariantData::HObject:
 
532
                        return m_pData->m_u.hObject;
 
533
                break;
 
534
                default: /* make gcc happy */ break;
 
535
        }
 
536
        qDebug("WARNING: invalid variant type %d in KviKvsVariant::asBoolean()",m_pData->m_eType);
 
537
        return false;
 
538
}
 
539
 
 
540
bool KviKvsVariant::asHObject(kvs_hobject_t & hObject) const
 
541
{
 
542
        if(!m_pData)
 
543
        {
 
544
                // nothing evaluates to a null object
 
545
                hObject = 0;
 
546
                return true;
 
547
        }
 
548
        switch(m_pData->m_eType)
 
549
        {
 
550
                case KviKvsVariantData::HObject:
 
551
                        hObject = m_pData->m_u.hObject;
 
552
                        return true;
 
553
                break;
 
554
                case KviKvsVariantData::Integer:
 
555
                        if(m_pData->m_u.iInt == 0)
 
556
                        {
 
557
                                hObject = 0;
 
558
                                return true;
 
559
                        }
 
560
                        return false;
 
561
                break;
 
562
                case KviKvsVariantData::String:
 
563
                        if(*(m_pData->m_u.pString) == "0")
 
564
                        {
 
565
                                hObject = 0;
 
566
                                return true;
 
567
                        }
 
568
                        return false;
 
569
                break;
 
570
                case KviKvsVariantData::Boolean:
 
571
                        if(!(m_pData->m_u.bBoolean))
 
572
                        {
 
573
                                hObject = 0;
 
574
                                return true;
 
575
                        }
 
576
                default: /* make gcc happy */ break;
 
577
        }
 
578
        return false;
 
579
}
 
580
 
 
581
bool KviKvsVariant::asNumber(KviKvsNumber & number) const
 
582
{
 
583
        if(!m_pData)
 
584
                return false;
 
585
 
 
586
        if(isInteger())
 
587
        {
 
588
                number.m_u.iInt = m_pData->m_u.iInt;
 
589
                number.m_type = KviKvsNumber::Integer;
 
590
                return true;
 
591
        }
 
592
 
 
593
        if(isReal())
 
594
        {
 
595
                number.m_u.dReal = *(m_pData->m_u.pReal);
 
596
                number.m_type = KviKvsNumber::Real;
 
597
                return true;
 
598
        }
 
599
 
 
600
        if(asInteger(number.m_u.iInt))
 
601
        {
 
602
                number.m_type = KviKvsNumber::Integer;
 
603
                return true;
 
604
        }
 
605
 
 
606
        if(asReal(number.m_u.dReal))
 
607
        {
 
608
                number.m_type = KviKvsNumber::Real;
 
609
                return true;
 
610
        }
 
611
        return false;
 
612
}
 
613
 
 
614
void KviKvsVariant::castToNumber(KviKvsNumber & number) const
 
615
{
 
616
        if(!m_pData)
 
617
        {
 
618
                number.m_u.iInt = 0;
 
619
                number.m_type = KviKvsNumber::Integer;
 
620
                return;
 
621
        }
 
622
 
 
623
        if(isInteger())
 
624
        {
 
625
                number.m_u.iInt = m_pData->m_u.iInt;
 
626
                number.m_type = KviKvsNumber::Integer;
 
627
                return;
 
628
        }
 
629
 
 
630
        if(isReal())
 
631
        {
 
632
                number.m_u.dReal = *(m_pData->m_u.pReal);
 
633
                number.m_type = KviKvsNumber::Real;
 
634
                return;
 
635
        }
 
636
 
 
637
        if(asInteger(number.m_u.iInt))
 
638
        {
 
639
                number.m_type = KviKvsNumber::Integer;
 
640
                return;
 
641
        }
 
642
 
 
643
        if(asReal(number.m_u.dReal))
 
644
        {
 
645
                number.m_type = KviKvsNumber::Real;
 
646
                return;
 
647
        }
 
648
        castToInteger(number.m_u.iInt);
 
649
        number.m_type = KviKvsNumber::Integer;
 
650
}
 
651
 
 
652
void KviKvsVariant::castToArray(KviKvsArrayCast * pCast) const
 
653
{
 
654
        if(!m_pData)
 
655
        {
 
656
                pCast->set(new KviKvsArray(),true);
 
657
                return;
 
658
        }
 
659
 
 
660
        switch(m_pData->m_eType)
 
661
        {
 
662
                case KviKvsVariantData::Array:
 
663
                        pCast->set(m_pData->m_u.pArray,false);
 
664
                break;
 
665
                case KviKvsVariantData::Hash:
 
666
                {
 
667
                        KviPointerHashTableIterator<QString,KviKvsVariant> it(*(m_pData->m_u.pHash->dict()));
 
668
                        KviKvsArray * pArray = new KviKvsArray();
 
669
                        kvs_int_t idx = 0;
 
670
                        while(KviKvsVariant * pVariant = it.current())
 
671
                        {
 
672
                                pArray->set(idx,new KviKvsVariant(*pVariant));
 
673
                                ++it;
 
674
                                idx++;
 
675
                        }
 
676
                        pCast->set(pArray,true);
 
677
                }
 
678
                break;
 
679
                default:
 
680
                {
 
681
                        // other scalars
 
682
                        KviKvsArray * pArray = new KviKvsArray();
 
683
                        pArray->set(0,new KviKvsVariant(*this));
 
684
                        pCast->set(pArray,true);
 
685
                }
 
686
                break;
 
687
        }
 
688
}
 
689
 
 
690
void KviKvsVariant::convertToArray()
 
691
{
 
692
        if(!m_pData)
 
693
        {
 
694
                setArray(new KviKvsArray());
 
695
                return;
 
696
        }
 
697
 
 
698
        switch(m_pData->m_eType)
 
699
        {
 
700
                case KviKvsVariantData::Array:
 
701
                        return;
 
702
                break;
 
703
                case KviKvsVariantData::Hash:
 
704
                {
 
705
                        KviPointerHashTableIterator<QString,KviKvsVariant> it(*(m_pData->m_u.pHash->dict()));
 
706
                        KviKvsArray * pArray = new KviKvsArray();
 
707
                        kvs_int_t idx = 0;
 
708
                        while(KviKvsVariant * pVariant = it.current())
 
709
                        {
 
710
                                pArray->set(idx,new KviKvsVariant(*pVariant));
 
711
                                ++it;
 
712
                                idx++;
 
713
                        }
 
714
                        setArray(pArray);
 
715
                }
 
716
                break;
 
717
                default:
 
718
                {
 
719
                        // other scalars
 
720
                        KviKvsArray * pArray = new KviKvsArray();
 
721
                        pArray->set(0,new KviKvsVariant(*this));
 
722
                        setArray(pArray);
 
723
                }
 
724
                break;
 
725
        }
 
726
}
 
727
 
 
728
bool KviKvsVariant::asInteger(kvs_int_t & iVal) const
 
729
{
 
730
        if(!m_pData)
 
731
                return false;
 
732
        switch(m_pData->m_eType)
 
733
        {
 
734
                case KviKvsVariantData::Integer:
 
735
                        iVal = m_pData->m_u.iInt;
 
736
                        return true;
 
737
                break;
 
738
                case KviKvsVariantData::String:
 
739
                {
 
740
                        bool bOk;
 
741
                        iVal = (kvs_int_t)KviQString::toI64(*(m_pData->m_u.pString),&bOk);
 
742
                        return bOk;
 
743
                }
 
744
                break;
 
745
                case KviKvsVariantData::Real:
 
746
                        // FIXME: this truncates the value!
 
747
                        iVal = (kvs_int_t)*(m_pData->m_u.pReal);
 
748
                        return true;
 
749
                break;
 
750
                case KviKvsVariantData::Boolean:
 
751
                        iVal = m_pData->m_u.bBoolean ? 1 : 0;
 
752
                        return true;
 
753
                break;
 
754
                //case KviKvsVariantData::HObject: <-- light casts from objects to integer are not valid
 
755
                //      iVal = m_pData->m_u.hObject ? 1 : 0;
 
756
                //      return true;
 
757
                //break;
 
758
                default: /* make gcc happy */
 
759
                break;
 
760
        }
 
761
        return false;
 
762
}
 
763
 
 
764
void KviKvsVariant::castToInteger(kvs_int_t & iVal) const
 
765
{
 
766
        if(!m_pData)
 
767
        {
 
768
                iVal = 0;
 
769
                return;
 
770
        }
 
771
        switch(m_pData->m_eType)
 
772
        {
 
773
                case KviKvsVariantData::Integer:
 
774
                        iVal = m_pData->m_u.iInt;
 
775
                break;
 
776
                case KviKvsVariantData::Boolean:
 
777
                        iVal = m_pData->m_u.bBoolean ? 1 : 0;
 
778
                break;
 
779
                case KviKvsVariantData::HObject:
 
780
                        iVal = m_pData->m_u.hObject ? 1 : 0;
 
781
                break;
 
782
                case KviKvsVariantData::String:
 
783
                {
 
784
                        bool bOk;
 
785
                        iVal = (kvs_int_t)KviQString::toI64(*(m_pData->m_u.pString),&bOk);
 
786
                        if(bOk)
 
787
                                return;
 
788
                        iVal = m_pData->m_u.pString->length();
 
789
                }
 
790
                break;
 
791
                case KviKvsVariantData::Real:
 
792
                        // FIXME: this truncates the value!
 
793
                        iVal = (kvs_int_t)*(m_pData->m_u.pReal);
 
794
                break;
 
795
                case KviKvsVariantData::Array:
 
796
                        iVal = m_pData->m_u.pArray->size();
 
797
                break;
 
798
                case KviKvsVariantData::Hash:
 
799
                        iVal = m_pData->m_u.pHash->size();
 
800
                break;
 
801
                default: /* make gcc happy */
 
802
                        iVal = 0;
 
803
                break;
 
804
        }
 
805
}
 
806
 
 
807
bool KviKvsVariant::asReal(kvs_real_t & dVal) const
 
808
{
 
809
        if(!m_pData)
 
810
                return false;
 
811
        switch(m_pData->m_eType)
 
812
        {
 
813
                case KviKvsVariantData::Integer:
 
814
                        dVal = m_pData->m_u.iInt;
 
815
                        return true;
 
816
                break;
 
817
                case KviKvsVariantData::String:
 
818
                {
 
819
                        bool bOk;
 
820
                        dVal = m_pData->m_u.pString->toDouble(&bOk);
 
821
                        return bOk;
 
822
                }
 
823
                break;
 
824
                case KviKvsVariantData::Real:
 
825
                        dVal = *(m_pData->m_u.pReal);
 
826
                        return true;
 
827
                break;
 
828
                case KviKvsVariantData::Boolean:
 
829
                        dVal = m_pData->m_u.bBoolean ? 1.0 : 0.0;
 
830
                        return true;
 
831
                break;
 
832
                default: /* by default we make gcc happy */ break;
 
833
        }
 
834
        return false;
 
835
}
 
836
 
 
837
void KviKvsVariant::asString(QString & szBuffer) const
 
838
{
 
839
        if(!m_pData)
 
840
        {
 
841
                szBuffer = QString();
 
842
                return;
 
843
        }
 
844
        switch(m_pData->m_eType)
 
845
        {
 
846
                case KviKvsVariantData::String:
 
847
                        szBuffer = *(m_pData->m_u.pString);
 
848
                break;
 
849
                case KviKvsVariantData::Array:
 
850
                        szBuffer = QString(); m_pData->m_u.pArray->appendAsString(szBuffer);
 
851
                break;
 
852
                case KviKvsVariantData::Hash:
 
853
                        szBuffer = QString(); m_pData->m_u.pHash->appendAsString(szBuffer);
 
854
                break;
 
855
                case KviKvsVariantData::Integer:
 
856
                        szBuffer.setNum(m_pData->m_u.iInt);
 
857
                break;
 
858
                case KviKvsVariantData::Real:
 
859
                        szBuffer.setNum(*(m_pData->m_u.pReal));
 
860
                break;
 
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);
 
866
                        else
 
867
                                szBuffer = "null-object";
 
868
                break;
 
869
                default: /* make gcc happy */ break;
 
870
        }
 
871
}
 
872
 
 
873
void KviKvsVariant::appendAsString(QString & szBuffer) const
 
874
{
 
875
        if(!m_pData)
 
876
                return;
 
877
        switch(m_pData->m_eType)
 
878
        {
 
879
                case KviKvsVariantData::String:
 
880
                        szBuffer.append(*(m_pData->m_u.pString));
 
881
                break;
 
882
                case KviKvsVariantData::Array:
 
883
                        m_pData->m_u.pArray->appendAsString(szBuffer);
 
884
                break;
 
885
                case KviKvsVariantData::Hash:
 
886
                        m_pData->m_u.pHash->appendAsString(szBuffer);
 
887
                break;
 
888
                case KviKvsVariantData::Integer:
 
889
                        KviQString::appendNumber(szBuffer,m_pData->m_u.iInt);
 
890
                break;
 
891
                case KviKvsVariantData::Real:
 
892
                        KviQString::appendNumber(szBuffer,*(m_pData->m_u.pReal));
 
893
                break;
 
894
                case KviKvsVariantData::Boolean:
 
895
                        KviQString::appendNumber(szBuffer,m_pData->m_u.bBoolean ? 1 : 0);
 
896
                break;
 
897
                case KviKvsVariantData::HObject:
 
898
                        szBuffer.append(m_pData->m_u.hObject ? "object" : "null-object");
 
899
                break;
 
900
                default: /* make gcc happy */ break;
 
901
        }
 
902
}
 
903
 
 
904
void KviKvsVariant::dump(const char * pcPrefix) const
 
905
{
 
906
        if(!m_pData)
 
907
        {
 
908
                qDebug("%s Nothing [this=0x%lx]",pcPrefix,(long unsigned int)this);
 
909
                return;
 
910
        }
 
911
        switch(m_pData->m_eType)
 
912
        {
 
913
                case KviKvsVariantData::String:
 
914
                        qDebug("%s String(%s) [this=0x%lx]",pcPrefix,m_pData->m_u.pString->toUtf8().data(),(long unsigned int)this);
 
915
                break;
 
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);
 
918
                break;
 
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);
 
921
                break;
 
922
                case KviKvsVariantData::Integer:
 
923
                        qDebug("%s Integer(%d) [this=0x%lx]",pcPrefix,(int) m_pData->m_u.iInt,(long unsigned int)this);
 
924
                break;
 
925
                case KviKvsVariantData::Real:
 
926
                        qDebug("%s Real(%f) [this=0x%lx]",pcPrefix,*(m_pData->m_u.pReal),(long unsigned int)this);
 
927
                break;
 
928
                case KviKvsVariantData::Boolean:
 
929
                        qDebug("%s Boolean(%s) [this=0x%lx]",pcPrefix,m_pData->m_u.bBoolean ? "true" : "false",(long unsigned int)this);
 
930
                break;
 
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);
 
933
                break;
 
934
                default: /* make gcc happy */ break;
 
935
        }
 
936
}
 
937
 
 
938
void KviKvsVariant::copyFrom(const KviKvsVariant * pVariant)
 
939
{
 
940
        DETACH_CONTENTS
 
941
        m_pData = pVariant->m_pData;
 
942
        if(m_pData)
 
943
                m_pData->m_uRefs++;
 
944
}
 
945
 
 
946
void KviKvsVariant::copyFrom(const KviKvsVariant & variant)
 
947
{
 
948
        DETACH_CONTENTS
 
949
        m_pData = variant.m_pData;
 
950
        if(m_pData)
 
951
                m_pData->m_uRefs++;
 
952
}
 
953
 
 
954
void KviKvsVariant::takeFrom(KviKvsVariant * pVariant)
 
955
{
 
956
        DETACH_CONTENTS
 
957
        m_pData = pVariant->m_pData;
 
958
        pVariant->m_pData = 0;
 
959
}
 
960
 
 
961
void KviKvsVariant::takeFrom(KviKvsVariant & variant)
 
962
{
 
963
        DETACH_CONTENTS
 
964
        m_pData = variant.m_pData;
 
965
        variant.m_pData = 0;
 
966
}
 
967
 
 
968
void KviKvsVariant::getTypeName(QString & szBuffer) const
 
969
{
 
970
        if(!m_pData)
 
971
        {
 
972
                szBuffer = "nothing";
 
973
                return;
 
974
        }
 
975
        switch(m_pData->m_eType)
 
976
        {
 
977
                case KviKvsVariantData::String:
 
978
                        szBuffer = "string";
 
979
                break;
 
980
                case KviKvsVariantData::Hash:
 
981
                        szBuffer = "hash";
 
982
                break;
 
983
                case KviKvsVariantData::Array:
 
984
                        szBuffer = "array";
 
985
                break;
 
986
                case KviKvsVariantData::Real:
 
987
                        szBuffer = "real"; 
 
988
                break;
 
989
                case KviKvsVariantData::Integer:
 
990
                        szBuffer = "integer";
 
991
                break;
 
992
                case KviKvsVariantData::Boolean:
 
993
                        szBuffer = "boolean";
 
994
                break;
 
995
                case KviKvsVariantData::HObject:
 
996
                        szBuffer = "hobject";
 
997
                break;
 
998
                default:
 
999
                        szBuffer = "internal_error";
 
1000
                break;
 
1001
        }
 
1002
}
 
1003
 
 
1004
bool KviKvsVariant::isEqualToNothing() const
 
1005
{
 
1006
        if(!m_pData)
 
1007
                return true;
 
1008
        switch(m_pData->m_eType)
 
1009
        {
 
1010
                case KviKvsVariantData::HObject:
 
1011
                        return (m_pData->m_u.hObject == (kvs_hobject_t)0);
 
1012
                break;
 
1013
                case KviKvsVariantData::Integer:
 
1014
                        return (m_pData->m_u.iInt == 0);
 
1015
                break;
 
1016
                case KviKvsVariantData::Real:
 
1017
                        return (*(m_pData->m_u.pReal) == 0.0);
 
1018
                break;
 
1019
                case KviKvsVariantData::String:
 
1020
                {
 
1021
                        if(m_pData->m_u.pString->isEmpty())
 
1022
                                return true;
 
1023
                        kvs_real_t dReal;
 
1024
                        if(asReal(dReal))
 
1025
                                return dReal == 0.0;
 
1026
                        return false;
 
1027
                }
 
1028
                break;
 
1029
                case KviKvsVariantData::Boolean:
 
1030
                        return !m_pData->m_u.bBoolean;
 
1031
                break;
 
1032
                case KviKvsVariantData::Hash:
 
1033
                        return m_pData->m_u.pHash->isEmpty();
 
1034
                break;
 
1035
                case KviKvsVariantData::Array:
 
1036
                        return m_pData->m_u.pArray->isEmpty();
 
1037
                break;
 
1038
                default:
 
1039
                break;
 
1040
        }
 
1041
 
 
1042
        return false;
 
1043
}
 
1044
 
 
1045
#define CMP_THISGREATER -1
 
1046
#define CMP_EQUAL 0
 
1047
#define CMP_OTHERGREATER 1
 
1048
 
 
1049
int KviKvsVariant::compare(const KviKvsVariant * pOther, bool bPreferNumeric) const
 
1050
{
 
1051
        if(!pOther)
 
1052
                return isEqualToNothing() ? CMP_EQUAL : CMP_THISGREATER;
 
1053
        if(!pOther->m_pData)
 
1054
                return isEqualToNothing() ? CMP_EQUAL : CMP_THISGREATER;
 
1055
        if(!m_pData)
 
1056
                return pOther->isEqualToNothing() ? CMP_EQUAL : CMP_OTHERGREATER;
 
1057
 
 
1058
        switch(m_pData->m_eType)
 
1059
        {
 
1060
                case KviKvsVariantData::HObject:
 
1061
                        switch(pOther->m_pData->m_eType)
 
1062
                        {
 
1063
                                case KviKvsVariantData::HObject:
 
1064
                                        if(m_pData->m_u.hObject == pOther->m_pData->m_u.hObject)
 
1065
                                                return CMP_EQUAL;
 
1066
                                        if(m_pData->m_u.hObject == ((kvs_hobject_t)0))
 
1067
                                                return CMP_OTHERGREATER;
 
1068
                                        return CMP_THISGREATER;
 
1069
                                break;
 
1070
                                case KviKvsVariantData::Integer:
 
1071
                                        return -1 * KviKvsVariantComparison::compareIntHObject(pOther,this);
 
1072
                                break;
 
1073
                                case KviKvsVariantData::Real:
 
1074
                                        return -1 * KviKvsVariantComparison::compareRealHObject(pOther,this);
 
1075
                                break;
 
1076
                                case KviKvsVariantData::String:
 
1077
                                        return -1 * KviKvsVariantComparison::compareStringHObject(pOther,this);
 
1078
                                break;
 
1079
                                case KviKvsVariantData::Boolean:
 
1080
                                        return -1 * KviKvsVariantComparison::compareBoolHObject(pOther,this);
 
1081
                                break;
 
1082
                                case KviKvsVariantData::Hash:
 
1083
                                        return KviKvsVariantComparison::compareHObjectHash(this,pOther);
 
1084
                                break;
 
1085
                                case KviKvsVariantData::Array:
 
1086
                                        return KviKvsVariantComparison::compareHObjectArray(this,pOther);
 
1087
                                break;
 
1088
                                default: // just make gcc happy
 
1089
                                break;
 
1090
                        }
 
1091
                break;
 
1092
                case KviKvsVariantData::Integer:
 
1093
                        switch(pOther->m_pData->m_eType)
 
1094
                        {
 
1095
                                case KviKvsVariantData::HObject:
 
1096
                                        return KviKvsVariantComparison::compareIntHObject(this,pOther);
 
1097
                                break;
 
1098
                                case KviKvsVariantData::Integer:
 
1099
                                        if(m_pData->m_u.iInt == pOther->m_pData->m_u.iInt)
 
1100
                                                return CMP_EQUAL;
 
1101
                                        if(m_pData->m_u.iInt > pOther->m_pData->m_u.iInt)
 
1102
                                                return CMP_THISGREATER;
 
1103
                                        return CMP_OTHERGREATER;
 
1104
                                break;
 
1105
                                case KviKvsVariantData::Real:
 
1106
                                        return KviKvsVariantComparison::compareIntReal(this,pOther);
 
1107
                                break;
 
1108
                                case KviKvsVariantData::String:
 
1109
                                        return KviKvsVariantComparison::compareIntString(this,pOther);
 
1110
                                break;
 
1111
                                case KviKvsVariantData::Boolean:
 
1112
                                        return KviKvsVariantComparison::compareIntBool(this,pOther);
 
1113
                                break;
 
1114
                                case KviKvsVariantData::Hash:
 
1115
                                        return KviKvsVariantComparison::compareIntHash(this,pOther);
 
1116
                                break;
 
1117
                                case KviKvsVariantData::Array:
 
1118
                                        return KviKvsVariantComparison::compareIntArray(this,pOther);
 
1119
                                break;
 
1120
                                default: // just make gcc happy
 
1121
                                break;
 
1122
                        }
 
1123
                break;
 
1124
                case KviKvsVariantData::Real:
 
1125
                        switch(pOther->m_pData->m_eType)
 
1126
                        {
 
1127
                                case KviKvsVariantData::HObject:
 
1128
                                        return KviKvsVariantComparison::compareRealHObject(this,pOther);
 
1129
                                break;
 
1130
                                case KviKvsVariantData::Integer:
 
1131
                                        return -1 * KviKvsVariantComparison::compareIntReal(pOther,this);
 
1132
                                break;
 
1133
                                case KviKvsVariantData::Real:
 
1134
                                        if(*(m_pData->m_u.pReal) == *(pOther->m_pData->m_u.pReal))
 
1135
                                                return CMP_EQUAL;
 
1136
                                        if(*(m_pData->m_u.pReal) > *(pOther->m_pData->m_u.pReal))
 
1137
                                                return CMP_THISGREATER;
 
1138
                                        return CMP_OTHERGREATER;
 
1139
                                break;
 
1140
                                case KviKvsVariantData::String:
 
1141
                                        return KviKvsVariantComparison::compareRealString(this,pOther);
 
1142
                                break;
 
1143
                                case KviKvsVariantData::Boolean:
 
1144
                                        return KviKvsVariantComparison::compareRealBool(this,pOther);
 
1145
                                break;
 
1146
                                case KviKvsVariantData::Hash:
 
1147
                                        return KviKvsVariantComparison::compareRealHash(this,pOther);
 
1148
                                break;
 
1149
                                case KviKvsVariantData::Array:
 
1150
                                        return KviKvsVariantComparison::compareRealArray(this,pOther);
 
1151
                                break;
 
1152
                                default: // just make gcc happy
 
1153
                                break;
 
1154
                        }
 
1155
                break;
 
1156
                case KviKvsVariantData::String:
 
1157
                        switch(pOther->m_pData->m_eType)
 
1158
                        {
 
1159
                                case KviKvsVariantData::String:
 
1160
                                        if(bPreferNumeric)
 
1161
                                        {
 
1162
                                                // prefer numeric comparison
 
1163
                                                double dReal1;
 
1164
                                                double dReal2;
 
1165
                                                if(asReal(dReal1))
 
1166
                                                {
 
1167
                                                        if(pOther->asReal(dReal2))
 
1168
                                                        {
 
1169
                                                                if(dReal1 == dReal2)
 
1170
                                                                        return CMP_EQUAL;
 
1171
                                                                if(dReal1 > dReal2)
 
1172
                                                                        return CMP_THISGREATER;
 
1173
                                                                return CMP_OTHERGREATER;
 
1174
                                                        }
 
1175
                                                }
 
1176
                                        }
 
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);
 
1184
                                break;
 
1185
                                case KviKvsVariantData::Hash:
 
1186
                                        return KviKvsVariantComparison::compareStringHash(this,pOther);
 
1187
                                break;
 
1188
                                case KviKvsVariantData::Array:
 
1189
                                        return KviKvsVariantComparison::compareStringArray(this,pOther);
 
1190
                                break;
 
1191
                                case KviKvsVariantData::HObject:
 
1192
                                        return KviKvsVariantComparison::compareStringHObject(this,pOther);
 
1193
                                break;
 
1194
                                default:
 
1195
                                break;
 
1196
                        }
 
1197
                break;
 
1198
                case KviKvsVariantData::Hash:
 
1199
                        switch(pOther->m_pData->m_eType)
 
1200
                        {
 
1201
                                case KviKvsVariantData::String:
 
1202
                                        return -1 * KviKvsVariantComparison::compareStringHash(pOther,this);
 
1203
                                case KviKvsVariantData::Real:
 
1204
                                        return -1 * KviKvsVariantComparison::compareRealHash(pOther,this);
 
1205
                                break;
 
1206
                                case KviKvsVariantData::Integer:
 
1207
                                        return -1 * KviKvsVariantComparison::compareIntHash(pOther,this);
 
1208
                                break;
 
1209
                                case KviKvsVariantData::Boolean:
 
1210
                                        return -1 * KviKvsVariantComparison::compareBoolHash(pOther,this);
 
1211
                                break;
 
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())
 
1216
                                                return CMP_EQUAL;
 
1217
                                        return CMP_OTHERGREATER;
 
1218
                                break;
 
1219
                                case KviKvsVariantData::Array:
 
1220
                                        return -1 * KviKvsVariantComparison::compareArrayHash(pOther,this);
 
1221
                                break;
 
1222
                                case KviKvsVariantData::HObject:
 
1223
                                        return -1 * KviKvsVariantComparison::compareHObjectHash(pOther,this);
 
1224
                                break;
 
1225
                                default:
 
1226
                                break;
 
1227
                        }
 
1228
                break;
 
1229
                case KviKvsVariantData::Array:
 
1230
                        switch(pOther->m_pData->m_eType)
 
1231
                        {
 
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);
 
1240
                                break;
 
1241
                                case KviKvsVariantData::Hash:
 
1242
                                        return KviKvsVariantComparison::compareArrayHash(this,pOther);
 
1243
                                break;
 
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())
 
1248
                                                return CMP_EQUAL;
 
1249
                                        return CMP_OTHERGREATER;
 
1250
                                break;
 
1251
                                case KviKvsVariantData::HObject:
 
1252
                                        return -1 * KviKvsVariantComparison::compareHObjectArray(pOther,this);
 
1253
                                break;
 
1254
                                default:
 
1255
                                break;
 
1256
                        }
 
1257
                break;
 
1258
                case KviKvsVariantData::Boolean:
 
1259
                        switch(pOther->m_pData->m_eType)
 
1260
                        {
 
1261
                                case KviKvsVariantData::String:
 
1262
                                        return KviKvsVariantComparison::compareBoolString(this,pOther);
 
1263
                                break;
 
1264
                                case KviKvsVariantData::Real:
 
1265
                                        return -1 * KviKvsVariantComparison::compareRealBool(pOther,this);
 
1266
                                break;
 
1267
                                case KviKvsVariantData::Integer:
 
1268
                                        return -1 * KviKvsVariantComparison::compareIntBool(pOther,this);
 
1269
                                break;
 
1270
                                case KviKvsVariantData::Boolean:
 
1271
                                        if(m_pData->m_u.bBoolean == pOther->m_pData->m_u.bBoolean)
 
1272
                                                return CMP_EQUAL;
 
1273
                                        if(m_pData->m_u.bBoolean)
 
1274
                                                return CMP_THISGREATER;
 
1275
                                        return CMP_OTHERGREATER;
 
1276
                                break;
 
1277
                                case KviKvsVariantData::Hash:
 
1278
                                        return KviKvsVariantComparison::compareBoolHash(this,pOther);
 
1279
                                break;
 
1280
                                case KviKvsVariantData::Array:
 
1281
                                        return KviKvsVariantComparison::compareBoolArray(this,pOther);
 
1282
                                break;
 
1283
                                case KviKvsVariantData::HObject:
 
1284
                                        return KviKvsVariantComparison::compareBoolHObject(this,pOther);
 
1285
                                break;
 
1286
                                default:
 
1287
                                break;
 
1288
                        }
 
1289
                break;
 
1290
                default: // should never happen anyway
 
1291
                break;
 
1292
        }
 
1293
 
 
1294
        return CMP_THISGREATER; // should never happen
 
1295
}
 
1296
 
 
1297
void KviKvsVariant::serializeString(QString & szBuffer)
 
1298
{
 
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('"');
 
1309
}
 
1310
 
 
1311
void KviKvsVariant::serialize(QString & szResult)
 
1312
{
 
1313
        if(!m_pData)
 
1314
        {
 
1315
                szResult = "null";
 
1316
                return;
 
1317
        }
 
1318
 
 
1319
        switch(m_pData->m_eType)
 
1320
        {
 
1321
                case KviKvsVariantData::HObject:
 
1322
                        //can't serialize objects yet
 
1323
                break;
 
1324
                case KviKvsVariantData::Integer:
 
1325
                        szResult.setNum(m_pData->m_u.iInt);
 
1326
                break;
 
1327
                case KviKvsVariantData::Real:
 
1328
                        szResult.setNum(*(m_pData->m_u.pReal));
 
1329
                break;
 
1330
                case KviKvsVariantData::String:
 
1331
                        szResult = *(m_pData->m_u.pString);
 
1332
                        serializeString(szResult);
 
1333
                break;
 
1334
                case KviKvsVariantData::Boolean:
 
1335
                        szResult = m_pData->m_u.bBoolean ? "true" : "false";
 
1336
                break;
 
1337
                case KviKvsVariantData::Hash:
 
1338
                        m_pData->m_u.pHash->serialize(szResult);
 
1339
                break;
 
1340
                case KviKvsVariantData::Array:
 
1341
                        m_pData->m_u.pArray->serialize(szResult);
 
1342
                break;
 
1343
                case KviKvsVariantData::Nothing:
 
1344
                        szResult = "null";
 
1345
                break;
 
1346
                default: // just make gcc happy
 
1347
                break;
 
1348
        }
 
1349
}
 
1350
 
 
1351
KviKvsVariant * KviKvsVariant::unserialize(const QString & szBuffer)
 
1352
{
 
1353
        KviKvsVariant * pResult = 0;
 
1354
 
 
1355
        const QChar * pAux = (const QChar *)szBuffer.constData();
 
1356
 
 
1357
        pResult = unserialize(&pAux);
 
1358
 
 
1359
        if(pAux->unicode())
 
1360
        {
 
1361
                //strange extra characters?
 
1362
                if(pResult)
 
1363
                        delete pResult;
 
1364
                pResult = 0;
 
1365
        }
 
1366
 
 
1367
        return pResult;
 
1368
}
 
1369
 
 
1370
KviKvsVariant * KviKvsVariant::unserialize(const QChar ** ppAux)
 
1371
{
 
1372
        KviKvsVariant * pResult = 0;
 
1373
 
 
1374
        while((*ppAux)->isSpace())
 
1375
                (*ppAux)++;
 
1376
 
 
1377
        switch((*ppAux)->unicode())
 
1378
        {
 
1379
                case 't':
 
1380
                        //true
 
1381
                        pResult = unserializeBool(ppAux,true);
 
1382
                break;
 
1383
                case 'f':
 
1384
                        //false
 
1385
                        pResult = unserializeBool(ppAux,false);
 
1386
                break;
 
1387
                case 'n':
 
1388
                        //null
 
1389
                        pResult = unserializeNull(ppAux);
 
1390
                break;
 
1391
                case '[':
 
1392
                        //array
 
1393
                        pResult = unserializeArray(ppAux);
 
1394
                break;
 
1395
                case '{':
 
1396
                        //hash
 
1397
                        pResult = unserializeHash(ppAux);
 
1398
                break;
 
1399
                case '"':
 
1400
                        //string
 
1401
                        pResult = unserializeString(ppAux);
 
1402
                break;
 
1403
                case '0':
 
1404
                case '1':
 
1405
                case '2':
 
1406
                case '3':
 
1407
                case '4':
 
1408
                case '5':
 
1409
                case '6':
 
1410
                case '7':
 
1411
                case '8':
 
1412
                case '9':
 
1413
                case '-':
 
1414
                        //real or integer
 
1415
                        pResult = unserializeNumber(ppAux);
 
1416
                break;
 
1417
                default:
 
1418
                        //incorrect value
 
1419
                        return 0;
 
1420
        }
 
1421
 
 
1422
        while((*ppAux)->isSpace())
 
1423
                (*ppAux)++;
 
1424
 
 
1425
        return pResult;
 
1426
}
 
1427
 
 
1428
KviKvsVariant * KviKvsVariant::unserializeBool(const QChar ** ppAux, bool bBool)
 
1429
{
 
1430
        bool bOk = false;
 
1431
 
 
1432
        if(bBool)
 
1433
        {
 
1434
                if(KviQString::equalCIN(QString("true"),*ppAux,4))
 
1435
                {
 
1436
                        (*ppAux) += 4;
 
1437
                        bOk = true;
 
1438
                }
 
1439
        } else {
 
1440
                if(KviQString::equalCIN(QString("false"),*ppAux,5))
 
1441
                {
 
1442
                        (*ppAux) += 5;
 
1443
                        bOk = true;
 
1444
                }
 
1445
        }
 
1446
 
 
1447
        if(bOk)
 
1448
                return new KviKvsVariant(bBool);
 
1449
        return 0;
 
1450
}
 
1451
 
 
1452
KviKvsVariant * KviKvsVariant::unserializeNull(const QChar ** ppAux)
 
1453
{
 
1454
        if(KviQString::equalCIN(QString("null"),*ppAux,4))
 
1455
        {
 
1456
                (*ppAux) += 4;
 
1457
                return new KviKvsVariant();
 
1458
        }
 
1459
        return 0;
 
1460
}
 
1461
 
 
1462
KviKvsVariant * KviKvsVariant::unserializeNumber(const QChar ** ppAux)
 
1463
{
 
1464
        QString szData;
 
1465
 
 
1466
        if((*ppAux)->unicode() == '-')
 
1467
        {
 
1468
                szData.append('-');
 
1469
                (*ppAux)++;
 
1470
        }
 
1471
 
 
1472
        if(!(*ppAux)->isDigit())
 
1473
        {
 
1474
                return 0;
 
1475
        }
 
1476
 
 
1477
        while((*ppAux)->isDigit())
 
1478
        {
 
1479
                szData.append(**ppAux);
 
1480
                (*ppAux)++;
 
1481
        }
 
1482
 
 
1483
        if((*ppAux)->unicode() == '.')
 
1484
        {
 
1485
                return unserializeReal(ppAux,szData);
 
1486
        }
 
1487
 
 
1488
        return unserializeInteger(ppAux,szData);
 
1489
}
 
1490
 
 
1491
KviKvsVariant * KviKvsVariant::unserializeReal(const QChar ** ppAux, QString & szData)
 
1492
{
 
1493
        QString szExponent;
 
1494
        (*ppAux)++; //skip .
 
1495
        szData.append('.');
 
1496
        while((*ppAux)->isDigit())
 
1497
        {
 
1498
                szData.append(**ppAux);
 
1499
                (*ppAux)++;
 
1500
        }
 
1501
 
 
1502
        if((*ppAux)->unicode() == 'e' || (*ppAux)->unicode() == 'E')
 
1503
        {
 
1504
                (*ppAux)++;
 
1505
                if((*ppAux)->unicode() == '-')
 
1506
                {
 
1507
                        szExponent.append('-');
 
1508
                        (*ppAux)++;
 
1509
                } else {
 
1510
                        if((*ppAux)->unicode() == '+')
 
1511
                        {
 
1512
                                szExponent.append('+');
 
1513
                                (*ppAux)++;
 
1514
                        }
 
1515
                }
 
1516
 
 
1517
                while((*ppAux)->isDigit())
 
1518
                {
 
1519
                        szExponent.append(**ppAux);
 
1520
                        (*ppAux)++;
 
1521
                }
 
1522
        }
 
1523
 
 
1524
        float fValue = szData.toFloat();
 
1525
        if(!szExponent.isNull())
 
1526
        {
 
1527
                fValue *= pow(10.0,szExponent.toInt());
 
1528
        }
 
1529
        return new KviKvsVariant(fValue);
 
1530
}
 
1531
 
 
1532
KviKvsVariant * KviKvsVariant::unserializeInteger(const QChar ** ppAux, QString & szData)
 
1533
{
 
1534
        QString szExponent;
 
1535
 
 
1536
        if((*ppAux)->unicode() == 'e' || (*ppAux)->unicode() == 'E')
 
1537
        {
 
1538
                (*ppAux)++;
 
1539
                if((*ppAux)->unicode() == '-')
 
1540
                {
 
1541
                        szExponent.append('-');
 
1542
                        (*ppAux)++;
 
1543
                } else {
 
1544
                        if((*ppAux)->unicode() == '+')
 
1545
                        {
 
1546
                                szExponent.append('+');
 
1547
                                (*ppAux)++;
 
1548
                        }
 
1549
                }
 
1550
 
 
1551
                while((*ppAux)->isDigit())
 
1552
                {
 
1553
                        szExponent.append(**ppAux);
 
1554
                        (*ppAux)++;
 
1555
                }
 
1556
        }
 
1557
 
 
1558
        kvs_int_t iValue = szData.toInt();
 
1559
        if(!szExponent.isNull())
 
1560
        {
 
1561
                iValue *= (kvs_int_t) pow(10.0,szExponent.toInt());
 
1562
        }
 
1563
        return new KviKvsVariant(iValue);
 
1564
}
 
1565
 
 
1566
KviKvsVariant * KviKvsVariant::unserializeString(const QChar ** ppAux)
 
1567
{
 
1568
        QString szBuffer;
 
1569
        unserializeString(ppAux,szBuffer);
 
1570
        return new KviKvsVariant(szBuffer);
 
1571
}
 
1572
 
 
1573
void KviKvsVariant::unserializeString(const QChar ** ppAux, QString & szData)
 
1574
{
 
1575
        szData = "";
 
1576
        QString szHex; //temp var
 
1577
        //skip leading "
 
1578
        (*ppAux)++;
 
1579
        while((*ppAux)->unicode())
 
1580
        {
 
1581
                switch((*ppAux)->unicode())
 
1582
                {
 
1583
                        case '"':
 
1584
                                //EOF
 
1585
                                (*ppAux)++;
 
1586
                                return;
 
1587
                        break;
 
1588
                        case '\\':
 
1589
                                //Special
 
1590
                                (*ppAux)++;
 
1591
                                switch((*ppAux)->unicode())
 
1592
                                {
 
1593
                                        case 't':
 
1594
                                                szData.append('\t');
 
1595
                                        break;
 
1596
                                        case '\"':
 
1597
                                                szData.append('\"');
 
1598
                                        break;
 
1599
                                        case '/':
 
1600
                                                szData.append('/');
 
1601
                                        break;
 
1602
                                        case 'b':
 
1603
                                                szData.append('\b');
 
1604
                                        break;
 
1605
                                        case 'f':
 
1606
                                                szData.append('\f');
 
1607
                                        break;
 
1608
                                        case 'n':
 
1609
                                                szData.append('\n');
 
1610
                                        break;
 
1611
                                        case 'r':
 
1612
                                                szData.append('\r');
 
1613
                                        break;
 
1614
                                        case 'u':
 
1615
                                                //4 hexadecmical digits pending...
 
1616
                                                szHex = "";
 
1617
                                                (*ppAux)++;
 
1618
                                                for(int i=0; i<4 && (*ppAux)->unicode(); i++)
 
1619
                                                {
 
1620
                                                        if((*ppAux)->isDigit() ||
 
1621
                                                                ((*ppAux)->unicode() >='A' && (*ppAux)->unicode() <='F')|| //ABCDEF
 
1622
                                                                ((*ppAux)->unicode() >='a' && (*ppAux)->unicode() <='f')) //abcdef
 
1623
                                                        {
 
1624
                                                                szHex.append(**ppAux);
 
1625
                                                                (*ppAux)++;
 
1626
                                                        } else {
 
1627
                                                                break;
 
1628
                                                        }
 
1629
                                                }
 
1630
                                                (*ppAux)--;
 
1631
                                                szData.append(QChar(szHex.toUInt(0,16)));
 
1632
                                        break;
 
1633
                                        default:
 
1634
                                                //Fallback; incorrect escape
 
1635
                                                (*ppAux)--;
 
1636
                                                szData.append('\\');
 
1637
                                }
 
1638
                                (*ppAux)++;
 
1639
                        break;
 
1640
                        default:
 
1641
                                szData.append(**ppAux);
 
1642
                                (*ppAux)++;
 
1643
                        break;
 
1644
                }
 
1645
        }
 
1646
}
 
1647
 
 
1648
KviKvsVariant * KviKvsVariant::unserializeHash(const QChar ** ppAux)
 
1649
{
 
1650
        KviKvsHash * pHash = new KviKvsHash();
 
1651
        QString szKey;
 
1652
        KviKvsVariant * pElement = 0;
 
1653
        //skip leading '{'
 
1654
        (*ppAux)++;
 
1655
        int i=0;
 
1656
        while(1)
 
1657
        {
 
1658
                //skip leading space
 
1659
                while((*ppAux)->isSpace())
 
1660
                        (*ppAux)++;
 
1661
                //waiting for starting of string
 
1662
                if((*ppAux)->unicode() != '\"')
 
1663
                {
 
1664
                        //strange characters
 
1665
                        delete pHash;
 
1666
                        return 0;
 
1667
                }
 
1668
                unserializeString(ppAux,szKey);
 
1669
                if(szKey.isEmpty())
 
1670
                {
 
1671
                        //Strange element name
 
1672
                        delete pHash;
 
1673
                        return 0;
 
1674
                }
 
1675
 
 
1676
                //skip leading space before ':'
 
1677
                while((*ppAux)->isSpace())
 
1678
                        (*ppAux)++;
 
1679
                //waiting for name-value delimeter
 
1680
                if((*ppAux)->unicode() != ':')
 
1681
                {
 
1682
                        //strange characters
 
1683
                        delete pHash;
 
1684
                        return 0;
 
1685
                }
 
1686
                (*ppAux)++;
 
1687
 
 
1688
                //getting element
 
1689
                pElement = unserialize(ppAux);
 
1690
                if(pElement)
 
1691
                {
 
1692
                        pHash->set(szKey,pElement);
 
1693
                        i++;
 
1694
                        while((*ppAux)->isSpace())
 
1695
                                (*ppAux)++;
 
1696
                        switch((*ppAux)->unicode())
 
1697
                        {
 
1698
                                case ',':
 
1699
                                        //goto next
 
1700
                                        (*ppAux)++;
 
1701
                                break;
 
1702
                                case '}':
 
1703
                                        //EOF array
 
1704
                                        (*ppAux)++;
 
1705
                                        return new KviKvsVariant(pHash);
 
1706
                                break;
 
1707
                                default:
 
1708
                                        delete pHash;
 
1709
                                        return 0;
 
1710
                                break;
 
1711
                        }
 
1712
                } else {
 
1713
                        //error
 
1714
                        delete pHash;
 
1715
                        return 0;
 
1716
                }
 
1717
        }
 
1718
        return 0;
 
1719
}
 
1720
 
 
1721
KviKvsVariant * KviKvsVariant::unserializeArray(const QChar ** ppAux)
 
1722
{
 
1723
        KviKvsArray * pArray = new KviKvsArray();
 
1724
        KviKvsVariant * pElement = 0;
 
1725
        (*ppAux)++;
 
1726
        int i=0;
 
1727
        while(1)
 
1728
        {
 
1729
                pElement = unserialize(ppAux);
 
1730
                if(pElement)
 
1731
                {
 
1732
                        pArray->set(i,pElement);
 
1733
                        i++;
 
1734
                        while((*ppAux)->isSpace())
 
1735
                                (*ppAux)++;
 
1736
                        switch((*ppAux)->unicode())
 
1737
                        {
 
1738
                                case ',':
 
1739
                                        //goto next
 
1740
                                        (*ppAux)++;
 
1741
                                break;
 
1742
                                case ']':
 
1743
                                        //EOF array
 
1744
                                        (*ppAux)++;
 
1745
                                        return new KviKvsVariant(pArray);
 
1746
                                break;
 
1747
                                default:
 
1748
                                        delete pArray;
 
1749
                                        return 0;
 
1750
                                break;
 
1751
                        }
 
1752
                } else {
 
1753
                        //error
 
1754
                        delete pArray;
 
1755
                        return 0;
 
1756
                }
 
1757
        }
 
1758
        return 0;
 
1759
}