comet-cpp 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/bin/comet-html +69 -0
  3. data/bin/comet-make +53 -0
  4. data/bin/comet-new +62 -0
  5. data/bin/comet-web +14 -0
  6. data/lib/comet-html/generator.rb +220 -0
  7. data/lib/comet-html/header-generator.rb +145 -0
  8. data/lib/comet-html/parser-binding.rb +42 -0
  9. data/lib/comet-html/parser-class.rb +168 -0
  10. data/lib/comet-html/parser-context.rb +61 -0
  11. data/lib/comet-html/parser-reference.rb +98 -0
  12. data/lib/comet-html/parser-repeater.rb +58 -0
  13. data/lib/comet-html/parser-slot.rb +108 -0
  14. data/lib/comet-html/source-generator.rb +285 -0
  15. data/lib/comet-html/utils.rb +88 -0
  16. data/lib/guard/comet-html.rb +32 -0
  17. data/lib/guard/comet.rb +36 -0
  18. data/vendor/project/Gemfile +4 -0
  19. data/vendor/project/Guardfile +5 -0
  20. data/vendor/project/app/application.hpp +29 -0
  21. data/vendor/project/app/collections/.gitkeep +0 -0
  22. data/vendor/project/app/controllers/.gitkeep +0 -0
  23. data/vendor/project/app/main.cpp +6 -0
  24. data/vendor/project/app/models/.gitkeep +0 -0
  25. data/vendor/project/app/routes.cpp +7 -0
  26. data/vendor/project/app/views/layouts/.gitkeep +0 -0
  27. data/vendor/project/public/index.html +7 -0
  28. data/vendor/src/anchorable_element.hpp +79 -0
  29. data/vendor/src/append_semantics.hpp +73 -0
  30. data/vendor/src/bindable.cpp +99 -0
  31. data/vendor/src/bindable.hpp +106 -0
  32. data/vendor/src/cheerp_parse_cookie_values.cpp +58 -0
  33. data/vendor/src/comment_element.cpp +11 -0
  34. data/vendor/src/comment_element.hpp +17 -0
  35. data/vendor/src/cookies.cpp +94 -0
  36. data/vendor/src/cookies.hpp +60 -0
  37. data/vendor/src/custom_element.hpp +61 -0
  38. data/vendor/src/datatree.cpp +198 -0
  39. data/vendor/src/datatree.hpp +233 -0
  40. data/vendor/src/document.cpp +62 -0
  41. data/vendor/src/document.hpp +31 -0
  42. data/vendor/src/element.cpp +358 -0
  43. data/vendor/src/element.hpp +138 -0
  44. data/vendor/src/events.hpp +76 -0
  45. data/vendor/src/exception.cpp +13 -0
  46. data/vendor/src/exception.hpp +11 -0
  47. data/vendor/src/from_string.cpp +99 -0
  48. data/vendor/src/from_string.hpp +37 -0
  49. data/vendor/src/globals.cpp +6 -0
  50. data/vendor/src/globals.hpp +15 -0
  51. data/vendor/src/http.cpp +93 -0
  52. data/vendor/src/http.hpp +72 -0
  53. data/vendor/src/lexical_cast.hpp +51 -0
  54. data/vendor/src/local_storage.cpp +75 -0
  55. data/vendor/src/local_storage.hpp +53 -0
  56. data/vendor/src/mvc/collection.hpp +154 -0
  57. data/vendor/src/mvc/controller.hpp +59 -0
  58. data/vendor/src/mvc/id_type.hpp +9 -0
  59. data/vendor/src/mvc/layout.hpp +44 -0
  60. data/vendor/src/mvc/model.cpp +89 -0
  61. data/vendor/src/mvc/model.hpp +50 -0
  62. data/vendor/src/object.cpp +71 -0
  63. data/vendor/src/object.hpp +298 -0
  64. data/vendor/src/parse_cookie_values.hpp +12 -0
  65. data/vendor/src/promise.cpp +50 -0
  66. data/vendor/src/promise.hpp +43 -0
  67. data/vendor/src/repeater.hpp +116 -0
  68. data/vendor/src/router.cpp +62 -0
  69. data/vendor/src/router.hpp +34 -0
  70. data/vendor/src/router_base.hpp +107 -0
  71. data/vendor/src/signal.hpp +150 -0
  72. data/vendor/src/slot_element.hpp +61 -0
  73. data/vendor/src/url.cpp +19 -0
  74. data/vendor/src/url.hpp +15 -0
  75. data/vendor/src/window.cpp +22 -0
  76. data/vendor/src/window.hpp +24 -0
  77. metadata +134 -0
