The R Project SVN R-packages

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7747 ripley 1
#include "JSONNode.h"
2
 
3
#define IMPLEMENT_CTOR(type)\
4
    JSONNode::JSONNode(const json_string & name_t, type value_t) json_nothrow : internal(internalJSONNode::newInternal()){\
5
	   internal -> Set(value_t);\
6
	   internal -> setname(name_t);\
7
	   LIBJSON_CTOR;\
8
    }
9
IMPLEMENT_FOR_ALL_TYPES(IMPLEMENT_CTOR)
10
 
11
#ifndef JSON_LIBRARY
12
    JSONNode::JSONNode(const json_string & name_t, const json_char * value_t) json_nothrow : internal(internalJSONNode::newInternal()){
13
	   internal -> Set(json_string(value_t));
14
	   internal -> setname(name_t);
15
	   LIBJSON_CTOR;
16
    }
17
#endif
18
 
19
#if (defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY))
20
    #include "JSONWorker.h"
21
    JSONNode JSONNode::stringType(const json_string & str){
22
        JSONNode res;
23
        res.set_name(json_global(EMPTY_JSON_STRING));
24
        #ifdef JSON_LESS_MEMORY
25
            res = JSONWorker::FixString(str, res.internal, false);
26
        #else
27
            res = JSONWorker::FixString(str, res.internal -> _string_encoded);
28
        #endif
29
        return res;
30
    }
31
 
32
    void JSONNode::set_name_(const json_string & newname) json_nothrow {
33
        #ifdef JSON_LESS_MEMORY
34
            json_string _newname = JSONWorker::FixString(newname, internal, true);
35
        #else
36
            json_string _newname = JSONWorker::FixString(newname, internal -> _name_encoded);
37
        #endif
38
        set_name(_newname);
39
    }
40
#endif
41
 
42
#ifdef JSON_CASTABLE
43
    JSONNode JSONNode::as_node(void) const json_nothrow {
44
	   JSON_CHECK_INTERNAL();
45
	   if (type() == JSON_NODE){
46
		  return *this;
47
	   } else if (type() == JSON_ARRAY){
48
		  JSONNode res(duplicate());
49
		  res.internal -> _type = JSON_NODE;
50
		  return res;
51
	   }
52
	   #ifdef JSON_MUTEX_CALLBACKS
53
		  if (internal -> mylock != 0){
54
			 JSONNode res(JSON_NODE);
55
			 res.set_mutex(internal -> mylock);
56
			 return res;
57
		  }
58
	   #endif
59
	   return JSONNode(JSON_NODE);
60
    }
61
 
62
    JSONNode JSONNode::as_array(void) const json_nothrow {
63
	   JSON_CHECK_INTERNAL();
64
	   if (type() == JSON_ARRAY){
65
		  return *this;
66
	   } else if (type() == JSON_NODE){
67
		  JSONNode res(duplicate());
68
		  res.internal -> _type = JSON_ARRAY;
69
		  json_foreach(res.internal -> CHILDREN, runner){
70
			 (*runner) -> clear_name();
71
		  }
72
		  return res;
73
	   }
74
	   #ifdef JSON_MUTEX_CALLBACKS
75
		  if (internal -> mylock != 0){
76
			 JSONNode res(JSON_ARRAY);
77
			 res.set_mutex(internal -> mylock);
78
			 return res;
79
		  }
80
	   #endif
81
	   return JSONNode(JSON_ARRAY);
82
    }
83
 
84
    void JSONNode::cast(char newtype) json_nothrow {
85
	   JSON_CHECK_INTERNAL();
86
	   if (newtype == type()) return;
87
 
88
	   switch(newtype){
89
		  case JSON_NULL:
90
			 nullify();
91
			 return;
92
		  case JSON_STRING:
93
			 *this = as_string();
94
			 return;
95
		  case JSON_NUMBER:
96
			 *this = as_float();
97
			 return;
98
		  case JSON_BOOL:
99
			 *this = as_bool();
100
			 return;
101
		  case JSON_ARRAY:
102
			 *this = as_array();
103
			 return;
104
		  case JSON_NODE:
105
			 *this = as_node();
106
			 return;
107
	   }
108
	   JSON_FAIL(JSON_TEXT("cast to unknown type"));
109
    }
110
#endif
111
 
