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