1 #include "Core.h"
2
3 namespace Upp {
4
5 static String sAsString(const Vector<Value>& v);
6
7 #define LTIMING(x) // RTIMING(x)
8
9 struct Ref::ValueRef : public RefManager {
GetTypeUpp::Ref::ValueRef10 virtual int GetType() { return VALUE_V; }
GetValueUpp::Ref::ValueRef11 virtual Value GetValue(const void *ptr) { return *(Value *) ptr; }
IsNullUpp::Ref::ValueRef12 virtual bool IsNull(const void *ptr) { return UPP::IsNull(*(Value *) ptr); }
SetValueUpp::Ref::ValueRef13 virtual void SetValue(void *ptr, const Value& v) { *(Value *) ptr = v; }
SetNullUpp::Ref::ValueRef14 virtual void SetNull(void *ptr) { *(Value *) ptr = Null; }
15 };
16
Ref(String & s)17 Ref::Ref(String& s) { ptr = &s; m = &Single< StdRef<String> >(); }
Ref(WString & s)18 Ref::Ref(WString& s) { ptr = &s; m = &Single< StdRef<WString> >(); }
Ref(int & i)19 Ref::Ref(int& i) { ptr = &i; m = &Single< StdRef<int> >(); }
Ref(int64 & i)20 Ref::Ref(int64& i) { ptr = &i; m = &Single< StdRef<int64> >(); }
Ref(double & d)21 Ref::Ref(double& d) { ptr = &d; m = &Single< StdRef<double> >(); }
Ref(bool & b)22 Ref::Ref(bool& b) { ptr = &b; m = &Single< StdRef<bool> >(); }
Ref(Date & d)23 Ref::Ref(Date& d) { ptr = &d; m = &Single< StdRef<Date> >(); }
Ref(Time & t)24 Ref::Ref(Time& t) { ptr = &t; m = &Single< StdRef<Time> >(); }
Ref(Value & v)25 Ref::Ref(Value& v) { ptr = &v; m = &Single< ValueRef >(); }
26
27 // ----------------------------------
28
IsNull() const29 bool ValueArray::Data::IsNull() const
30 {
31 return data.IsEmpty();
32 }
33
Serialize(Stream & s)34 void ValueArray::Data::Serialize(Stream& s)
35 {
36 s % data;
37 }
38
Jsonize(JsonIO & jio)39 void ValueArray::Data::Jsonize(JsonIO& jio)
40 {
41 Upp::Jsonize(jio, data);
42 }
43
Xmlize(XmlIO & io)44 void ValueArray::Data::Xmlize(XmlIO& io)
45 {
46 Upp::Xmlize(io, data);
47 }
48
GetHashValue() const49 hash_t ValueArray::Data::GetHashValue() const
50 {
51 CombineHash w(data.GetCount());
52 for(int i = 0; i < data.GetCount(); i++)
53 w.Put(data[i].GetHashValue());
54 return w;
55 }
56
IsEqual(const Value::Void * p)57 bool ValueArray::Data::IsEqual(const Value::Void *p)
58 {
59 return ((Data *)p)->data == data;
60 }
61
Compare(const Value::Void * p)62 int ValueArray::Data::Compare(const Value::Void *p)
63 {
64 return data.Compare(((Data *)p)->data);
65 }
66
operator ==(const ValueArray & v) const67 bool ValueArray::operator==(const ValueArray& v) const
68 {
69 return v.data->data == data->data;
70 }
71
Compare(const ValueArray & b) const72 int ValueArray::Compare(const ValueArray& b) const
73 {
74 return data->data.Compare(b.data->data);
75 }
76
sAsString(const Vector<Value> & v)77 static String sAsString(const Vector<Value>& v)
78 {
79 String s;
80 s << "[";
81 for(int i = 0; i < v.GetCount(); i++) {
82 if(i) s << ", ";
83 s << v[i];
84 }
85 s << "]";
86 return s;
87 }
88
AsString() const89 String ValueArray::Data::AsString() const
90 {
91 return sAsString(data);
92 }
93
94 Vector<Value> ValueArray::VoidData;
95
Create()96 Vector<Value>& ValueArray::Create()
97 {
98 data = new Data;
99 return data->data;
100 }
101
Clone()102 Vector<Value>& ValueArray::Clone() {
103 if(data->GetRefCount() != 1) {
104 Data *d = new Data;
105 d->data = clone(data->data);
106 data->Release();
107 data = d;
108 }
109 return data->data;
110 }
111
Init0()112 void ValueArray::Init0()
113 {
114 data = &Single<NullData>();
115 data->Retain();
116 }
117
ValueArray(const ValueArray & v)118 ValueArray::ValueArray(const ValueArray& v) {
119 data = v.data;
120 data->Retain();
121 }
122
ValueArray(ValueArray && v)123 ValueArray::ValueArray(ValueArray&& v) {
124 data = v.data;
125 v.Init0();
126 }
127
ValueArray(Vector<Value> && v)128 ValueArray::ValueArray(Vector<Value>&& v)
129 {
130 Create() = pick(v);
131 }
132
ValueArray(const Vector<Value> & v,int deep)133 ValueArray::ValueArray(const Vector<Value>& v, int deep)
134 {
135 Create() = clone(v);
136 }
137
operator Value() const138 ValueArray::operator Value() const {
139 data->Retain();
140 return Value(data, VALUEARRAY_V);
141 }
142
ValueArray(const Value & src)143 ValueArray::ValueArray(const Value& src)
144 {
145 if(!UPP::IsNull(src)) {
146 if(src.Is<ValueMap>()) {
147 ValueArray v = ValueMap(src);
148 data = v.data;
149 data->Retain();
150 return;
151 }
152 else {
153 if(src.GetType() != VALUEARRAY_V)
154 throw ValueTypeError(String().Cat() << "Invalid value conversion: "
155 << src.GetTypeName() << " -> ValueArray",
156 src, VALUEARRAY_V);
157 data = (ValueArray::Data *)src.GetVoidPtr();
158 }
159 }
160 else
161 data = &Single<NullData>();
162 data->Retain();
163 }
164
Serialize(Stream & s)165 void ValueArray::Serialize(Stream& s) {
166 if(s.IsLoading()) {
167 data->Release();
168 Create();
169 }
170 data->Serialize(s);
171 }
172
Jsonize(JsonIO & jio)173 void ValueArray::Jsonize(JsonIO& jio)
174 {
175 if(jio.IsLoading()) {
176 data->Release();
177 Create();
178 }
179 data->Jsonize(jio);
180 }
181
Xmlize(XmlIO & xio)182 void ValueArray::Xmlize(XmlIO& xio)
183 {
184 if(xio.IsLoading()) {
185 data->Release();
186 Create();
187 }
188 data->Xmlize(xio);
189 }
190
ToString() const191 String ValueArray::ToString() const
192 {
193 return sAsString(Get());
194 }
195
~ValueArray()196 ValueArray::~ValueArray() {
197 ASSERT(data->GetRefCount() > 0);
198 data->Release();
199 }
200
operator =(const ValueArray & v)201 ValueArray& ValueArray::operator=(const ValueArray& v) {
202 v.data->Retain();
203 data->Release();
204 data = v.data;
205 return *this;
206 }
207
SetCount(int n)208 void ValueArray::SetCount(int n)
209 {
210 Clone().SetCount(n);
211 }
212
SetCount(int n,const Value & v)213 void ValueArray::SetCount(int n, const Value& v)
214 {
215 Clone().SetCount(n, v);
216 }
217
Clear()218 void ValueArray::Clear() {
219 Clone().Clear();
220 }
221
Add(const Value & v)222 void ValueArray::Add(const Value& v) {
223 Clone().Add(v);
224 }
225
Set(int i,const Value & v)226 void ValueArray::Set(int i, const Value& v) {
227 #if !defined(_MSC_VER) || _MSC_VER > 1310
228 ASSERT(i >= 0);
229 Clone().At(i) = v;
230 #else
231 throw 0;
232 #endif
233 }
234
At(int i)235 Value& ValueArray::At(int i)
236 {
237 return Clone().At(i);
238 }
239
Remove(int i,int count)240 void ValueArray::Remove(int i, int count)
241 {
242 Clone().Remove(i, count);
243 }
244
Remove(const Vector<int> & ii)245 void ValueArray::Remove(const Vector<int>& ii)
246 {
247 Clone().Remove(ii);
248 }
249
Insert(int i,const ValueArray & va)250 void ValueArray::Insert(int i, const ValueArray& va)
251 {
252 if(va.data == data) {
253 ValueArray va2 = va;
254 Clone().Insert(i, va2.Get());
255 }
256 else
257 Clone().Insert(i, va.Get());
258 }
259
Get(int i) const260 const Value& ValueArray::Get(int i) const {
261 ASSERT(i >= 0 && i < GetCount());
262 return data->data[i];
263 }
264
GetAndClear(int i)265 Value ValueArray::GetAndClear(int i)
266 {
267 ASSERT(i >= 0 && i < GetCount());
268 Vector<Value>& x = Clone();
269 Value v = x[i];
270 x[i] = Value();
271 return v;
272 }
273
Pick()274 Vector<Value> ValueArray::Pick()
275 {
276 Vector<Value>& x = Clone();
277 Vector<Value> r = pick(x);
278 x.Clear();
279 return r;
280 }
281
282 template<>
AsString(const ValueArray & v)283 String AsString(const ValueArray& v) {
284 return sAsString(v.Get());
285 }
286
IsNull() const287 bool ValueMap::Data::IsNull() const {
288 return this == &Single<ValueMap::NullData>();
289 }
290
Serialize(Stream & s)291 void ValueMap::Data::Serialize(Stream& s) {
292 #if !defined(_MSC_VER) || _MSC_VER > 1310
293 s % key % value;
294 #else
295 throw 0;
296 #endif
297 }
298
Xmlize(XmlIO & xio)299 void ValueMap::Data::Xmlize(XmlIO& xio)
300 {
301 #if !defined(_MSC_VER) || _MSC_VER > 1310
302 Upp::Xmlize(xio, key);
303 Upp::Xmlize(xio, value);
304 #else
305 throw 0;
306 #endif
307 }
308
Jsonize(JsonIO & jio)309 void ValueMap::Data::Jsonize(JsonIO& jio)
310 {
311 if(jio.IsStoring()) {
312 ValueArray va;
313 int n = min(value.GetCount(), key.GetCount());
314 for(int i = 0; i < n; i++) {
315 ValueMap m;
316 m.Add("key", StoreAsJsonValue(key[i]));
317 m.Add("value", StoreAsJsonValue(value[i]));
318 va.Add(m);
319 }
320 jio.Set(va);
321 }
322 else {
323 Value va = jio.Get();
324 key.Clear();
325 value.Clear();
326 for(int i = 0; i < va.GetCount(); i++) {
327 Value k, v;
328 LoadFromJsonValue(k, va[i]["key"]);
329 LoadFromJsonValue(v, va[i]["value"]);
330 key.Add(k);
331 value.Add(v);
332 }
333 }
334 }
335
GetHashValue() const336 hash_t ValueMap::Data::GetHashValue() const {
337 CombineHash w(key.GetCount());
338 for(int i = 0; i < key.GetCount(); i++)
339 w.Put(key[i].GetHashValue());
340 w.Put(value.GetHashValue());
341 return w;
342 }
343
sIsEqual(const Index<Value> & a,const Index<Value> & b)344 static bool sIsEqual(const Index<Value>& a, const Index<Value>& b)
345 {
346 if(&a == &b) return true;
347 if(a.GetCount() != b.GetCount()) return false;
348 for(int i = 0; i < a.GetCount(); i++) {
349 if(a[i] != b[i]) return false;
350 }
351 return true;
352 }
353
IsEqual(const Value::Void * p)354 bool ValueMap::Data::IsEqual(const Value::Void *p)
355 {
356 return sIsEqual(((Data *)p)->key, key) && ((Data *)p)->value == value;
357 }
358
operator ==(const ValueMap & v) const359 bool ValueMap::operator==(const ValueMap& v) const
360 {
361 return sIsEqual(data->key, v.data->key) && data->value == v.data->value;
362 }
363
Compare(const Value::Void * p)364 int ValueMap::Data::Compare(const Value::Void *p)
365 {
366 Data *b = (Data *)p;
367 int n = min(key.GetCount(), b->key.GetCount());
368 for(int i = 0; i < n; i++) {
369 int q = SgnCompare(key[i], b->key[i]);
370 if(q)
371 return q;
372 q = SgnCompare(value[i], b->value[i]);
373 if(q)
374 return q;
375 }
376 return SgnCompare(key.GetCount(), b->key.GetCount());
377 }
378
Compare(const ValueMap & b) const379 int ValueMap::Compare(const ValueMap& b) const
380 {
381 return data->Compare((Value::Void *)b.data);
382 }
383
IsSame(const ValueMap & b) const384 bool ValueMap::IsSame(const ValueMap& b) const
385 {
386 for(int pass = 0; pass < 2; pass++) {
387 const ValueMap& m = pass ? *this : b;
388 const ValueMap& n = pass ? b : *this;
389 for(int i = 0; i < m.GetCount(); i++)
390 if(!n[m.GetKey(i)].IsSame(m.GetValue(i)))
391 return false;
392 }
393 return true;
394 }
395
AsString() const396 String ValueMap::Data::AsString() const
397 {
398 String s;
399 s << "{ ";
400 for(int i = 0; i < key.GetCount(); i++) {
401 if(i) s << ", ";
402 s << key[i] << ": " << value[i];
403 }
404 s << " }";
405 return s;
406 }
407
Create()408 ValueMap::Data& ValueMap::Create()
409 {
410 data = new Data;
411 return *data;
412 }
413
Clone(Data * & ptr)414 void ValueMap::Clone(Data *&ptr)
415 {
416 Data *d = new Data;
417 d->key = clone(ptr->key);
418 d->value = ptr->value;
419 ptr->Release();
420 ptr = d;
421 }
422
Init0()423 void ValueMap::Init0()
424 {
425 data = &Single<NullData>();
426 data->Retain();
427 }
428
ValueMap(const ValueMap & v)429 ValueMap::ValueMap(const ValueMap& v)
430 {
431 data = v.data;
432 data->Retain();
433 }
434
ValueMap(Index<Value> && k,Vector<Value> && v)435 ValueMap::ValueMap(Index<Value>&& k, Vector<Value>&& v)
436 {
437 Data& d = Create();
438 d.key = pick(k);
439 d.value = ValueArray(pick(v));
440 }
441
ValueMap(VectorMap<Value,Value> && m)442 ValueMap::ValueMap(VectorMap<Value, Value>&& m)
443 {
444 Data& d = Create();
445 d.key = m.PickKeys();
446 d.value = ValueArray(m.PickValues());
447 }
448
ValueMap(const Index<Value> & k,const Vector<Value> & v,int deep)449 ValueMap::ValueMap(const Index<Value>& k, const Vector<Value>& v, int deep)
450 {
451 Data& d = Create();
452 d.key = clone(k);
453 d.value = ValueArray(v, 0);
454 }
455
ValueMap(const VectorMap<Value,Value> & m,int deep)456 ValueMap::ValueMap(const VectorMap<Value, Value>& m, int deep)
457 {
458 Data& d = Create();
459 d.key = clone(m.GetKeys());
460 d.value = ValueArray(m.GetValues(), 0);
461 }
462
Pick()463 VectorMap<Value, Value> ValueMap::Pick()
464 {
465 Data& d = UnShare();
466 VectorMap<Value, Value> m(d.key.PickKeys(), d.value.Pick());
467 d.key.Clear();
468 return m;
469 }
470
operator Value() const471 ValueMap::operator Value() const {
472 data->Retain();
473 return Value(data, VALUEMAP_V);
474 }
475
FromArray(const ValueArray & va)476 void ValueMap::FromArray(const ValueArray& va)
477 {
478 Init0();
479 for(int i = 0; i < va.GetCount(); i++)
480 Add(i, va[i]);
481 }
482
ValueMap(const Value & src)483 ValueMap::ValueMap(const Value& src)
484 {
485 if(!IsNull(src)) {
486 if(src.Is<ValueArray>()) {
487 FromArray(src);
488 return;
489 }
490 else {
491 if(src.GetType() != VALUEMAP_V)
492 throw ValueTypeError(String().Cat() << "Invalid value conversion: "
493 << src.GetTypeName() << " -> ValueMap",
494 src, VALUEMAP_V);
495 data = (ValueMap::Data *)src.GetVoidPtr();
496 }
497 }
498 else
499 data = &Single<NullData>();
500 data->Retain();
501 }
502
Serialize(Stream & s)503 void ValueMap::Serialize(Stream& s) {
504 if(s.IsLoading()) {
505 data->Release();
506 Create();
507 }
508 data->Serialize(s);
509 }
510
Jsonize(JsonIO & jio)511 void ValueMap::Jsonize(JsonIO& jio)
512 {
513 if(jio.IsLoading()) {
514 data->Release();
515 Create();
516 }
517 data->Jsonize(jio);
518 }
519
Xmlize(XmlIO & xio)520 void ValueMap::Xmlize(XmlIO& xio)
521 {
522 if(xio.IsLoading()) {
523 data->Release();
524 Create();
525 }
526 data->Xmlize(xio);
527 }
528
~ValueMap()529 ValueMap::~ValueMap() {
530 ASSERT(data->GetRefCount() > 0);
531 data->Release();
532 }
533
operator =(const ValueMap & v)534 ValueMap& ValueMap::operator=(const ValueMap& v) {
535 v.data->Retain();
536 data->Release();
537 data = v.data;
538 return *this;
539 }
540
Clear()541 void ValueMap::Clear() {
542 data->Release();
543 Init0();
544 }
545
Set(const Value & key,const Value & value)546 void ValueMap::Set(const Value& key, const Value& value)
547 {
548 Data& d = UnShare();
549 int i = d.key.Find(key);
550 if(i >= 0)
551 d.value.Set(i, value);
552 else {
553 d.key.Add(key);
554 d.value.Add(value);
555 }
556 }
557
SetAt(int i,const Value & v)558 void ValueMap::SetAt(int i, const Value& v) {
559 UnShare().value.Set(i, v);
560 }
561
SetKey(int i,const Value & k)562 void ValueMap::SetKey(int i, const Value& k) {
563 UnShare().key.Set(i, k);
564 }
565
RemoveKey(const Value & key)566 int ValueMap::RemoveKey(const Value& key)
567 {
568 Data& d = UnShare();
569 Vector<int> rk;
570 int q = d.key.Find(key);
571 while(q >= 0) {
572 rk.Add(q);
573 q = d.key.FindNext(q);
574 }
575 if(rk.GetCount()) {
576 Sort(rk);
577 d.key.Remove(rk);
578 d.value.Remove(rk);
579 }
580 return rk.GetCount();
581 }
582
Remove(int i)583 void ValueMap::Remove(int i)
584 {
585 Data& d = UnShare();
586 d.key.Remove(i);
587 d.value.Remove(i);
588 }
589
GetAndClear(const Value & key)590 Value ValueMap::GetAndClear(const Value& key)
591 {
592 Data& d = UnShare();
593 int q = d.key.Find(key);
594 return q < 0 ? ErrorValue() : d.value.GetAndClear(q);
595 }
596
597 // ----------------------------------
598
operator ()(const Value & k1,const Value & v1,const Value & k2,const Value & v2) const599 bool StdValuePairOrder::operator()(const Value& k1, const Value& v1, const Value& k2, const Value& v2) const
600 {
601 int q = StdValueCompare(k1, k2, language);
602 if(q) return q < 0;
603 return StdValueCompare(v1, v2, language);
604 }
605
operator ()(const Value & keya,const Value & valuea,const Value & keyb,const Value & valueb) const606 bool FnValuePairOrder::operator()(const Value& keya, const Value& valuea, const Value& keyb, const Value& valueb) const
607 {
608 return (*fn)(keya, valuea, keyb, valueb) < 0;
609 }
610
CompareStrings(const Value & a,const Value & b,const LanguageInfo & f)611 int CompareStrings(const Value& a, const Value& b, const LanguageInfo& f)
612 {
613 return f.Compare(WString(a), WString(b));
614 }
615
Xmlize(XmlIO & xio)616 void Complex::Xmlize(XmlIO& xio)
617 {
618 double r, i;
619 r = real(); i = imag();
620 xio.Attr("real", r).Attr("imag", i);
621 *this = C(r, i);
622 }
623
Jsonize(JsonIO & jio)624 void Complex::Jsonize(JsonIO& jio)
625 {
626 double r, i;
627 r = real(); i = imag();
628 jio("real", r)("imag", i);
629 *this = C(r, i);
630 }
631
Serialize(Stream & s)632 void Complex::Serialize(Stream& s)
633 {
634 double r, i;
635 r = real(); i = imag();
636 s % r % i;
637 *this = C(r, i);
638 }
639
640 template <class T>
sReg(const char * name)641 static void sReg(const char *name)
642 {
643 if(FitsSvoValue<T>())
644 Value::SvoRegister<T>(name);
645 else
646 Value::Register<T>(name);
647 }
648
649 INITBLOCK
650 {
651 sReg<Point>("Point");
652 sReg<Point64>("Point64");
653 sReg<Pointf>("Pointf");
654 sReg<Size>("Size");
655 sReg<Size64>("Size64");
656 sReg<Sizef>("Sizef");
657 Value::Register<Rect>("Rect");
658 Value::Register<Rect64>("Rect64");
659 Value::Register<Rectf>("Rectf");
660 }
661
662 }
663
664