112
//different just to supress the warning
113
#ifdef JSON_REF_COUNT
114
void JSONNode::merge(JSONNode & other) json_nothrow {
115
#else
116
void JSONNode::merge(JSONNode &) json_nothrow {
117
#endif
118
    JSON_CHECK_INTERNAL();
119
    #ifdef JSON_REF_COUNT
120
	   if (internal == other.internal) return;
121
	   JSON_ASSERT(*this == other, JSON_TEXT("merging two nodes that aren't equal"));
122
	   if (internal -> refcount < other.internal -> refcount){
123
		  *this = other;
124
	   } else {
125
		  other = *this;
126
	   }
127
    #endif
128
}
129
 
130
#ifdef JSON_REF_COUNT
131
    void JSONNode::merge(JSONNode * other) json_nothrow {
132
	   JSON_CHECK_INTERNAL();
133
	   if (internal == other -> internal) return;
134
	   *other = *this;
135
    }
136
 
137
    //different just to supress the warning
138
    void JSONNode::merge(unsigned int num, ...) json_nothrow {
139
#else
140
    void JSONNode::merge(unsigned int, ...) json_nothrow {
141
#endif
142
    JSON_CHECK_INTERNAL();
143
    #ifdef JSON_REF_COUNT
144
	   va_list args;
145
	   va_start(args, num);
146
	   for(unsigned int i = 0; i < num; ++i){
147
		  merge(va_arg(args, JSONNode*));
148
	   }
149
	   va_end(args);
150
    #endif
151
}
152
 
153
JSONNode JSONNode::duplicate(void) const json_nothrow {
154
    JSON_CHECK_INTERNAL();
155
    JSONNode mycopy(*this);
156
    #ifdef JSON_REF_COUNT
157
	   JSON_ASSERT(internal == mycopy.internal, JSON_TEXT("copy ctor failed to ref count correctly"));
158
	   mycopy.makeUniqueInternal();
159
    #endif
160
    JSON_ASSERT(internal != mycopy.internal, JSON_TEXT("makeUniqueInternal failed"));
161
    return mycopy;
162
}
163
 
164
JSONNode & JSONNode::at(json_index_t pos) json_throws(std::out_of_range) {
165
    JSON_CHECK_INTERNAL();
166
    if (json_unlikely(pos >= internal -> size())){
167
	   JSON_FAIL(JSON_TEXT("at() out of bounds"));
168
	   json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
169
    }
170
    return (*this)[pos];
171
}
172
 
173
const JSONNode & JSONNode::at(json_index_t pos) const json_throws(std::out_of_range) {
174
    JSON_CHECK_INTERNAL();
175
    if (json_unlikely(pos >= internal -> size())){
176
	   JSON_FAIL(JSON_TEXT("at() const out of bounds"));
177
	   json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
178
    }
179
    return (*this)[pos];
180
}
181
 
182
JSONNode & JSONNode::operator[](json_index_t pos) json_nothrow {
183
    JSON_CHECK_INTERNAL();
184
    JSON_ASSERT(pos < internal -> size(), JSON_TEXT("[] out of bounds"));
185
    makeUniqueInternal();
186
    return *(internal -> at(pos));
187
}
188
 
189
const JSONNode & JSONNode::operator[](json_index_t pos) const json_nothrow {
190
    JSON_CHECK_INTERNAL();
191
    JSON_ASSERT(pos < internal -> size(), JSON_TEXT("[] const out of bounds"));
192
    return *(internal -> at(pos));
193
}
194
 
195
JSONNode & JSONNode::at(const json_string & name_t) json_throws(std::out_of_range) {
196
    JSON_CHECK_INTERNAL();
197
    JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at"));
198
    makeUniqueInternal();
199
    if (JSONNode ** res = internal -> at(name_t)){
200
	   return *(*res);
201
    }
202
    JSON_FAIL(json_string(JSON_TEXT("at could not find child by name: ")) + name_t);
203
    json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
204
}
205
 
206
const JSONNode & JSONNode::at(const json_string & name_t) const json_throws(std::out_of_range) {
207
    JSON_CHECK_INTERNAL();
208
    JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at"));
209
    if (JSONNode ** res = internal -> at(name_t)){
210
	   return *(*res);
211
    }
212
    JSON_FAIL(json_string(JSON_TEXT("at const could not find child by name: ")) + name_t);
213
    json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
214
}
215
 
216
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
217
    JSONNode & JSONNode::at_nocase(const json_string & name_t) json_throws(std::out_of_range) {
218
	   JSON_CHECK_INTERNAL();
219
	   JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at_nocase"));
220
	   makeUniqueInternal();
221
	   if (JSONNode ** res = internal -> at_nocase(name_t)){
222
		  return *(*res);
223
	   }
224
	   JSON_FAIL(json_string(JSON_TEXT("at_nocase could not find child by name: ")) + name_t);
225
	   json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
226
    }
227
 
228
    const JSONNode & JSONNode::at_nocase(const json_string & name_t) const json_throws(std::out_of_range) {
229
	   JSON_CHECK_INTERNAL();
230
	   JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at_nocase"));
231
	   if (JSONNode ** res = internal -> at_nocase(name_t)){
232
		  return *(*res);
233
	   }
234
	   JSON_FAIL(json_string(JSON_TEXT("at_nocase const could not find child by name: ")) + name_t);
235
	   json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
236
    }
237
#endif
238
 
239
#ifndef JSON_LIBRARY
240
    struct auto_delete {
241
	   public:
242
		  auto_delete(JSONNode * node) json_nothrow : mynode(node){};
243
		  ~auto_delete(void) json_nothrow { JSONNode::deleteJSONNode(mynode); };
244
		  JSONNode * mynode;
245
	   private:
246
		  auto_delete(const auto_delete &);
247
		  auto_delete & operator = (const auto_delete &);
248
    };
249
#endif
250
 
251
JSONNode JSON_PTR_LIB JSONNode::pop_back(json_index_t pos) json_throws(std::out_of_range) {
252
    JSON_CHECK_INTERNAL();
253
    if (json_unlikely(pos >= internal -> size())){
254
	   JSON_FAIL(JSON_TEXT("pop_back out of bounds"));
255
	   json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
256
    }
257
    makeUniqueInternal();
258
    #ifdef JSON_LIBRARY
259
	   return internal -> pop_back(pos);
260
    #else
261
	   auto_delete temp(internal -> pop_back(pos));
262
	   return *temp.mynode;
263
    #endif
264
}
265
 
266
JSONNode JSON_PTR_LIB JSONNode::pop_back(const json_string & name_t) json_throws(std::out_of_range) {
267
    JSON_CHECK_INTERNAL();
268
    JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("pop_back"));
269
    #ifdef JSON_LIBRARY
270
	   return internal -> pop_back(name_t);
271
    #else
272
	   if (JSONNode * res = internal -> pop_back(name_t)){
273
		  auto_delete temp(res);
274
		  return *(temp.mynode);
275
	   }
276
	   JSON_FAIL(json_string(JSON_TEXT("pop_back const could not find child by name: ")) + name_t);
277
	   json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
278
    #endif
279
}
280
 
281
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
282
    JSONNode JSON_PTR_LIB JSONNode::pop_back_nocase(const json_string & name_t) json_throws(std::out_of_range) {
283
	   JSON_CHECK_INTERNAL();
284
	   JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("pop_back_no_case"));
285
	   #ifdef JSON_LIBRARY
286
		  return internal -> pop_back_nocase(name_t);
287
	   #else
288
		  if (JSONNode * res = internal -> pop_back_nocase(name_t)){
289
			 auto_delete temp(res);
290
			 return *(temp.mynode);
291
		  }
292
		  JSON_FAIL(json_string(JSON_TEXT("pop_back_nocase could not find child by name: ")) + name_t);
293
		  json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
294
	   #endif
295
    }
