yinspire 0.1.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.
- data/README +24 -0
- data/bench/pq/Makefile +5 -0
- data/bench/pq/bench.cc +321 -0
- data/bench/pq/bench.rb +125 -0
- data/bench/pq/bench_binaryheap.h +46 -0
- data/bench/pq/bench_calendarqueue.h +58 -0
- data/bench/pq/bench_pairingheap.h +61 -0
- data/bench/pq/bench_stlpq.h +46 -0
- data/bench/pq/benchmark.h +225 -0
- data/bench/pq/distribution.h +93 -0
- data/bench/pq/make.rb +24 -0
- data/bin/yinspire +186 -0
- data/examples/nets/gereon2005.c.json +93723 -0
- data/examples/nets/gereon2005.yin +232650 -0
- data/examples/nets/skorpion.graphml +396 -0
- data/examples/nets/spiketrains_angle_180.txt +8 -0
- data/lib/Algorithms/Array.h +52 -0
- data/lib/Algorithms/BinaryHeap.h +265 -0
- data/lib/Algorithms/CalendarQueue.h +257 -0
- data/lib/Algorithms/IndexedBinaryHeap.h +90 -0
- data/lib/Algorithms/PairingHeap.h +169 -0
- data/lib/Allocators/ChunkedFreelistAllocator.h +96 -0
- data/lib/Allocators/MemoryAllocator.h +45 -0
- data/lib/Allocators/RubyMemoryAllocator.h +37 -0
- data/lib/Yinspire.rb +69 -0
- data/lib/Yinspire/All.rb +10 -0
- data/lib/Yinspire/Core/NeuralEntity.rb +133 -0
- data/lib/Yinspire/Core/Neuron.rb +162 -0
- data/lib/Yinspire/Core/Scheduling/NeuralEntity.rb +123 -0
- data/lib/Yinspire/Core/Scheduling/Simulator.rb +94 -0
- data/lib/Yinspire/Core/Simulator.rb +36 -0
- data/lib/Yinspire/Core/StimuliMixin.rb +103 -0
- data/lib/Yinspire/Core/Stimulus.rb +25 -0
- data/lib/Yinspire/Core/Synapse.rb +64 -0
- data/lib/Yinspire/Dumpers/Dumper.rb +19 -0
- data/lib/Yinspire/Dumpers/Dumper_Dot.rb +28 -0
- data/lib/Yinspire/Loaders/GraphML.rb +84 -0
- data/lib/Yinspire/Loaders/Loader.rb +31 -0
- data/lib/Yinspire/Loaders/Loader_GraphML.rb +97 -0
- data/lib/Yinspire/Loaders/Loader_JSON.rb +181 -0
- data/lib/Yinspire/Loaders/Loader_Spike.rb +42 -0
- data/lib/Yinspire/Loaders/Loader_Yin.rb +62 -0
- data/lib/Yinspire/Loaders/YinScanner.rb +247 -0
- data/lib/Yinspire/Models/Neuron_Base.rb +38 -0
- data/lib/Yinspire/Models/Neuron_Input.rb +12 -0
- data/lib/Yinspire/Models/Neuron_InputOutput.rb +39 -0
- data/lib/Yinspire/Models/Neuron_Output.rb +15 -0
- data/lib/Yinspire/Models/Neuron_SRM01.rb +50 -0
- data/lib/Yinspire/Models/Neuron_SRM02.rb +64 -0
- data/lib/Yinspire/Models/Synapse_Hebb.rb +67 -0
- data/pure_cpp/Makefile +22 -0
- data/pure_cpp/README +2 -0
- data/pure_cpp/src/algo/binary_heap.h +277 -0
- data/pure_cpp/src/algo/indexed_binary_heap.h +90 -0
- data/pure_cpp/src/json/json.cc +542 -0
- data/pure_cpp/src/json/json.h +182 -0
- data/pure_cpp/src/json/json_parser.cc +685 -0
- data/pure_cpp/src/json/json_parser.h +15 -0
- data/pure_cpp/src/json/json_parser.rl +213 -0
- data/pure_cpp/src/main.cc +49 -0
- data/pure_cpp/src/memory_allocator.h +45 -0
- data/pure_cpp/src/neural_entity.cc +208 -0
- data/pure_cpp/src/neural_entity.h +243 -0
- data/pure_cpp/src/neuron.cc +136 -0
- data/pure_cpp/src/neuron.h +70 -0
- data/pure_cpp/src/neuron_srm_01.cc +77 -0
- data/pure_cpp/src/neuron_srm_01.h +36 -0
- data/pure_cpp/src/simulator.cc +151 -0
- data/pure_cpp/src/simulator.h +116 -0
- data/pure_cpp/src/synapse.cc +117 -0
- data/pure_cpp/src/synapse.h +60 -0
- data/pure_cpp/src/types.h +18 -0
- data/run.rb +68 -0
- data/tools/conv_jsonc_to_yin.rb +165 -0
- data/tools/converter.rb +93 -0
- data/tools/json_writer.rb +122 -0
- data/yinspire.gemspec +20 -0
- metadata +156 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
/*
|
2
|
+
* An Indexed Binary Heap
|
3
|
+
*
|
4
|
+
* Copyright (c) 2007, 2008 by Michael Neumann (mneumann@ntecs.de)
|
5
|
+
*
|
6
|
+
* The Indexed Binary Heap keeps track of the indices of it's elements
|
7
|
+
* stored in the heap to allow efficient updating of their priorities.
|
8
|
+
*
|
9
|
+
* The requirement was to modify an elements priority. In a regular
|
10
|
+
* implicit binary heap this is an inefficient operation as the element
|
11
|
+
* has to be found prior to modifying it's priority. And finding an
|
12
|
+
* element is O(n) in an implicit binary heap due to it's non sorted
|
13
|
+
* nature (i.e. can't apply binary search). By keeping track of the
|
14
|
+
* elements index and storing this value inside the elements structure,
|
15
|
+
* the complexity of modifying an elements priority is reduced to
|
16
|
+
* O(log n) in the worst-case!
|
17
|
+
*
|
18
|
+
* NOTE: Index 0 of the elements array is unused. It's the index that
|
19
|
+
* should be used to denote that an element is NOT actually present in
|
20
|
+
* the binary heap.
|
21
|
+
*
|
22
|
+
* See documentation of BinaryHeap as well.
|
23
|
+
*
|
24
|
+
* Example:
|
25
|
+
*
|
26
|
+
* struct E
|
27
|
+
* {
|
28
|
+
* float schedule_at;
|
29
|
+
* unsigned int schedule_index;
|
30
|
+
*
|
31
|
+
* inline static bool less(const E& e1, const E& e2)
|
32
|
+
* {
|
33
|
+
* return e1.schedule_at < e2.schedule_at;
|
34
|
+
* }
|
35
|
+
*
|
36
|
+
* inline static unsigned int& index(const E& e)
|
37
|
+
* {
|
38
|
+
* return e.schedule_index;
|
39
|
+
* }
|
40
|
+
* };
|
41
|
+
*
|
42
|
+
* IndexedBinaryHeap<E, MemoryAllocator> heap;
|
43
|
+
* ...
|
44
|
+
*
|
45
|
+
*/
|
46
|
+
|
47
|
+
#ifndef __YINSPIRE__INDEXED_BINARY_HEAP__
|
48
|
+
#define __YINSPIRE__INDEXED_BINARY_HEAP__
|
49
|
+
|
50
|
+
#include "binary_heap.h"
|
51
|
+
|
52
|
+
template <typename E, class Acc=E>
|
53
|
+
struct BinaryHeapIndexer
|
54
|
+
{
|
55
|
+
static inline void index_changed(E& e, unsigned int i)
|
56
|
+
{
|
57
|
+
Acc::index(e) = i;
|
58
|
+
}
|
59
|
+
};
|
60
|
+
|
61
|
+
|
62
|
+
template <typename E, class Alloc, class Acc=E, unsigned int MIN_CAPA=1024>
|
63
|
+
class IndexedBinaryHeap : public BinaryHeap<E, Alloc, Acc, BinaryHeapIndexer<E, Acc>, MIN_CAPA>
|
64
|
+
{
|
65
|
+
typedef unsigned int I; // index type
|
66
|
+
typedef BinaryHeap<E, Alloc, Acc, BinaryHeapIndexer<E, Acc>, MIN_CAPA> super;
|
67
|
+
typedef BinaryHeapIndexer<E, Acc> Idx;
|
68
|
+
|
69
|
+
public:
|
70
|
+
|
71
|
+
void
|
72
|
+
update(const E& element)
|
73
|
+
{
|
74
|
+
I i = Acc::index(element);
|
75
|
+
if (i == 0)
|
76
|
+
{
|
77
|
+
super::push(element);
|
78
|
+
}
|
79
|
+
else
|
80
|
+
{
|
81
|
+
// FIXME: use propagate up/down instead
|
82
|
+
Idx::index_changed(this->elements[i], 0); // detach from heap
|
83
|
+
I bubble = super::move_bubble_down(i);
|
84
|
+
super::insert_and_bubble_up(bubble, element);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
};
|
89
|
+
|
90
|
+
#endif
|
@@ -0,0 +1,542 @@
|
|
1
|
+
#include "json.h"
|
2
|
+
#include <string.h>
|
3
|
+
#include <math.h>
|
4
|
+
|
5
|
+
/* TODO:
|
6
|
+
* output indentation
|
7
|
+
* escape string (\0 characters in string?)
|
8
|
+
*/
|
9
|
+
|
10
|
+
struct jsonArrayItem
|
11
|
+
{
|
12
|
+
jsonValue* value;
|
13
|
+
jsonArrayItem* next;
|
14
|
+
|
15
|
+
jsonArrayItem(jsonValue* value, jsonArrayItem* next=NULL)
|
16
|
+
{
|
17
|
+
this->value = value;
|
18
|
+
this->next = next;
|
19
|
+
this->value->ref_incr();
|
20
|
+
}
|
21
|
+
|
22
|
+
~jsonArrayItem()
|
23
|
+
{
|
24
|
+
this->value->ref_decr();
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
28
|
+
struct jsonHashItem
|
29
|
+
{
|
30
|
+
jsonString* key;
|
31
|
+
jsonValue* value;
|
32
|
+
jsonHashItem* next;
|
33
|
+
|
34
|
+
jsonHashItem(jsonString* key, jsonValue* value, jsonHashItem* next=NULL)
|
35
|
+
{
|
36
|
+
this->key = key;
|
37
|
+
this->value = value;
|
38
|
+
this->next = next;
|
39
|
+
|
40
|
+
this->key->ref_incr();
|
41
|
+
this->value->ref_incr();
|
42
|
+
}
|
43
|
+
|
44
|
+
~jsonHashItem()
|
45
|
+
{
|
46
|
+
this->key->ref_decr();
|
47
|
+
this->value->ref_decr();
|
48
|
+
}
|
49
|
+
};
|
50
|
+
|
51
|
+
jsonValue::jsonValue()
|
52
|
+
{
|
53
|
+
this->ref_count = 1;
|
54
|
+
}
|
55
|
+
|
56
|
+
jsonValue::~jsonValue()
|
57
|
+
{
|
58
|
+
}
|
59
|
+
|
60
|
+
const char* jsonValue::type()
|
61
|
+
{
|
62
|
+
return "value";
|
63
|
+
}
|
64
|
+
|
65
|
+
bool jsonValue::is_type(const char* t)
|
66
|
+
{
|
67
|
+
return (strcmp(t, type()) == 0);
|
68
|
+
}
|
69
|
+
|
70
|
+
void jsonValue::ref_incr()
|
71
|
+
{
|
72
|
+
this->ref_count++;
|
73
|
+
}
|
74
|
+
|
75
|
+
void jsonValue::ref_decr()
|
76
|
+
{
|
77
|
+
if (--this->ref_count <= 0) delete this;
|
78
|
+
}
|
79
|
+
|
80
|
+
jsonNull* jsonValue::asNull()
|
81
|
+
{
|
82
|
+
return dynamic_cast<jsonNull*>(this);
|
83
|
+
}
|
84
|
+
|
85
|
+
jsonTrue* jsonValue::asTrue()
|
86
|
+
{
|
87
|
+
return dynamic_cast<jsonTrue*>(this);
|
88
|
+
}
|
89
|
+
|
90
|
+
jsonFalse* jsonValue::asFalse()
|
91
|
+
{
|
92
|
+
return dynamic_cast<jsonFalse*>(this);
|
93
|
+
}
|
94
|
+
|
95
|
+
jsonNumber* jsonValue::asNumber()
|
96
|
+
{
|
97
|
+
return dynamic_cast<jsonNumber*>(this);
|
98
|
+
}
|
99
|
+
|
100
|
+
jsonString* jsonValue::asString()
|
101
|
+
{
|
102
|
+
return dynamic_cast<jsonString*>(this);
|
103
|
+
}
|
104
|
+
|
105
|
+
jsonArray* jsonValue::asArray()
|
106
|
+
{
|
107
|
+
return dynamic_cast<jsonArray*>(this);
|
108
|
+
}
|
109
|
+
|
110
|
+
jsonHash* jsonValue::asHash()
|
111
|
+
{
|
112
|
+
return dynamic_cast<jsonHash*>(this);
|
113
|
+
}
|
114
|
+
|
115
|
+
void jsonNull::output(std::ostream& s)
|
116
|
+
{
|
117
|
+
s << "null";
|
118
|
+
}
|
119
|
+
const char* jsonNull::type()
|
120
|
+
{
|
121
|
+
return "null";
|
122
|
+
}
|
123
|
+
|
124
|
+
void jsonTrue::output(std::ostream& s)
|
125
|
+
{
|
126
|
+
s << "true";
|
127
|
+
}
|
128
|
+
|
129
|
+
const char* jsonTrue::type()
|
130
|
+
{
|
131
|
+
return "true";
|
132
|
+
}
|
133
|
+
|
134
|
+
void jsonFalse::output(std::ostream& s)
|
135
|
+
{
|
136
|
+
s << "false";
|
137
|
+
}
|
138
|
+
|
139
|
+
const char* jsonFalse::type()
|
140
|
+
{
|
141
|
+
return "false";
|
142
|
+
}
|
143
|
+
|
144
|
+
jsonNumber::jsonNumber(double value)
|
145
|
+
{
|
146
|
+
this->value = value;
|
147
|
+
}
|
148
|
+
|
149
|
+
void jsonNumber::output(std::ostream& s) {
|
150
|
+
if (isinf(value))
|
151
|
+
{
|
152
|
+
if (value < 0.0)
|
153
|
+
{
|
154
|
+
s << "-Infinity";
|
155
|
+
}
|
156
|
+
else
|
157
|
+
{
|
158
|
+
s << "Infinity";
|
159
|
+
}
|
160
|
+
}
|
161
|
+
else
|
162
|
+
{
|
163
|
+
s << value;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
const char* jsonNumber::type()
|
168
|
+
{
|
169
|
+
return "number";
|
170
|
+
}
|
171
|
+
|
172
|
+
jsonString::jsonString(std::string& value)
|
173
|
+
{
|
174
|
+
this->value = value;
|
175
|
+
}
|
176
|
+
|
177
|
+
jsonString::jsonString(const char* value)
|
178
|
+
{
|
179
|
+
this->value = value;
|
180
|
+
}
|
181
|
+
|
182
|
+
jsonString::jsonString(const char* _value, int len) : value(_value, len)
|
183
|
+
{
|
184
|
+
}
|
185
|
+
|
186
|
+
void jsonString::output(std::ostream& s)
|
187
|
+
{
|
188
|
+
s << '"' << value << '"';
|
189
|
+
}
|
190
|
+
|
191
|
+
const char* jsonString::type()
|
192
|
+
{
|
193
|
+
return "string";
|
194
|
+
}
|
195
|
+
|
196
|
+
jsonArrayIterator::jsonArrayIterator(jsonArray *array)
|
197
|
+
{
|
198
|
+
this->array = array;
|
199
|
+
this->array->ref_incr();
|
200
|
+
this->pos = this->array->head;
|
201
|
+
}
|
202
|
+
|
203
|
+
jsonArrayIterator::~jsonArrayIterator()
|
204
|
+
{
|
205
|
+
this->array->ref_decr();
|
206
|
+
}
|
207
|
+
|
208
|
+
void jsonArrayIterator::next()
|
209
|
+
{
|
210
|
+
if (this->pos != NULL)
|
211
|
+
{
|
212
|
+
this->pos = this->pos->next;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
jsonValue *jsonArrayIterator::current()
|
217
|
+
{
|
218
|
+
if (this->pos != NULL)
|
219
|
+
{
|
220
|
+
return this->pos->value;
|
221
|
+
}
|
222
|
+
else
|
223
|
+
{
|
224
|
+
return NULL;
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
jsonHashIterator::jsonHashIterator(jsonHash *hash)
|
229
|
+
{
|
230
|
+
this->hash = hash;
|
231
|
+
this->hash->ref_incr();
|
232
|
+
this->pos = this->hash->head;
|
233
|
+
}
|
234
|
+
|
235
|
+
jsonHashIterator::~jsonHashIterator()
|
236
|
+
{
|
237
|
+
this->hash->ref_decr();
|
238
|
+
}
|
239
|
+
|
240
|
+
void jsonHashIterator::next()
|
241
|
+
{
|
242
|
+
if (this->pos != NULL)
|
243
|
+
{
|
244
|
+
this->pos = this->pos->next;
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
jsonString *jsonHashIterator::current_key()
|
249
|
+
{
|
250
|
+
if (this->pos != NULL)
|
251
|
+
{
|
252
|
+
return this->pos->key;
|
253
|
+
}
|
254
|
+
else
|
255
|
+
{
|
256
|
+
return NULL;
|
257
|
+
}
|
258
|
+
}
|
259
|
+
|
260
|
+
jsonValue *jsonHashIterator::current_value()
|
261
|
+
{
|
262
|
+
if (this->pos != NULL)
|
263
|
+
{
|
264
|
+
return this->pos->value;
|
265
|
+
}
|
266
|
+
else
|
267
|
+
{
|
268
|
+
return NULL;
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
jsonArray::jsonArray()
|
273
|
+
{
|
274
|
+
head = tail = NULL;
|
275
|
+
}
|
276
|
+
|
277
|
+
jsonArray::~jsonArray()
|
278
|
+
{
|
279
|
+
jsonArrayItem* j;
|
280
|
+
for (jsonArrayItem* i=head; i != NULL; )
|
281
|
+
{
|
282
|
+
j = i->next;
|
283
|
+
delete i;
|
284
|
+
i = j;
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
288
|
+
void jsonArray::output(std::ostream& s)
|
289
|
+
{
|
290
|
+
s << "[";
|
291
|
+
for (jsonArrayItem* i=head; i != NULL; i=i->next)
|
292
|
+
{
|
293
|
+
if (i != head) s << ", ";
|
294
|
+
i->value->output(s);
|
295
|
+
}
|
296
|
+
s << "]";
|
297
|
+
}
|
298
|
+
|
299
|
+
void jsonArray::push(jsonValue* value)
|
300
|
+
{
|
301
|
+
jsonArrayItem* i = new jsonArrayItem(value);
|
302
|
+
|
303
|
+
if (head == NULL)
|
304
|
+
{
|
305
|
+
head = tail = i;
|
306
|
+
}
|
307
|
+
else
|
308
|
+
{
|
309
|
+
tail->next = i;
|
310
|
+
tail = i;
|
311
|
+
}
|
312
|
+
}
|
313
|
+
|
314
|
+
/*void jsonArray::each(void (*iter)(jsonValue*, void*), void* data)
|
315
|
+
{
|
316
|
+
for (jsonArrayItem* i=head; i != NULL; i=i->next)
|
317
|
+
{
|
318
|
+
iter(i->value, data);
|
319
|
+
}
|
320
|
+
}
|
321
|
+
*/
|
322
|
+
|
323
|
+
jsonValue* jsonArray::get(int index)
|
324
|
+
{
|
325
|
+
for (jsonArrayItem* i=head; i != NULL; i=i->next, index--)
|
326
|
+
{
|
327
|
+
if (index == 0)
|
328
|
+
return i->value;
|
329
|
+
}
|
330
|
+
return NULL;
|
331
|
+
}
|
332
|
+
|
333
|
+
const char* jsonArray::type()
|
334
|
+
{
|
335
|
+
return "array";
|
336
|
+
}
|
337
|
+
|
338
|
+
jsonHash::jsonHash()
|
339
|
+
{
|
340
|
+
head = tail = NULL;
|
341
|
+
}
|
342
|
+
|
343
|
+
jsonHash::~jsonHash()
|
344
|
+
{
|
345
|
+
jsonHashItem* j;
|
346
|
+
for (jsonHashItem* i=head; i != NULL; )
|
347
|
+
{
|
348
|
+
j = i->next;
|
349
|
+
delete i;
|
350
|
+
i = j;
|
351
|
+
}
|
352
|
+
}
|
353
|
+
|
354
|
+
void jsonHash::output(std::ostream& s)
|
355
|
+
{
|
356
|
+
s << "{";
|
357
|
+
for (jsonHashItem* i=head; i != NULL; i=i->next)
|
358
|
+
{
|
359
|
+
if (i != head) s << ", " << std::endl;
|
360
|
+
i->key->output(s);
|
361
|
+
s << ": ";
|
362
|
+
i->value->output(s);
|
363
|
+
}
|
364
|
+
s << "}";
|
365
|
+
}
|
366
|
+
|
367
|
+
/*void jsonHash::each(void (*iter)(jsonString*, jsonValue*, void*), void* data)
|
368
|
+
{
|
369
|
+
for (jsonHashItem* i=head; i != NULL; i=i->next)
|
370
|
+
{
|
371
|
+
iter(i->key, i->value, data);
|
372
|
+
}
|
373
|
+
}
|
374
|
+
*/
|
375
|
+
|
376
|
+
jsonValue* jsonHash::get(const char* key)
|
377
|
+
{
|
378
|
+
for (jsonHashItem* i=head; i != NULL; i=i->next)
|
379
|
+
{
|
380
|
+
if (i->key->value == key)
|
381
|
+
{
|
382
|
+
return i->value;
|
383
|
+
}
|
384
|
+
}
|
385
|
+
return NULL;
|
386
|
+
}
|
387
|
+
|
388
|
+
jsonValue* jsonHash::get(std::string& key)
|
389
|
+
{
|
390
|
+
return get(key.c_str());
|
391
|
+
}
|
392
|
+
|
393
|
+
jsonValue* jsonHash::get(jsonString* key)
|
394
|
+
{
|
395
|
+
return get(key->value);
|
396
|
+
}
|
397
|
+
|
398
|
+
bool jsonHash::has_key(const char* key)
|
399
|
+
{
|
400
|
+
return (get(key) != NULL);
|
401
|
+
}
|
402
|
+
|
403
|
+
bool jsonHash::has_key(std::string& key)
|
404
|
+
{
|
405
|
+
return (get(key.c_str()) != NULL);
|
406
|
+
}
|
407
|
+
|
408
|
+
bool jsonHash::has_key(jsonString* key)
|
409
|
+
{
|
410
|
+
return (get(key) != NULL);
|
411
|
+
}
|
412
|
+
|
413
|
+
bool jsonHash::get_bool(const char* key, bool default_value)
|
414
|
+
{
|
415
|
+
jsonValue* v = get(key);
|
416
|
+
if (v != NULL)
|
417
|
+
{
|
418
|
+
if (v->is_type("true"))
|
419
|
+
{
|
420
|
+
return true;
|
421
|
+
}
|
422
|
+
else if (v->is_type("false"))
|
423
|
+
{
|
424
|
+
return false;
|
425
|
+
}
|
426
|
+
else
|
427
|
+
{
|
428
|
+
throw "invalid type cast";
|
429
|
+
}
|
430
|
+
}
|
431
|
+
else
|
432
|
+
{
|
433
|
+
return default_value;
|
434
|
+
}
|
435
|
+
}
|
436
|
+
|
437
|
+
double jsonHash::get_number(const char* key, double default_value)
|
438
|
+
{
|
439
|
+
jsonValue* v = get(key);
|
440
|
+
if (v != NULL)
|
441
|
+
{
|
442
|
+
if (v->is_type("number"))
|
443
|
+
{
|
444
|
+
return ((jsonNumber*)v)->value;
|
445
|
+
}
|
446
|
+
else
|
447
|
+
{
|
448
|
+
throw "invalid type cast";
|
449
|
+
}
|
450
|
+
}
|
451
|
+
else
|
452
|
+
{
|
453
|
+
return default_value;
|
454
|
+
}
|
455
|
+
}
|
456
|
+
|
457
|
+
std::string& jsonHash::get_string(const char* key)
|
458
|
+
{
|
459
|
+
jsonValue* v = get(key);
|
460
|
+
if (v != NULL)
|
461
|
+
{
|
462
|
+
if (v->is_type("string"))
|
463
|
+
{
|
464
|
+
return ((jsonString*)v)->value;
|
465
|
+
}
|
466
|
+
else
|
467
|
+
{
|
468
|
+
throw "invalid type cast";
|
469
|
+
}
|
470
|
+
}
|
471
|
+
else
|
472
|
+
{
|
473
|
+
throw "key not found";
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
void jsonHash::set(const char* key, jsonValue* value)
|
478
|
+
{
|
479
|
+
set(new jsonString(key), value);
|
480
|
+
}
|
481
|
+
|
482
|
+
void jsonHash::set(const char* key, double value)
|
483
|
+
{
|
484
|
+
set(new jsonString(key), new jsonNumber(value));
|
485
|
+
}
|
486
|
+
|
487
|
+
void jsonHash::set(const char* key, int value)
|
488
|
+
{
|
489
|
+
set(new jsonString(key), new jsonNumber(value));
|
490
|
+
}
|
491
|
+
|
492
|
+
void jsonHash::set(const char* key, bool value)
|
493
|
+
{
|
494
|
+
set(new jsonString(key), value ? (jsonValue*)new jsonTrue() : (jsonValue*)new jsonFalse());
|
495
|
+
}
|
496
|
+
|
497
|
+
void jsonHash::set(const char* key, const char* value)
|
498
|
+
{
|
499
|
+
set(new jsonString(key), new jsonString(value));
|
500
|
+
}
|
501
|
+
|
502
|
+
void jsonHash::set(const char* key, std::string& value)
|
503
|
+
{
|
504
|
+
set(new jsonString(key), new jsonString(value));
|
505
|
+
}
|
506
|
+
|
507
|
+
void jsonHash::set(jsonString* key, jsonValue* value)
|
508
|
+
{
|
509
|
+
if (head == NULL)
|
510
|
+
{
|
511
|
+
head = tail = new jsonHashItem(key, value);
|
512
|
+
}
|
513
|
+
else
|
514
|
+
{
|
515
|
+
bool duplicate = false;
|
516
|
+
|
517
|
+
for (jsonHashItem* i=head; i != NULL; i=i->next)
|
518
|
+
{
|
519
|
+
if (i->key->value == key->value)
|
520
|
+
{
|
521
|
+
i->key->ref_decr();
|
522
|
+
i->value->ref_decr();
|
523
|
+
i->key = key;
|
524
|
+
i->value = value;
|
525
|
+
duplicate = true;
|
526
|
+
break;
|
527
|
+
}
|
528
|
+
}
|
529
|
+
|
530
|
+
if (!duplicate)
|
531
|
+
{
|
532
|
+
jsonHashItem* t = new jsonHashItem(key, value);
|
533
|
+
tail->next = t;
|
534
|
+
tail = t;
|
535
|
+
}
|
536
|
+
}
|
537
|
+
}
|
538
|
+
|
539
|
+
const char* jsonHash::type()
|
540
|
+
{
|
541
|
+
return "hash";
|
542
|
+
}
|