1
18 #ifndef __value_hpp__
19 #define __value_hpp__
20
22
23 #include <string>
24 #include <functional>
27
28 #pragma warning( push )
29 #pragma warning(disable:4786) //identifier was truncated...
30
32 {
33
34 template<typename TC>
36 if(!src) return 0;
37 size_t cnt = 0; while( *src++ ) ++cnt;
38 return cnt;
39 }
40
41 // wide (utf16) string
42 typedef std::basic_string<WCHAR>
string;
43 // ascii or utf8 string
45
47
48 // value by key bidirectional proxy/accessor
50 // value by index bidirectional proxy/accessor
53
54 #ifdef CPP11
55 // native function that can be stored inside the value:
56 typedef std::function<value(unsigned int argc, const value* argv)> native_function_t;
57 #endif
58
60 {
61 value(
void*) {}
// no such thing, sorry 62 //void* get(const void* defv) const { return 0; } // and this one too is disabled
63 //void* get(const void* defv) { return 0; } // and this one too is disabled
64 public:
69
72
76
80 //value( const std::ustring& s ) { ValueInit(this); ValueStringDataSet(this, LPCWSTR(s.c_str()), UINT(s.length()), 0); }
81 //value( const std::string& s ) { aux::a2w as(s.c_str()); ValueInit(this); ValueStringDataSet(this, LPCWSTR(as.c_str()), UINT(as.length()), UT_STRING_SYMBOL); }
83
85
87 #ifdef CPP11
88 value(
const native_function_t& nfr );
89 #endif
90
93 #ifdef WIN32
95 #endif
97
98 // string-symbol
100 {
101 aux::a2w as(s);
103 }
104
106 {
107 aux::a2w as(s);
108 return value(as.chars());
109 }
111 {
112 return value( aux::chars_of(s) );
113 }
114
116 {
119 return v;
120 }
121
123 // if such value is used as a return value from native function
124 // the script runtime will throw an error in script rather than returning that value.
125 {
127 if( !s ) return v;
129 return v;
130 }
131
147 // if it is a native functor reference
149
151
153
155 {
156 if( this == &rs ) return true;
159 return false;
161 return true;
162 else
163 assert(false);
164 return false;
165 }
167 {
169 }
170
171
172 int get(
int defv)
const 173 {
174 int v;
176 return defv;
177 }
178 double get(
double defv)
const 179 {
180 double v;
182 return defv;
183 }
184 string get(
const WCHAR* defv)
const 185 {
186 aux::wchars wc;
188 return aux::make_string(wc);
190 }
192 {
193 aux::wchars s;
195 return s;
196 }
198 {
199 aux::bytes bs;
201 return bs;
202 }
203
204 #ifdef WIN32
205 FILETIME get_date() const
206 {
207 INT64 v;
209 return FILETIME();
210 }
211 #endif
212
213 bool get(
bool defv)
const 214 {
215 int v;
217 return defv;
218 }
219
220 template<typename T> T get() const;
221
223 {
225 if( s )
226 {
227 if(len == 0) len = (
unsigned int)
str_length(s);
229 }
231 }
233 {
234 return from_string(s.c_str(), (
unsigned int)s.length(),ct);
235 }
237 {
239 }
240
241
243 {
245 return aux::make_string(
get_chars());
// do not need to allocate 249 }
250
252 {
254 }
255
256 // if it is an array or map returns number of elements there, otherwise - 0
257 // if it is a function - returns number of arguments
259 {
260 int n = 0;
262 return n;
263 }
264 // if it is an array - returns nth element
265 // if it is a map - returns nth value of the map
266 // if it is a function - returns nth argument
267 // otherwise it returns undefined value
269 {
272 return r;
273 }
274
277
278 // if it is a map - returns value under the key in the map
279 // if it is a function - returns value of argument with the name
280 // otherwise it returns undefined value
283
284 typedef std::function<bool(const value& key, const value& val)>
key_value_cb;
285
287 {
288 // return true to continue enumeration
289 virtual bool on(
const value& key,
const value& val) = 0;
291 {
294 }
295
297 {
298 key_value_cb* cb = (key_value_cb*)param;
300 }
301
302 };
303
304 // enum
306 {
308 }
309
310 // calls cbf for each key/value pair found in T_OBJECT or T_MAP
312 {
314 }
315
317 {
320 return r;
321 }
322
323 // if it is an array - sets nth element expanding the array if needed
324 // if it is a map - sets nth value of the map;
325 // if it is a function - sets nth argument of the function;
326 // otherwise it converts this to array and adds v as first element.
328 {
330 }
331
333 {
335 }
336 // if it is a map - sets named value in the map;
337 // if it is a function - sets named argument of the function;
338 // otherwise it converts this to map and adds key/v to it.
339
341 {
343 }
345 {
348 }
349
353 {
356 return r;
357 }
358
362 {
366 return r;
367 }
368
369 // T_OBJECT and T_DOM_OBJECT only, get value of object's data slot
371 {
372 LPCBYTE pv = 0;
unsigned int dummy;
375 return (void*)pv;
376 }
377
378 //
379 // Below this point are TISCRIPT/SCITER related methods
380 //
381
382 //#if defined(HAS_TISCRIPT)
383
390
391
392 // T_OBJECT only, set value of object's data slot
394 {
397 }
398
399 // T_OBJECT only, class name of the object: e.g. Array, Function, etc. or custom class name.
400 //std_wstring get_object_class_name() const
401 //{
402 // assert(is_object());
403 // return get(L"");
404 //}
405 // T_OBJECT/UT_OBJECT_FUNCTION only, call TS function
406 // 'self' here is what will be known as 'this' inside the function, can be undefined for invocations of global functions
408 {
410 ValueInvoke(const_cast<value*>(
this),&
self,argc,argv,&rv,LPCWSTR(url_or_script_name));
411 return rv;
412 }
413
419
422 {
424 }
425
426 //#endif //defined(HAS_TISCRIPT)
427
428 // "smart" or "soft" equality test
430 {
431 if( v1 == v2 ) return true; // strict comparison
432 switch ( v1.
t > v2.
t? v1.
t: v2.
t )
433 {
435 {
436 bool const r1 = v1.
get(
false);
437 bool const r2 = v2.
get(!r1);
438 return r1 == r2;
439 }
441 {
442 int const r1 = v1.
get(0);
443 int const r2 = v2.
get(-r1);
444 return r1 == r2;
445 }
447 {
448 double const r1 = v1.
get(0.0);
449 double const r2 = v2.
get(-r1);
450 return r1 == r2;
451 }
452 }
453 return false;
454 }
455 };
456
457 template<>
inline int value::get<int>()
const {
return get(0); }
458 template<>
inline unsigned value::get<unsigned>()
const {
return (
unsigned)
get(0); }
459 template<>
inline bool value::get<bool>()
const {
return get(
false); }
460 template<>
inline double value::get<double>()
const {
return get(0.0); }
461 template<>
inline float value::get<float>()
const {
return (
float)
get(0.0); }
462 template<>
inline string value::get<string>()
const {
return to_string(); }
463 //template<> inline const value& value::get<const value&>() const { return *this; }
464 template<>
inline value value::get<value>()
const {
return *
this; }
465
466 // value by key bidirectional proxy/accessor
468 {
473 protected:
475 public:
479 };
480
483
484 // value by index bidirectional proxy/accessor
486 {
489 int idx;
491 protected:
493 public:
497 };
498
501
502 }
503
504
505 #ifdef CPP11
507
508 class native_function
509 {
510 public:
511 native_function(const native_function_t& f): func(f) { assert(f); }
512 virtual ~native_function() {}
513
514 virtual bool invoke(
unsigned int argc,
const VALUE*
argv,
VALUE* retval )
515 {
516 if( func ) {
518 value r = func(argc,static_cast<const value*>(argv));
520 return true;
521 }
522 else
523 return false;
524 }
525 native_function_t func;
526 private:
527 native_function(const native_function& f);
528 native_function&
operator=(
const native_function& f);
529 public:
530 static VOID invoke_impl( VOID* tag, UINT argc,
const VALUE* argv,
VALUE* retval)
531 {
532 native_function* self = static_cast<native_function*>(tag);
534 value r =
self->func(argc,static_cast<const value*>(argv));
536 }
537 static VOID release_impl( VOID* tag )
538 {
539 native_function* self = static_cast<native_function*>(tag);
540 delete self;
541 }
542 };
543
546 native_function* pnf = new native_function(nfr);
548 }
549
550 // vfunc(native function) is a wrapper that produces sciter::value from native function
551 // see uminimal sample
552 template<typename R>
553 inline value vfunc( R(*func)() ) {
555 }
556 template<typename R, typename T1>
557 inline value vfunc( R(*func)(T1 t1) ) {
559 R r = func(argc >= 1? argv[0].get<T1>(): T1() );
561 });
562 }
563 template<typename R, typename T1, typename T2>
564 inline value vfunc( R(*func)(T1 t1,T2 t2) ) {
566 R r = func(argc >= 1? argv[0].get<T1>(): T1(),
567 argc >= 2? argv[1].get<T2>(): T2() );
569 });
570 }
571 template<typename R, typename T1, typename T2, typename T3>
572 inline value vfunc( R(*func)(T1 t1,T2 t2,T3 t3) ) {
574 R r = func(argc >= 1? argv[0].get<T1>(): T1(),
575 argc >= 2? argv[1].get<T2>(): T2(),
576 argc >= 3? argv[2].get<T3>(): T3());
578 });
579 }
580 template<typename R, typename T1, typename T2, typename T3, typename T4>
581 inline value vfunc( R(*func)(T1 t1,T2 t2,T3 t3,T4 t4) ) {
583 R r = func(argc >= 1? argv[0].get<T1>(): T1(),
584 argc >= 2? argv[1].get<T2>(): T2(),
585 argc >= 3? argv[2].get<T3>(): T3(),
586 argc >= 4? argv[3].get<T4>(): T4());
588 });
589 }
590
591 // versions of the above but for generic std::function
592 template<typename R>
593 inline value vfunc( std::function<R()> func )
594 {
596 R r = func();
return value(r);
597 });
598 }
599
600 template<typename R,typename P0>
601 inline value vfunc( std::function<R(P0)> func )
602 {
604 R r = func(argc >= 1? argv[0].get<P0>(): P0() );
606 }
607 template<typename R,typename P0,typename P1>
608 inline value vfunc( std::function<R(P0,P1)> func )
609 {
611 R r = func(argc >= 1? argv[0].get<P0>(): P0(),
612 argc >= 2? argv[1].get<P1>(): P1() );
614 }
615
616 template<typename R, typename P0, typename P1, typename P2>
617 inline value vfunc( std::function<R(P0,P1,P2)> func )
618 {
620 R r = func(argc >= 1? argv[0].get<P0>(): P0(),
621 argc >= 2? argv[1].get<P1>(): P1(),
622 argc >= 3? argv[2].get<P2>(): P2());
624 }
625
626 template<typename R, typename P0, typename P1, typename P2, typename P3>
627 inline value vfunc( std::function<R(P0,P1,P2,P3)> func ) {
629 R r = func(argc >= 1? argv[0].get<P0>(): P0(),
630 argc >= 2? argv[1].get<P1>(): P1(),
631 argc >= 3? argv[2].get<P2>(): P2(),
632 argc >= 4? argv[3].get<P3>(): P3());
634 }
635
636
637 }
638 #endif
639
640 #pragma warning( pop )
641
642 #endif
void set_object_data(void *pv)
value call(const value &p1, const value &p2, const value &p3) const
value call(int argc, const value *argv, value self=value(), const WCHAR *url_or_script_name=0) const
value_key_a(value &c, const value &k)
size_t str_length(const TC *src)
bool operator!=(const value &rs) const
UINT SCAPI ValueStringDataSet(VALUE *pval, LPCWSTR chars, UINT numChars, UINT units)
UINT SCAPI ValueClear(VALUE *pval)
UINT SCAPI ValueNthElementKey(const VALUE *pval, INT n, VALUE *pretval)
value get_item(int n) const
UINT SCAPI ValueElementsCount(const VALUE *pval, INT *pn)
bool operator==(const value &rs) const
bool is_error_string() const
UINT SCAPI ValueEnumElements(const VALUE *pval, KeyValueCallback *penum, LPVOID param)
static value secure_string(const WCHAR *s, size_t slen)
void set_item(const value &key, const value &v)
value get_item(const char *name) const
std::basic_string< char > astring
BOOL SCAPI ValueIsNativeFunctor(const VALUE *pval)
void each_key_value(key_value_cb cbf) const
UINT SCAPI ValueInvoke(const VALUE *pval, VALUE *pthis, UINT argc, const VALUE *argv, VALUE *pretval, LPCWSTR url)
static value date(INT64 v, bool is_utc=true)
static value from_string(aux::wchars s, VALUE_STRING_CVT_TYPE ct=CVT_SIMPLE)
void append(const value &v)
std::runtime_error script_error
aux::wchars get_chars() const
bool is_object_class() const
static value from_string(const WCHAR *s, unsigned int len=0, VALUE_STRING_CVT_TYPE ct=CVT_SIMPLE)
UINT SCAPI ValueIsolate(VALUE *pdst)
static value make_error(const WCHAR *s)
bool is_object_native() const
static BOOL SC_CALLBACK lambda_callback(LPVOID param, const VALUE *pkey, const VALUE *pval)
void enum_elements(enum_cb &cb) const
UINT SCAPI ValueNativeFunctorSet(VALUE *pval, NATIVE_FUNCTOR_INVOKE *pinvoke, NATIVE_FUNCTOR_RELEASE *prelease, VOID *tag)
bool is_undefined() const
value call(const value &p1) const
UINT SCAPI ValueCopy(VALUE *pdst, const VALUE *psrc)
bool is_object_function() const
static value currency(INT64 v)
UINT SCAPI ValueInt64DataSet(VALUE *pval, INT64 data, UINT type, UINT units)
static value symbol(aux::wchars wc)
bool is_dom_element() const
UINT SCAPI ValueIntData(const VALUE *pval, INT *pData)
value_idx_a(value &c, int i)
UINT SCAPI ValueToString(VALUE *pval, UINT how)
bool is_object_object() const
void set_item(const char *name, const value &v)
bool is_object_error() const
const value operator[](int n) const
UINT SCAPI ValueFromString(VALUE *pval, LPCWSTR str, UINT strLength, UINT how)
value(const WCHAR *s, unsigned int slen=0)
virtual bool on(const value &key, const value &val)=0
const std::vector< sciter::string > & argv()
UINT SCAPI ValueFloatData(const VALUE *pval, FLOAT_VALUE *pData)
static BOOL SC_CALLBACK _callback(LPVOID param, const VALUE *pkey, const VALUE *pval)
UINT SCAPI ValueBinaryData(const VALUE *pval, LPCBYTE *pBytes, UINT *pnBytes)
UINT SCAPI ValueInt64Data(const VALUE *pval, INT64 *pData)
UINT SCAPI ValueGetValueOfKey(const VALUE *pval, const VALUE *pkey, VALUE *pretval)
UINT SCAPI ValueBinaryDataSet(VALUE *pval, LPCBYTE pBytes, UINT nBytes, UINT type, UINT units)
void * get_object_data() const
bool is_object_array() const
static bool equal(const value &v1, const value &v2)
std::function< bool(const value &key, const value &val)> key_value_cb
static value make_string(const WCHAR *s)
UINT SCAPI ValueNthElementValueSet(VALUE *pval, INT n, const VALUE *pval_to_set)
value call(const value &p1, const value &p2) const
UINT SCAPI ValueFloatDataSet(VALUE *pval, FLOAT_VALUE data, UINT type, UINT units)
UINT SCAPI ValueInit(VALUE *pval)
const value operator[](const value &key) const
value get_item(const value &key) const
UINT SCAPI ValueIntDataSet(VALUE *pval, INT data, UINT type, UINT units)
string to_string(int how=CVT_SIMPLE) const
bool is_native_function() const
std::basic_string< WCHAR > string
UINT SCAPI ValueCompare(const VALUE *pval1, const VALUE *pval2)
UINT SCAPI ValueNthElementValue(const VALUE *pval, INT n, VALUE *pretval)
UINT SCAPI ValueSetValueToKey(VALUE *pval, const VALUE *pkey, const VALUE *pval_to_set)
value call(const value &p1, const value &p2, const value &p3, const value &p4) const
value & operator=(const value &src)
aux::bytes get_bytes() const
value(const value *arr, unsigned n)
static value from_string(const std::basic_string< WCHAR > &s, VALUE_STRING_CVT_TYPE ct=CVT_SIMPLE)
simple conversion of terminal values
void set_item(int n, const value &v)
static value make_string(const char *s)
UINT SCAPI ValueStringData(const VALUE *pval, LPCWSTR *pChars, UINT *pNumChars)