296
#endif
297
 
298
#ifdef JSON_MEMORY_POOL
299
	#include "JSONMemoryPool.h"
300
	memory_pool<NODEPOOL> json_node_mempool;
301
#endif
302
 
303
void JSONNode::deleteJSONNode(JSONNode * ptr) json_nothrow {
304
	#ifdef JSON_MEMORY_POOL
305
		ptr -> ~JSONNode();
306
		json_node_mempool.deallocate((void*)ptr);
307
	#elif defined(JSON_MEMORY_CALLBACKS)
308
		ptr -> ~JSONNode();
309
		libjson_free<JSONNode>(ptr);
310
	#else
311
		delete ptr;
312
	#endif
313
}
314
 
315
inline JSONNode * _newJSONNode(const JSONNode & orig) {
316
	#ifdef JSON_MEMORY_POOL
317
		return new((JSONNode*)json_node_mempool.allocate()) JSONNode(orig);
318
	#elif defined(JSON_MEMORY_CALLBACKS)
319
		return new(json_malloc<JSONNode>(1)) JSONNode(orig);
320
	#else
321
		return new JSONNode(orig);
322
	#endif
323
}
324
 
325
JSONNode * JSONNode::newJSONNode(const JSONNode & orig    JSON_MUTEX_COPY_DECL) {
326
	#ifdef JSON_MUTEX_CALLBACKS
327
		if (parentMutex != 0){
328
			JSONNode * temp = _newJSONNode(orig);
329
			temp -> set_mutex(parentMutex);
330
			return temp;
331
		}
332
	#endif
333
	return _newJSONNode(orig);
334
}
335
 
336
JSONNode * JSONNode::newJSONNode(internalJSONNode * internal_t) {
337
	#ifdef JSON_MEMORY_POOL
338
		return new((JSONNode*)json_node_mempool.allocate()) JSONNode(internal_t);
339
	#elif defined(JSON_MEMORY_CALLBACKS)
340
		return new(json_malloc<JSONNode>(1)) JSONNode(internal_t);
341
	#else
342
		return new JSONNode(internal_t);
343
	#endif
344
}
345
 
346
JSONNode * JSONNode::newJSONNode_Shallow(const JSONNode & orig) {
347
	#ifdef JSON_MEMORY_POOL
348
		return new((JSONNode*)json_node_mempool.allocate()) JSONNode(true, const_cast<JSONNode &>(orig));
349
	#elif defined(JSON_MEMORY_CALLBACKS)
350
		return new(json_malloc<JSONNode>(1)) JSONNode(true, const_cast<JSONNode &>(orig));
351
	#else
352
		return new JSONNode(true, const_cast<JSONNode &>(orig));
353
	#endif
354
}
355
 
356