Instrument Neutral Distributed Interface INDI  1.9.5
gason.h
Go to the documentation of this file.
1 /*
2 The MIT License (MIT)
3 
4 Copyright (c) 2013-2015 Ivan Vashchaev
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in
8 the Software without restriction, including without limitation the rights to
9 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 the Software, and to permit persons to whom the Software is furnished to do so,
11 subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 
24 #pragma once
25 
26 #include <cassert>
27 #include <cstddef>
28 #include <cstdint>
29 
30 enum JsonTag
31 {
38  JSON_NULL = 0xF
39 };
40 
41 struct JsonNode;
42 
43 #define JSON_VALUE_PAYLOAD_MASK 0x00007FFFFFFFFFFFULL
44 #define JSON_VALUE_NAN_MASK 0x7FF8000000000000ULL
45 #define JSON_VALUE_TAG_MASK 0xF
46 #define JSON_VALUE_TAG_SHIFT 47
47 
48 union JsonValue {
49  uint64_t ival;
50  double fval;
51 
52  JsonValue(double x) : fval(x) {}
53  JsonValue(JsonTag tag = JSON_NULL, void *payload = nullptr)
54  {
55 #if !defined(__arm__)
56  assert((uint64_t)(uintptr_t)payload <= JSON_VALUE_PAYLOAD_MASK);
57 #endif
58  ival = JSON_VALUE_NAN_MASK | ((uint64_t)tag << JSON_VALUE_TAG_SHIFT) | (uintptr_t)payload;
59  }
60  bool isDouble() const { return (int64_t)ival <= (int64_t)JSON_VALUE_NAN_MASK; }
61  JsonTag getTag() const
62  {
64  }
65  uint64_t getPayload() const
66  {
67  assert(!isDouble());
69  }
70  double toNumber() const
71  {
72  assert(getTag() == JSON_NUMBER);
73  return fval;
74  }
75  char *toString() const
76  {
77  assert(getTag() == JSON_STRING);
78  return (char *)getPayload();
79  }
80  JsonNode *toNode() const
81  {
82  assert(getTag() == JSON_ARRAY || getTag() == JSON_OBJECT);
83  return (JsonNode *)getPayload();
84  }
85 };
86 
87 struct JsonNode
88 {
91  char *key;
92 };
93 
95 {
97 
98  void operator++() { p = p->next; }
99  bool operator!=(const JsonIterator &x) const { return p != x.p; }
100  JsonNode *operator*() const { return p; }
101  JsonNode *operator->() const { return p; }
102 };
103 
105 {
106  return JsonIterator{ o.toNode() };
107 }
109 {
110  return JsonIterator{ nullptr };
111 }
112 
113 #define JSON_ERRNO_MAP(XX) \
114  XX(OK, "ok") \
115  XX(BAD_NUMBER, "bad number") \
116  XX(BAD_STRING, "bad string") \
117  XX(BAD_IDENTIFIER, "bad identifier") \
118  XX(STACK_OVERFLOW, "stack overflow") \
119  XX(STACK_UNDERFLOW, "stack underflow") \
120  XX(MISMATCH_BRACKET, "mismatch bracket") \
121  XX(UNEXPECTED_CHARACTER, "unexpected character") \
122  XX(UNQUOTED_KEY, "unquoted key") \
123  XX(BREAKING_BAD, "breaking bad") \
124  XX(ALLOCATION_FAILURE, "allocation failure")
125 
127 {
128 #define XX(no, str) JSON_##no,
130 #undef XX
131 };
132 
133 const char *jsonStrError(int err);
134 
136 {
137  struct Zone
138  {
139  Zone *next;
140  size_t used;
141  } *head = nullptr;
142 
143  public:
144  JsonAllocator() = default;
145  JsonAllocator(const JsonAllocator &) = delete;
146  JsonAllocator &operator=(const JsonAllocator &) = delete;
147  JsonAllocator(JsonAllocator &&x) : head(x.head) { x.head = nullptr; }
149  {
150  head = x.head;
151  x.head = nullptr;
152  return *this;
153  }
155  void *allocate(size_t size);
156  void deallocate();
157 };
158 
159 int jsonParse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator);
JSON_FALSE
@ JSON_FALSE
Definition: gason.h:37
JSON_NUMBER
@ JSON_NUMBER
Definition: gason.h:32
JsonNode::next
JsonNode * next
Definition: gason.h:90
JsonAllocator::operator=
JsonAllocator & operator=(JsonAllocator &&x)
Definition: gason.h:148
JSON_VALUE_PAYLOAD_MASK
#define JSON_VALUE_PAYLOAD_MASK
Definition: gason.h:43
JsonIterator::operator->
JsonNode * operator->() const
Definition: gason.h:101
JsonValue::fval
double fval
Definition: gason.h:50
JsonIterator::operator++
void operator++()
Definition: gason.h:98
JsonValue::isDouble
bool isDouble() const
Definition: gason.h:60
JsonValue::getTag
JsonTag getTag() const
Definition: gason.h:61
JsonValue
Definition: gason.h:48
JSON_ERRNO_MAP
#define JSON_ERRNO_MAP(XX)
Definition: gason.h:113
JsonValue::toNode
JsonNode * toNode() const
Definition: gason.h:80
JsonValue::JsonValue
JsonValue(JsonTag tag=JSON_NULL, void *payload=nullptr)
Definition: gason.h:53
JsonAllocator::operator=
JsonAllocator & operator=(const JsonAllocator &)=delete
XX
#define XX(no, str)
Definition: gason.h:128
JsonAllocator::allocate
void * allocate(size_t size)
Definition: gason.cpp:45
JSON_NULL
@ JSON_NULL
Definition: gason.h:38
JSON_VALUE_NAN_MASK
#define JSON_VALUE_NAN_MASK
Definition: gason.h:44
JSON_OBJECT
@ JSON_OBJECT
Definition: gason.h:35
JsonAllocator
Definition: gason.h:135
JsonIterator::p
JsonNode * p
Definition: gason.h:96
JsonValue::JsonValue
JsonValue(double x)
Definition: gason.h:52
JsonAllocator::~JsonAllocator
~JsonAllocator()
Definition: gason.h:154
begin
JsonIterator begin(JsonValue o)
Definition: gason.h:104
JsonAllocator::JsonAllocator
JsonAllocator()=default
JsonNode::value
JsonValue value
Definition: gason.h:89
JsonIterator::operator!=
bool operator!=(const JsonIterator &x) const
Definition: gason.h:99
JsonAllocator::JsonAllocator
JsonAllocator(JsonAllocator &&x)
Definition: gason.h:147
JsonValue::ival
uint64_t ival
Definition: gason.h:49
JsonValue::getPayload
uint64_t getPayload() const
Definition: gason.h:65
JsonAllocator::deallocate
void deallocate()
Definition: gason.cpp:74
end
JsonIterator end(JsonValue)
Definition: gason.h:108
jsonParse
int jsonParse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator)
Definition: gason.cpp:182
JsonIterator::operator*
JsonNode * operator*() const
Definition: gason.h:100
JsonErrno
JsonErrno
Definition: gason.h:126
JSON_STRING
@ JSON_STRING
Definition: gason.h:33
JSON_VALUE_TAG_MASK
#define JSON_VALUE_TAG_MASK
Definition: gason.h:45
JSON_TRUE
@ JSON_TRUE
Definition: gason.h:36
JSON_VALUE_TAG_SHIFT
#define JSON_VALUE_TAG_SHIFT
Definition: gason.h:46
JsonTag
JsonTag
Definition: gason.h:30
JsonIterator
Definition: gason.h:94
JsonValue::toString
char * toString() const
Definition: gason.h:75
JsonValue::toNumber
double toNumber() const
Definition: gason.h:70
jsonStrError
const char * jsonStrError(int err)
Definition: gason.cpp:31
JsonNode::key
char * key
Definition: gason.h:91
JsonNode
Definition: gason.h:87
JSON_ARRAY
@ JSON_ARRAY
Definition: gason.h:34