Skip to content

Commit 0747f45

Browse files
committed
types in simple_dom
1 parent d9c371a commit 0747f45

4 files changed

Lines changed: 47 additions & 15 deletions

File tree

ecosystem/simple_dom.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,15 @@ struct JHandler : public BaseReaderHandler<UTF8<>, JHandler> {
188188
JNode* get_root() {
189189
return _root;
190190
}
191-
void emplace_back(const char* s, size_t length) {
191+
void emplace_back(const char* s, size_t length, uint8_t type) {
192192
str val{s, length}; // _key may be empty()
193193
_nodes.back().emplace_back(_key, val, _root);
194+
_nodes.back().back().set_type(type);
194195
// LOG_DEBUG(_key, ": ", val);
195196
_key = {};
196197
}
197198
bool Null() {
198-
emplace_back(0, 0);
199+
emplace_back(0, 0, JNode::null);
199200
return true;
200201
}
201202
bool Key(const char* s, SizeType len, bool copy) {
@@ -205,22 +206,22 @@ struct JHandler : public BaseReaderHandler<UTF8<>, JHandler> {
205206
}
206207
bool String(const char* s, SizeType len, bool copy) {
207208
assert(!copy);
208-
emplace_back(s, len);
209+
emplace_back(s, len, JNode::STRING);
209210
return true;
210211
}
211212
bool RawNumber(const Ch* s, SizeType len, bool copy) {
212213
assert(!copy);
213214
// LOG_DEBUG(ALogString(s, len));
214-
emplace_back(s, len);
215+
emplace_back(s, len, JNode::NUMBER);
215216
return true;
216217
}
217218
bool RawBool(const Ch* s, SizeType len, bool copy) {
218219
assert(!copy);
219-
emplace_back(s, len);
220+
emplace_back(s, len, JNode::BOOLEAN);
220221
return true;
221222
}
222223
bool StartObject() {
223-
emplace_back(0, 0);
224+
emplace_back(0, 0, JNode::OBJECT);
224225
_nodes.emplace_back();
225226
return true;
226227
}
@@ -237,7 +238,7 @@ struct JHandler : public BaseReaderHandler<UTF8<>, JHandler> {
237238
_nodes.back().back().set_children(std::move(temp), _indexing);
238239
}
239240
bool StartArray() {
240-
emplace_back(0, 0);
241+
emplace_back(0, 0, JNode::ARRAY);
241242
_nodes.emplace_back();
242243
return true;
243244
}

ecosystem/simple_dom.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class Node {
8080
const char* text_begin() const { IF_RET(_impl->get_root()->_text_begin); }
8181
str key(const char* b) const { IF_RET(_impl->get_key(b)); }
8282
str value(const char* b) const { IF_RET(_impl->get_value(b)); }
83+
uint8_t type() const { IF_RET(_impl->get_type()); }
84+
uint8_t get_type() const { IF_RET(_impl->get_type()); }
8385
bool valid() const { return _impl; }
8486
operator bool() const { return _impl; }
8587
size_t num_children() const { IF_RET(_impl->num_children()); }
@@ -97,6 +99,7 @@ class Node {
9799
double to_double(double def_val = NAN) const {
98100
return value().to_double(def_val);
99101
}
102+
using TYPE = NodeImpl::TYPE;
100103

101104
bool operator==(str rhs) const { return value() == rhs; }
102105
bool operator!=(str rhs) const { return value() != rhs; }

ecosystem/simple_dom_impl.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,24 +48,31 @@ class NodeImpl : public Object {
4848
const static size_t MAX_VALUE_OFFSET = 4095;
4949
const static size_t MAX_VALUE_LENGTH = MAX_KEY_OFFSET;
5050

51+
enum TYPE : uint8_t {STRING, NUMBER, null, BOOLEAN, OBJECT, ARRAY};
52+
53+
union {
54+
const char* _text_begin; // addr of the text (only for root node)
55+
const NodeImpl* _root; // root node (only for non-root nodes)
56+
};
5157
union { struct { // for non-root nodes
52-
struct {
53-
uint8_t _flags;
54-
uint16_t _k_len : 12; // key length (12 bits)
55-
uint16_t _v_off : 12; // value offset (12 bits) to key end
56-
}__attribute__((packed));
57-
const NodeImpl* _root; // root node
58-
}; // packed as 20 bytes
58+
uint8_t _flags;
59+
uint16_t _k_len : 12; // key length (12 bits)
60+
uint16_t _v_off : 12; // value offset (12 bits) to key end
61+
}__attribute__((packed));
5962
struct { // for the root node
6063
uint8_t _flags_; // the same as _flags
6164
uint8_t _node_size; // sizeof(the node implementation)
6265
mutable uint16_t _refcnt; // reference counter of the document
63-
const char* _text_begin;
6466
}; };
6567
uint32_t _k_off; // key offset to _text_begin
6668
uint32_t _v_len; // value length
6769
uint32_t _nchildren; // for all nodes
6870

71+
void set_type(uint8_t type) {
72+
_flags &= (1 << 5) - 1;
73+
_flags |= (type & 0x7) << 5;
74+
}
75+
6976
using AT16 = std::atomic<uint16_t>;
7077
static_assert(sizeof(AT16) == sizeof(_refcnt), "...");
7178

@@ -102,6 +109,9 @@ struct { // for the root node
102109
bool is_root() const {
103110
return _flags & FLAG_IS_ROOT;
104111
}
112+
uint8_t get_type() const {
113+
return _flags >> 5;
114+
}
105115
const NodeImpl* get_root() const {
106116
return is_root() ? this : _root;
107117
}
@@ -139,6 +149,7 @@ struct { // for the root node
139149
int init_non_root(str key, str value, const NodeImpl* root, uint32_t flags);
140150
};
141151

152+
static_assert(sizeof(NodeImpl) == 32, "");
142153

143154
}
144155
}

ecosystem/test/test_simple_dom.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ void expect_eq_vals(Node node, const char * const (&truth)[N]) {
177177
expect_eq_vals(node, truth, N);
178178
}
179179

180+
void expect_types(Node node, const std::pair<const char*, uint8_t>* truth, size_t n) {
181+
for (size_t i = 0; i < n; ++i) {
182+
auto val = node[truth[i].first];
183+
EXPECT_EQ(val.type(), truth[i].second);
184+
}
185+
}
186+
187+
template<size_t N> inline
188+
void expect_types(Node node, const std::pair<const char*, uint8_t> (&truth)[N]) {
189+
return expect_types(node, truth, N);
190+
}
191+
180192
TEST(simple_dom, json) {
181193
const static char json0[] = R"({
182194
"hello": "world",
@@ -196,6 +208,11 @@ TEST(simple_dom, json) {
196208
{"i", "-123"},
197209
{"pi", "3.1416"},
198210
});
211+
using TYPE = Node::TYPE;
212+
expect_types(doc, {{"hello", TYPE::STRING}, {"t", TYPE::BOOLEAN},
213+
{"f", TYPE::BOOLEAN}, {"n", TYPE::null},
214+
{"i", TYPE::NUMBER}, {"pi", TYPE::NUMBER},
215+
{"a", TYPE::ARRAY}});
199216
EXPECT_EQ(doc["i"].to_int64_t(), -123);
200217
EXPECT_NEAR(doc["pi"].to_double(), 3.1416, 1e-5);
201218
expect_eq_vals(doc["a"], {"1", "2", "3", "4"});

0 commit comments

Comments
 (0)