@@ -0,0 +1,99 @@
1
+ #include "bindable.hpp"
2
+ #include "globals.hpp"
3
+ #include "from_string.hpp"
4
+
5
+ using namespace Comet;
6
+
7
+ Bindable& Bindable::use_mode(BindMode mode, const std::string& parameter)
8
+ {
9
+ bind_mode = mode;
10
+ switch (mode)
11
+ {
12
+ case ThrottleBind:
13
+ throttle_refresh = Comet::from_string<unsigned long>(parameter);
14
+ break ;
15
+ case SignalBind:
16
+ signal_name = parameter;
17
+ break ;
18
+ case StaticBind:
19
+ break ;
20
+ }
21
+ return *this;
22
+ }
23
+
24
+ void Bindable::enable(Comet::Signal<std::string>& signal)
25
+ {
26
+ enabled = true;
27
+ switch (bind_mode)
28
+ {
29
+ case StaticBind:
30
+ break ;
31
+ case SignalBind:
32
+ listen_to(signal, [this](const std::string& name) {
33
+ if (name == signal_name)
34
+ update();
35
+ });
36
+ break ;
37
+ case ThrottleBind:
38
+ enabled_ptr = std::make_shared<bool>(true);
39
+ throttle_schedule();
40
+ break ;
41
+ }
42
+ update();
43
+ }
44
+
45
+ void Bindable::disable()
46
+ {
47
+ enabled = false;
48
+ switch (bind_mode)
49
+ {
50
+ case StaticBind:
51
+ case ThrottleBind:
52
+ (*enabled_ptr) = false;
53
+ break ;
54
+ case SignalBind:
55
+ stop_listening();
56
+ break ;
57
+ }
58
+ }
59
+
60
+ void Bindable::update()
61
+ {
62
+ if (has_updater)
63
+ {
64
+ __asm__("try {");
65
+ updater();
66
+ __asm__("} catch(error) { console.error('[Comet] failed to update Bindable:', error); }");
67
+ }
68
+ else if (!element.is_undefined())
69
+ {
70
+ if (target == "text")
71
+ element.text(get_value());
72
+ else
73
+ element.attr(target, get_value());
74
+ }
75
+ }
76
+
77
+ std::string Bindable::get_value() const
78
+ {
79
+ std::string value;
80
+
81
+ __asm__("try {");
82
+ value = getter();
83
+ __asm__("} catch (err) { console.warn('failed to update attribute', err); }");
84
+ return value;
85
+ }
86
+
87
+ void Bindable::throttle_schedule()
88
+ {
89
+ std::shared_ptr<bool> _enabled_ptr = enabled_ptr;
90
+
91
+ Comet::window.set_timeout([this, _enabled_ptr]()
92
+ {
93
+ if (*_enabled_ptr)
94
+ {
95
+ update();
96
+ throttle_schedule();
97
+ }
98
+ }, throttle_refresh);
99
+ }
@@ -0,0 +1,106 @@
1
+ #ifndef COMET_BINDABLE_HPP
2
+ # define COMET_BINDABLE_HPP
3
+
4
+ # include "signal.hpp"
5
+ # include "element.hpp"
6
+
7
+ namespace Comet
8
+ {
9
+ struct IBindableView : public Comet::Element
10
+ {
11
+ IBindableView() : Comet::Element("div") {}
12
+ IBindableView(const client::String& tagName) : Comet::Element(tagName) {}
13
+
14
+ virtual void bind_attributes() = 0;
15
+ virtual void trigger_binding_updates() = 0;
16
+ private:
17
+ IBindableView(const IBindableView&) {}
18
+ };
19
+
20
+ struct BindableUpdater
21
+ {
22
+ std::function<void()> func;
23
+
24
+ void execute()
25
+ {
26
+ if (func)
27
+ func();
28
+ else
29
+ el.attr(target, getter());
30
+ }
31
+
32
+ Comet::Element el;
33
+ const std::string target;
34
+ std::function<std::string (void)> getter;
35
+ };
36
+
37
+ class Bindable : public Comet::Listener
38
+ {
39
+ public:
40
+ typedef std::function<std::string (void)> Getter;
41
+
42
+ enum BindMode
43
+ {
44
+ StaticBind,
45
+ SignalBind,
46
+ ThrottleBind
47
+ };
48
+
49
+ private:
50
+ BindMode bind_mode = StaticBind;
51
+ Comet::Element element;
52
+ std::string target;
53
+ Getter getter;
54
+ bool has_updater = false;
55
+ std::function<void()> updater;
56
+
57
+ std::string signal_name;
58
+ unsigned long throttle_refresh;
59
+ bool enabled = false;
60
+ std::shared_ptr<bool> enabled_ptr;
61
+
62
+ public:
63
+ Bindable() {}
64
+ Bindable(Comet::Element el, const std::string& t, Getter g) : element(el), target(t), getter(g) {}
65
+ Bindable(std::function<void ()> func) : has_updater(true), updater(func) {}
66
+
67
+ ~Bindable() { disable(); }
68
+
69
+ inline Bindable& bind_to(Comet::Element el) { element = el; return *this; }
70
+ inline Bindable& on_attribute(const std::string& t, Getter g) { target = t; getter = g; return *this; }
71
+ Bindable& use_mode(BindMode, const std::string& parameter);
72
+
73
+ void enable(Comet::Signal<std::string>& signal);
74
+ void disable();
75
+ void update();
76
+
77
+ private:
78
+ std::string get_value() const;
79
+ void throttle_schedule();
80
+ };
81
+
82
+ class BoundAttributes : public std::vector<Bindable>
83
+ {
84
+ public:
85
+ void update()
86
+ {
87
+ for (Bindable& bindable : *this)
88
+ bindable.update();
89
+ }
90
+
91
+ void enable(Comet::Signal<std::string>& signaler)
92
+ {
93
+ disable();
94
+ for (Bindable& bindable : *this)
95
+ bindable.enable(signaler);
96
+ }
97
+
98
+ void disable()
99
+ {
100
+ for (Bindable& bindable : *this)
101
+ bindable.disable();
102
+ }
103
+ };
104
+ }
105
+
106
+ #endif
@@ -0,0 +1,58 @@
1
+ #include "parse_cookie_values.hpp"
2
+ #include "url.hpp"
3
+ #include <regex>
4
+ #include <iostream>
5
+
6
+ using namespace std;
7
+
8
+ static bool trigger_add_cookie_value(const string& str, std::function<bool (const string&, const string&)> callback, size_t key_start, size_t key_end, size_t val_start, size_t val_end)
9
+ {
10
+ string key = str.substr(key_start, key_end - key_start);
11
+ string val = str.substr(val_start, val_end - val_start);
12
+ key = Comet::Url::decode(key);
13
+ val = Comet::Url::decode(val);
14
+ return callback(key, val);
15
+ }
16
+
17
+ namespace Comet
18
+ {
19
+ void parse_cookie_values(const string& str, std::function<bool (const std::string&, const std::string&)> callback)
20
+ {
21
+ char state = 0;
22
+ size_t key_start = 0;
23
+ size_t key_end = 0;
24
+ size_t val_start = 0;
25
+
26
+ for (size_t i = 0 ; i < str.size() ; ++i)
27
+ {
28
+ switch (state)
29
+ {
30
+ case 0: // spaces
31
+ if (str[i] == ' ') continue ;
32
+ key_start = i;
33
+ state++;
34
+ case 1: // key
35
+ if (str[i] == '=')
36
+ {
37
+ key_end = i;
38
+ val_start = i + 1;
39
+ state++;
40
+ }
41
+ break ;
42
+ case 2: // value
43
+ if (str[i] == ';')
44
+ {
45
+ state = 0;
46
+ if (!(trigger_add_cookie_value(str, callback,
47
+ key_start, key_end, val_start, i)))
48
+ return ;
49
+ }
50
+ }
51
+ }
52
+ if (state == 2)
53
+ {
54
+ trigger_add_cookie_value(str, callback,
55
+ key_start, key_end, val_start, str.size());
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,11 @@
1
+ #include "comment_element.hpp"
2
+ #include "globals.hpp"
3
+
4
+ using namespace Comet;
5
+
6
+ client::HTMLElement* CommentElement::makeCommentElement(const client::String& str)
7
+ {
8
+ client::Comment* comment = Comet::document->createComment(str);
9
+
10
+ return reinterpret_cast<client::HTMLElement*>(comment);
11
+ }
@@ -0,0 +1,17 @@
1
+ #ifndef COMET_COMMENT_ELEMENT_HPP
2
+ # define COMET_COMMENT_ELEMENT_HPP
3
+
4
+ # include "element.hpp"
5
+
6
+ namespace Comet
7
+ {
8
+ class CommentElement : public Comet::Element
9
+ {
10
+ static client::HTMLElement* makeCommentElement(const client::String&);
11
+ public:
12
+ CommentElement(const client::String& str) : Element(makeCommentElement(str)) {}
13
+ CommentElement() : Element(makeCommentElement("")) {}
14
+ };
15
+ }
16
+
17
+ #endif
@@ -0,0 +1,94 @@
1
+ #include "cookies.hpp"
2
+ #include "exception.hpp"
3
+ #include "object.hpp"
4
+ #include "url.hpp"
5
+ #include "parse_cookie_values.hpp"
6
+ #include <cheerp/client.h>
7
+ #include <cheerp/clientlib.h>
8
+
9
+ using namespace Comet;
10
+ using namespace std;
11
+
12
+ Comet::Cookies cookies;
13
+
14
+ bool Cookies::has(const string& key)
15
+ {
16
+ ensure_cookie_map_is_updated();
17
+ return cookie_store.find(key) != cookie_store.end();
18
+ }
19
+
20
+ template<>
21
+ string Cookies::get<string>(const string& key)
22
+ {
23
+ ensure_cookie_map_is_updated();
24
+ if (!has(key))
25
+ Comet::raise(std::runtime_error("cookie `" + key + "` does not exist"));
26
+ return cookie_store.at(key);
27
+ }
28
+
29
+ template<>
30
+ void Cookies::set<string>(const string& key, const string& val)
31
+ {
32
+ ensure_cookie_map_is_updated();
33
+ if (has(key))
34
+ cookie_store.at(key) = val;
35
+ else
36
+ cookie_store.insert(pair<string, string>(key, val));
37
+ set_cookie_string(
38
+ Url::encode(key) + '=' + Url::encode(val)
39
+ );
40
+ }
41
+
42
+ template<>
43
+ void Cookies::set<string>(const string& key, const string& val, time_t expires_in)
44
+ {
45
+ string time_string;
46
+
47
+ ensure_cookie_map_is_updated();
48
+ if (has(key))
49
+ cookie_store.at(key) = val;
50
+ else
51
+ cookie_store.insert(pair<string, string>(key, val));
52
+ if (expires_in > 0)
53
+ {
54
+ ObjectImpl<client::Date> date;
55
+ double expires_time = date->getTime() + expires_in * 1000;
56
+
57
+ date->setTime(expires_time);
58
+ time_string = "; expires=" + (string)date.apply("toGMTString");
59
+ }
60
+ set_cookie_string(
61
+ Url::encode(key) + '=' + Url::encode(val) + time_string
62
+ );
63
+ }
64
+
65
+ void Cookies::remove(const string& key)
66
+ {
67
+ ensure_cookie_map_is_updated();
68
+ cookie_store.erase(key);
69
+ set_cookie_string(
70
+ Url::encode(key) + "=null; expires=Sat, 05 Nov 2016 00:00:00 GMT"
71
+ );
72
+ last_cookie_string = get_cookie_string();
73
+ }
74
+
75
+ void Cookies::update_cookie_map()
76
+ {
77
+ last_cookie_string = get_cookie_string();
78
+ cookie_store.clear();
79
+ Comet::parse_cookie_values(last_cookie_string,
80
+ [this](const string& key, const string& value) {
81
+ cookie_store.emplace(key, value);
82
+ return true;
83
+ });
84
+ }
85
+
86
+ string Cookies::get_cookie_string() const
87
+ {
88
+ return (string)(*client::document.get_cookie());
89
+ }
90
+
91
+ void Cookies::set_cookie_string(const string& str) const
92
+ {
93
+ client::document.set_cookie(str.c_str());
94
+ }
@@ -0,0 +1,60 @@
1
+ #ifndef CRAILS_FRONT_COOKIES_HPP
2
+ # define CRAILS_FRONT_COOKIES_HPP
3
+
4
+ # include "from_string.hpp"
5
+ # include <string>
6
+ # include <map>
7
+ # include <ctime>
8
+
9
+ namespace Comet
10
+ {
11
+ class Cookies
12
+ {
13
+ typedef std::map<std::string, std::string> CookieMap;
14
+ public:
15
+ bool has(const std::string& key);
16
+ void remove(const std::string& key);
17
+
18
+ template<typename TYPE>
19
+ TYPE get(const std::string& key)
20
+ {
21
+ std::string val = get<std::string>(key);
22
+
23
+ return Comet::from_string<TYPE>(val);
24
+ }
25
+
26
+ template<typename TYPE>
27
+ void set(const std::string& key, const TYPE& val)
28
+ {
29
+ set(key, std::to_string(val), 0);
30
+ }
31
+
32
+ template<typename TYPE>
33
+ void set(const std::string& key, const TYPE& val, std::time_t expires_in)
34
+ {
35
+ set(key, std::to_string(val), expires_in);
36
+ }
37
+
38
+ private:
39
+ std::string get_cookie_string() const;
40
+ void set_cookie_string(const std::string&) const;
41
+
42
+ inline void ensure_cookie_map_is_updated()
43
+ {
44
+ if (last_cookie_string != get_cookie_string())
45
+ update_cookie_map();
46
+ }
47
+
48
+ void update_cookie_map();
49
+
50
+ CookieMap cookie_store;
51
+ std::string last_cookie_string;
52
+ };
53
+
54
+ template<>
55
+ std::string Cookies::get<std::string>(const std::string& key);
56
+ template<>
57
+ void Cookies::set(const std::string& key, const std::string& val, std::time_t);
58
+ }
59
+
60
+ #endif
@@ -0,0 +1,61 @@
1
+ #ifndef COMET_HTML_TEMPLATE_HPP
2
+ # define COMET_HTML_TEMPLATE_HPP
3
+
4
+ # include "bindable.hpp"
5
+ # include "element.hpp"
6
+
7
+ namespace Comet
8
+ {
9
+ class BindableEngineCommon : public IBindableView
10
+ {
11
+ protected:
12
+ Comet::BoundAttributes bound_attributes;
13
+ virtual Comet::Signal<std::string>& get_signaler() = 0;
14
+
15
+ public:
16
+ BindableEngineCommon(const client::String& tagName) : IBindableView(tagName) {}
17
+ BindableEngineCommon() {}
18
+
19
+ virtual void bind_attributes()
20
+ {
21
+ bound_attributes.enable(get_signaler());
22
+ }
23
+
24
+ virtual void trigger_binding_updates()
25
+ {
26
+ bound_attributes.update();
27
+ }
28
+ };
29
+
30
+ class BindableEngine : public BindableEngineCommon
31
+ {
32
+ public:
33
+ BindableEngine(const client::String& tagName) : BindableEngineCommon(tagName) {}
34
+ BindableEngine() {}
35
+
36
+ Comet::Signal<std::string> signaler;
37
+ protected:
38
+ Comet::Signal<std::string>& get_signaler() { return signaler; }
39
+
40
+ };
41
+
42
+ class BindableEngineClient : public BindableEngineCommon
43
+ {
44
+ public:
45
+ BindableEngineClient(const client::String& tagName, Comet::Signal<std::string>& s) : BindableEngineCommon(tagName), signaler(s) {}
46
+ BindableEngineClient(Comet::Signal<std::string>& s) : signaler(s) {}
47
+
48
+ Comet::Signal<std::string>& signaler;
49
+ protected:
50
+ Comet::Signal<std::string>& get_signaler() { return signaler; }
51
+ };
52
+
53
+ class CustomElement : public BindableEngine
54
+ {
55
+ public:
56
+ CustomElement(const client::String& tagName) : BindableEngine(tagName) {}
57
+ CustomElement() {}
58
+ };
59
+ }
60
+
61
+ #endif
@@ -0,0 +1,198 @@
1
+ #include "datatree.hpp"
2
+ #include "globals.hpp"
3
+ #include "exception.hpp"
4
+ #include <iostream>
5
+
6
+ using namespace std;
7
+
8
+ DataTree& DataTree::from_json(stringstream& stream)
9
+ {
10
+ return from_json(stream.str());
11
+ }
12
+
13
+ DataTree& DataTree::from_json(const string& str)
14
+ {
15
+ Comet::String js_str(str);
16
+
17
+ tree = Comet::Object::from_json(*js_str);
18
+ return *this;
19
+ }
20
+
21
+ DataTree& DataTree::from_json_file(const string&)
22
+ {
23
+ Comet::raise(std::logic_error("DataTree::from_json_file not available from Comet.cpp"));
24
+ return *this;
25
+ }
26
+
27
+ string DataTree::to_json() const
28
+ {
29
+ return tree.to_json();
30
+ }
31
+
32
+ void Data::each(function<bool (Data)> functor)
33
+ {
34
+ for (auto _key : get_keys())
35
+ {
36
+ Data data(as_object(), _key);
37
+
38
+ if (!(functor(data)))
39
+ break ;
40
+ }
41
+ }
42
+
43
+ void Data::each(function<bool (const Data)> functor) const
44
+ {
45
+ for (auto _key : get_keys())
46
+ {
47
+ const Data data(as_object(), _key);
48
+
49
+ if (!(functor(data)))
50
+ break ;
51
+ }
52
+ }
53
+
54
+ Data Data::at(unsigned int i) const
55
+ {
56
+ std::stringstream stream;
57
+ std::string stringified;
58
+
59
+ stream << i;
60
+ stream >> stringified;
61
+ return Data(as_object(), stringified);
62
+ }
63
+
64
+ bool Data::exists() const
65
+ {
66
+ if (key.length())
67
+ {
68
+ Comet::String js_key(key);
69
+
70
+ return object->hasOwnProperty(*js_key);
71
+ }
72
+ return true;
73
+ }
74
+
75
+ bool Data::is_blank() const
76
+ {
77
+ return !exists() || as<string>() == "";
78
+ }
79
+
80
+ bool Data::is_null() const
81
+ {
82
+ return !exists() || as<string>() == "null";
83
+ }
84
+
85
+ vector<string> Data::get_keys() const
86
+ {
87
+ return Comet::window["Object"].apply("keys", as_object());
88
+ }
89
+
90
+ vector<string> Data::find_missing_keys(const vector<string>& keys) const
91
+ {
92
+ vector<string> missing_keys;
93
+ string path_prefix;
94
+
95
+ for (string key : keys)
96
+ {
97
+ Comet::String js_key(key);
98
+
99
+ if (!(as_object()->hasOwnProperty(*js_key)))
100
+ missing_keys.push_back(key);
101
+ }
102
+ return missing_keys;
103
+ }
104
+
105
+ bool Data::require(const vector<string>& keys) const
106
+ {
107
+ return find_missing_keys(keys).size() == 0;
108
+ }
109
+
110
+ bool Data::is_array() const
111
+ {
112
+ return *(as_object()["constructor"]) == *(Comet::window["Array"]);
113
+ }
114
+
115
+ void Data::merge(Data data)
116
+ {
117
+ if (data.exists())
118
+ {
119
+ if (key.length() > 0)
120
+ {
121
+ if (data.is_array())
122
+ object.set(key, data.as_object().apply("slice", 0));
123
+ else
124
+ object.set(key, Comet::Object::from_json(data.as_object().to_json()));
125
+ }
126
+ else
127
+ {
128
+ for (const auto& key : data.get_keys())
129
+ (*this)[key].merge(data[key]);
130
+ }
131
+ }
132
+ }
133
+
134
+ void Data::merge(DataTree datatree)
135
+ {
136
+ merge(datatree.as_data());
137
+ }
138
+
139
+ void Data::output(ostream& out) const
140
+ {
141
+ out << to_json();
142
+ }
143
+
144
+ string Data::to_json() const
145
+ {
146
+ return as_object().to_json();
147
+ }
148
+
149
+ string Data::to_xml() const
150
+ {
151
+ Comet::raise(std::logic_error("Data::to_xml not available from Comet.cpp"));
152
+ return "";
153
+ }
154
+
155
+ size_t Data::count() const
156
+ {
157
+ if (is_array())
158
+ return as_object()["length"];
159
+ return get_keys().size();
160
+ }
161
+
162
+ void Data::destroy()
163
+ {
164
+ if (key.length() > 0)
165
+ object.unset(key);
166
+ else
167
+ {
168
+ for (auto subkey : get_keys())
169
+ object.unset(subkey);
170
+ }
171
+ }
172
+
173
+ template<>
174
+ bool Data::as<bool>() const
175
+ {
176
+ std::string as_string = as_object().apply("toString");
177
+ std::stringstream stream;
178
+ int numerical_value;
179
+
180
+ if (as_string == "true" || as_string == "false")
181
+ return as_string == "true";
182
+ stream << as_string;
183
+ stream >> numerical_value;
184
+ return numerical_value != 0;
185
+ }
186
+
187
+ template<>
188
+ string Data::as<string>() const
189
+ {
190
+ return as_object().apply("toString");
191
+ }
192
+
193
+
194
+ template<>
195
+ wstring Data::as<wstring>() const
196
+ {
197
+ return as_object().apply("toString");
198
+ }