superstudio 0.8.2102
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.
- checksums.yaml +7 -0
- data/LICENSE +621 -0
- data/README.md +17 -0
- data/ext/superstudio/extconf.rb +6 -0
- data/ext/superstudio/finalize.h +11 -0
- data/ext/superstudio/fnv_64.c +97 -0
- data/ext/superstudio/fnv_64.h +12 -0
- data/ext/superstudio/hash_linked_list.c +222 -0
- data/ext/superstudio/hash_linked_list.h +38 -0
- data/ext/superstudio/json_builder.c +501 -0
- data/ext/superstudio/json_builder.h +246 -0
- data/ext/superstudio/json_object_array.c +409 -0
- data/ext/superstudio/json_object_array.h +34 -0
- data/ext/superstudio/json_single_object.c +320 -0
- data/ext/superstudio/json_single_object.h +31 -0
- data/ext/superstudio/json_value.c +113 -0
- data/ext/superstudio/json_value.h +19 -0
- data/ext/superstudio/json_value_array.c +157 -0
- data/ext/superstudio/json_value_array.h +23 -0
- data/ext/superstudio/jsonbroker.c +334 -0
- data/ext/superstudio/jsonbroker.h +12 -0
- data/ext/superstudio/ss_alloc.c +27 -0
- data/ext/superstudio/ss_alloc.h +11 -0
- data/ext/superstudio/superstudio.c +10 -0
- data/ext/superstudio/superstudio.h +9 -0
- data/lib/generators/superstudio/schema_generator.rb +65 -0
- data/lib/generators/superstudio/schema_map_generator.rb +60 -0
- data/lib/superstudio.rb +109 -0
- data/lib/superstudio/schema_internal_definer.rb +210 -0
- data/lib/superstudio/schema_interpreter.rb +127 -0
- data/lib/superstudio/schema_reader.rb +51 -0
- data/lib/superstudio/superstudio.so +0 -0
- metadata +76 -0
data/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## LICENSE
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2017 David Dawson
|
|
5
|
+
|
|
6
|
+
Superstudio is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
Superstudio is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU General Public License
|
|
17
|
+
along with Superstudio. If not, see <http://www.gnu.org/licenses/>.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#ifndef SS_FINALIZE_
|
|
2
|
+
|
|
3
|
+
#include "json_builder.h"
|
|
4
|
+
|
|
5
|
+
unsigned long finalize_key_values(JSONDocumentBuilder* builder, SingleValueJSON* single_values, JSONObject* parent_json, unsigned long counter);
|
|
6
|
+
unsigned long finalize_single_objects(JSONDocumentBuilder* builder, SingleObjectJSON* level_single_objects, unsigned long counter, int comma_finish);
|
|
7
|
+
unsigned long finalize_value_array(JSONDocumentBuilder* builder, ArrayValueJSON* value_arrays, unsigned long counter);
|
|
8
|
+
unsigned long finalize_object_array(JSONDocumentBuilder* builder, ArrayObjectJSON* object_array, unsigned long counter);
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
#endif //SS_FINALIZE_
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include "fnv_64.h"
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* 0 = char* string
|
|
8
|
+
* 1 = short
|
|
9
|
+
* 2 = int
|
|
10
|
+
* 3 = long
|
|
11
|
+
* 4 = float
|
|
12
|
+
* 6 = double
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
uint64_t fnv_hash(uint64_t hash, void *data, char type)
|
|
16
|
+
{
|
|
17
|
+
unsigned int i;
|
|
18
|
+
|
|
19
|
+
union {
|
|
20
|
+
short source_short;
|
|
21
|
+
int source_int;
|
|
22
|
+
long source_long;
|
|
23
|
+
float source_float;
|
|
24
|
+
double source_double;
|
|
25
|
+
char* source_string;
|
|
26
|
+
char short_bytes[sizeof(short)];
|
|
27
|
+
char int_bytes[sizeof(int)];
|
|
28
|
+
char long_bytes[sizeof(long)];
|
|
29
|
+
char float_bytes[sizeof(float)];
|
|
30
|
+
char double_bytes[sizeof(double)];
|
|
31
|
+
} byte_struct;
|
|
32
|
+
|
|
33
|
+
switch(type) {
|
|
34
|
+
case 1:
|
|
35
|
+
byte_struct.source_short = *(short*)data;
|
|
36
|
+
for (i=0; i<sizeof(short); i++) {
|
|
37
|
+
char* byte = &byte_struct.short_bytes[sizeof(short) - 1 - i];
|
|
38
|
+
hash = fnv_hash_byte(hash, byte);
|
|
39
|
+
}
|
|
40
|
+
return hash;
|
|
41
|
+
break;
|
|
42
|
+
case 2:
|
|
43
|
+
byte_struct.source_int = *(int*)data;
|
|
44
|
+
for (i=0; i<sizeof(int); i++) {
|
|
45
|
+
char* byte = &byte_struct.int_bytes[sizeof(int) - 1 - i];
|
|
46
|
+
hash = fnv_hash_byte(hash, byte);
|
|
47
|
+
}
|
|
48
|
+
return hash;
|
|
49
|
+
break;
|
|
50
|
+
case 3:
|
|
51
|
+
byte_struct.source_long = *(long*)data;
|
|
52
|
+
for (i=0; i<sizeof(long); i++) {
|
|
53
|
+
char* byte = &byte_struct.long_bytes[sizeof(long) - 1 - i];
|
|
54
|
+
hash = fnv_hash_byte(hash, byte);
|
|
55
|
+
}
|
|
56
|
+
return hash;
|
|
57
|
+
break;
|
|
58
|
+
case 4:
|
|
59
|
+
byte_struct.source_float = *(float*)data;
|
|
60
|
+
for (i=0; i<sizeof(float); i++) {
|
|
61
|
+
char* byte = &byte_struct.float_bytes[sizeof(float) - 1 - i];
|
|
62
|
+
hash = fnv_hash_byte(hash, byte);
|
|
63
|
+
}
|
|
64
|
+
return hash;
|
|
65
|
+
break;
|
|
66
|
+
case 5:
|
|
67
|
+
byte_struct.source_double = *(double*)data;
|
|
68
|
+
for (i=0; i<sizeof(double); i++) {
|
|
69
|
+
char* byte = &byte_struct.double_bytes[sizeof(double) - 1 - i];
|
|
70
|
+
hash = fnv_hash_byte(hash, byte);
|
|
71
|
+
}
|
|
72
|
+
return hash;
|
|
73
|
+
break;
|
|
74
|
+
case 0:
|
|
75
|
+
byte_struct.source_string = (char*)data;
|
|
76
|
+
while(*byte_struct.source_string != '\0') {
|
|
77
|
+
hash = fnv_hash_byte(hash, byte_struct.source_string);
|
|
78
|
+
*byte_struct.source_string = *byte_struct.source_string + 1;
|
|
79
|
+
}
|
|
80
|
+
return hash;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
uint64_t fnv_hash_byte(uint64_t hash, char *data)
|
|
87
|
+
{
|
|
88
|
+
hash ^= (uint64_t)(*data);
|
|
89
|
+
hash *= (FNV_PRIME % UINT64_MAX);
|
|
90
|
+
return hash;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
void hash_byte(uint64_t *hash, char *data)
|
|
94
|
+
{
|
|
95
|
+
*hash ^= (uint64_t)(*data);
|
|
96
|
+
*hash *= (FNV_PRIME % UINT64_MAX);
|
|
97
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#ifndef FNV_HASH_
|
|
2
|
+
#define FNV_OFFSET 14695981039346656037U
|
|
3
|
+
#define FNV_PRIME 1099511628211U
|
|
4
|
+
#define FNV_HASH_
|
|
5
|
+
|
|
6
|
+
#include <stdint.h>
|
|
7
|
+
|
|
8
|
+
uint64_t fnv_hash(uint64_t starting_hash, void *data, char type);
|
|
9
|
+
uint64_t fnv_hash_byte(uint64_t hash, char *data);
|
|
10
|
+
void hash_byte(uint64_t *hash, char *data);
|
|
11
|
+
|
|
12
|
+
#endif //FNV_HASH_
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <math.h>
|
|
5
|
+
#include "ss_alloc.h"
|
|
6
|
+
#include "hash_linked_list.h"
|
|
7
|
+
#include "json_value.h"
|
|
8
|
+
#include "json_value_array.h"
|
|
9
|
+
#include "json_object_array.h"
|
|
10
|
+
#include "json_single_object.h"
|
|
11
|
+
|
|
12
|
+
void hl_initialize(HashList *list, SSMemoryStack* memory_stack, unsigned long query_rows)
|
|
13
|
+
{
|
|
14
|
+
long bucket_count = ((long)((query_rows + 1) / (log10(query_rows + 1)/log10(2))) + 1);
|
|
15
|
+
list->length = 0;
|
|
16
|
+
list->bucket_interval = UINT64_MAX / bucket_count;
|
|
17
|
+
list->next = NULL;
|
|
18
|
+
list->last = NULL;
|
|
19
|
+
list->buckets = (HashListNode**)ss_alloc(memory_stack, 1, bucket_count * sizeof(HashListNode*));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void print_list_details(HashList *list)
|
|
23
|
+
{
|
|
24
|
+
printf("Length: %i\n", list->length);
|
|
25
|
+
HashListNode *i;
|
|
26
|
+
i = list->next;
|
|
27
|
+
while(i) {
|
|
28
|
+
printf("Hash: %lu\n", i->hash);
|
|
29
|
+
i = i->next;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
void increment_length(HashList *list)
|
|
34
|
+
{
|
|
35
|
+
int tmp_length;
|
|
36
|
+
tmp_length = list->length;
|
|
37
|
+
list->length = ++tmp_length;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
uint64_t hl_first(HashList *list)
|
|
42
|
+
{
|
|
43
|
+
HashListNode first_node;
|
|
44
|
+
first_node = *(list->next);
|
|
45
|
+
return first_node.hash;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
HashListNode* hl_insert_or_find(HashList *list,
|
|
49
|
+
uint64_t passed_hash,
|
|
50
|
+
JSONObject* related_object,
|
|
51
|
+
JSONLevelBuilder* related_parent_level,
|
|
52
|
+
JSONLevelBuilder* related_single_json_info,
|
|
53
|
+
JSONLevelBuilder* related_object_info_list,
|
|
54
|
+
SSMemoryStack* memory_stack
|
|
55
|
+
)
|
|
56
|
+
{
|
|
57
|
+
HashListNode* found_node;
|
|
58
|
+
int bucket_number = find_target_bucket(passed_hash, list->bucket_interval);
|
|
59
|
+
|
|
60
|
+
if (!list->next) {
|
|
61
|
+
HashListNode *new_node = (HashListNode*)ss_alloc(memory_stack, 1, sizeof(HashListNode));
|
|
62
|
+
|
|
63
|
+
new_node->hash = passed_hash;
|
|
64
|
+
new_node->next = NULL;
|
|
65
|
+
new_node->bucket_next = NULL;
|
|
66
|
+
new_node->bucket_previous = NULL;
|
|
67
|
+
new_node->related_JSON_object = related_object;
|
|
68
|
+
new_node->related_parent_level = related_parent_level;
|
|
69
|
+
new_node->single_object_info_list = related_single_json_info;
|
|
70
|
+
new_node->array_object_info_list = related_object_info_list;
|
|
71
|
+
|
|
72
|
+
list->last = list->next = list->buckets[bucket_number] = new_node;
|
|
73
|
+
increment_length(list);
|
|
74
|
+
return list->next;
|
|
75
|
+
}
|
|
76
|
+
found_node = hl_find_node(list, passed_hash);
|
|
77
|
+
if (found_node) {
|
|
78
|
+
if (found_node->bucket_previous != NULL) {
|
|
79
|
+
found_node->bucket_previous->bucket_next = found_node->bucket_next;
|
|
80
|
+
found_node->bucket_next = list->buckets[bucket_number];
|
|
81
|
+
|
|
82
|
+
found_node->bucket_previous = NULL;
|
|
83
|
+
|
|
84
|
+
list->buckets[bucket_number] = found_node;
|
|
85
|
+
}
|
|
86
|
+
return found_node;
|
|
87
|
+
} else {
|
|
88
|
+
HashListNode *new_node = (HashListNode*)ss_alloc(memory_stack, 1, sizeof(HashListNode));
|
|
89
|
+
new_node->hash = passed_hash;
|
|
90
|
+
new_node->next = NULL;
|
|
91
|
+
new_node->bucket_next = NULL;
|
|
92
|
+
new_node->bucket_previous = NULL;
|
|
93
|
+
new_node->related_JSON_object = related_object;
|
|
94
|
+
new_node->related_parent_level = related_parent_level;
|
|
95
|
+
new_node->single_object_info_list = related_single_json_info;
|
|
96
|
+
new_node->array_object_info_list = related_object_info_list;
|
|
97
|
+
|
|
98
|
+
if (list->buckets[bucket_number] != NULL) {
|
|
99
|
+
list->buckets[bucket_number]->bucket_previous = new_node;
|
|
100
|
+
new_node->bucket_next = list->buckets[bucket_number];
|
|
101
|
+
}
|
|
102
|
+
list->buckets[bucket_number] = new_node;
|
|
103
|
+
|
|
104
|
+
increment_length(list);
|
|
105
|
+
|
|
106
|
+
list->last->next = new_node;
|
|
107
|
+
list->last = new_node;
|
|
108
|
+
|
|
109
|
+
return list->last;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
HashListNode* hl_find_node(HashList *list, uint64_t passed_hash)
|
|
114
|
+
{
|
|
115
|
+
int bucket_number = find_target_bucket(passed_hash, list->bucket_interval);
|
|
116
|
+
HashListNode *i = list->buckets[bucket_number];
|
|
117
|
+
|
|
118
|
+
if (i == NULL) {
|
|
119
|
+
return NULL;
|
|
120
|
+
}
|
|
121
|
+
while(i) {
|
|
122
|
+
if (i->hash == passed_hash) {
|
|
123
|
+
return i;
|
|
124
|
+
}
|
|
125
|
+
i = i->bucket_next;
|
|
126
|
+
}
|
|
127
|
+
return NULL;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
JSONObject* find_or_create_node(
|
|
131
|
+
JSONDocumentBuilder* builder,
|
|
132
|
+
JSONLevelBuilder* level_definitions,
|
|
133
|
+
JSONLevelBuilder* child_levels,
|
|
134
|
+
JSONLevelBuilder* child_array_start,
|
|
135
|
+
JSONObject* parent_object,
|
|
136
|
+
uint64_t hash,
|
|
137
|
+
unsigned char parent_type,
|
|
138
|
+
char** row_strings,
|
|
139
|
+
unsigned long* string_sizes,
|
|
140
|
+
unsigned long visible_depth,
|
|
141
|
+
HashList* parent_search_list
|
|
142
|
+
)
|
|
143
|
+
{
|
|
144
|
+
HashListNode* found_node;
|
|
145
|
+
JSONObject* found_object = NULL;
|
|
146
|
+
JSONLevelBuilder* found_level_definitions;
|
|
147
|
+
SingleObjectJSON* related_child_objects;
|
|
148
|
+
SingleObjectJSON* single_parent_object; // We need to search in two directions - through each child and through each child's single object children
|
|
149
|
+
int found = 0;
|
|
150
|
+
|
|
151
|
+
builder->json_char_count += 3; // Starting, ending brace and comma
|
|
152
|
+
|
|
153
|
+
// Dev note:
|
|
154
|
+
// The create calls will handle duplicates where additional stuff doesn't need to be added
|
|
155
|
+
if (parent_type == 4) {
|
|
156
|
+
|
|
157
|
+
create_array_object(builder,
|
|
158
|
+
hash,
|
|
159
|
+
parent_search_list,
|
|
160
|
+
level_definitions,
|
|
161
|
+
child_levels,
|
|
162
|
+
child_array_start,
|
|
163
|
+
level_definitions->identifier_int);
|
|
164
|
+
|
|
165
|
+
found_node = hl_find_node(parent_search_list, hash);
|
|
166
|
+
if (found_node) {
|
|
167
|
+
found_object = found_node->related_JSON_object;
|
|
168
|
+
found_level_definitions = found_node->related_parent_level;
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
|
|
172
|
+
create_single_object(builder,
|
|
173
|
+
hash,
|
|
174
|
+
level_definitions->identifier_int,
|
|
175
|
+
parent_object);
|
|
176
|
+
|
|
177
|
+
// Dev note:
|
|
178
|
+
// When adding a single object, we're finding the parent hash because the single object is hashed as well
|
|
179
|
+
// Single objects are a 1-1 relationship
|
|
180
|
+
related_child_objects = parent_object->single_objects;
|
|
181
|
+
while (related_child_objects->set_flag && !found) {
|
|
182
|
+
single_parent_object = related_child_objects;
|
|
183
|
+
if (single_parent_object->identifier_int == level_definitions->identifier_int) {
|
|
184
|
+
found = 1;
|
|
185
|
+
} else {
|
|
186
|
+
single_parent_object = single_parent_object->value->single_objects;
|
|
187
|
+
while (single_parent_object->set_flag && !found) {
|
|
188
|
+
if (single_parent_object->identifier_int == level_definitions->identifier_int) {
|
|
189
|
+
found = 1;
|
|
190
|
+
} else {
|
|
191
|
+
single_parent_object = single_parent_object->next_item;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
related_child_objects = related_child_objects->next_item;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (found) {
|
|
199
|
+
found_object = single_parent_object->value;
|
|
200
|
+
} else {
|
|
201
|
+
found_object = parent_object;
|
|
202
|
+
}
|
|
203
|
+
found_level_definitions = level_definitions;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (found_object) {
|
|
207
|
+
set_key_values(builder, string_sizes, row_strings, visible_depth, found_level_definitions, found_object);
|
|
208
|
+
set_value_arrays(builder, found_level_definitions, found_level_definitions->column_count, row_strings, string_sizes, visible_depth, found_object);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return found_object;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
void hl_set_json_object(HashListNode* node, JSONObject* related_object)
|
|
215
|
+
{
|
|
216
|
+
node->related_JSON_object = related_object;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
int find_target_bucket(uint64_t passed_hash, unsigned long interval)
|
|
220
|
+
{
|
|
221
|
+
return passed_hash / interval;
|
|
222
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#ifndef HASH_LIST_
|
|
2
|
+
#define HASH_LIST_
|
|
3
|
+
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
#include "json_builder.h"
|
|
6
|
+
|
|
7
|
+
void hl_initialize(HashList *list, SSMemoryStack* memory_stack, unsigned long query_rows);
|
|
8
|
+
void print_list_details(HashList *list);
|
|
9
|
+
void increment_length(HashList *list);
|
|
10
|
+
uint64_t hl_first(HashList *list);
|
|
11
|
+
int find_target_bucket(uint64_t passed_hash, unsigned long interval);
|
|
12
|
+
void hl_set_json_object(HashListNode* node, JSONObject* related_object);
|
|
13
|
+
|
|
14
|
+
JSONObject* find_or_create_node(JSONDocumentBuilder* builder,
|
|
15
|
+
JSONLevelBuilder* level_definitions,
|
|
16
|
+
JSONLevelBuilder* child_levels,
|
|
17
|
+
JSONLevelBuilder* child_array_start,
|
|
18
|
+
JSONObject* parent_object,
|
|
19
|
+
uint64_t hash,
|
|
20
|
+
unsigned char parent_type,
|
|
21
|
+
char** row_strings,
|
|
22
|
+
unsigned long* string_sizes,
|
|
23
|
+
unsigned long visible_depth,
|
|
24
|
+
HashList* parent_search_list);
|
|
25
|
+
|
|
26
|
+
HashListNode* hl_insert_or_find(HashList *list,
|
|
27
|
+
uint64_t passed_hash,
|
|
28
|
+
JSONObject* related_object,
|
|
29
|
+
JSONLevelBuilder* related_parent_level,
|
|
30
|
+
JSONLevelBuilder* related_single_json_info,
|
|
31
|
+
JSONLevelBuilder* related_object_info_list,
|
|
32
|
+
SSMemoryStack* memory_stack
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
HashListNode* hl_find_node(HashList *list, uint64_t passed_hash);
|
|
37
|
+
|
|
38
|
+
#endif // HASH_LIST_
|
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
#include <string.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include "json_builder.h"
|
|
5
|
+
#include "json_value.h"
|
|
6
|
+
#include "json_value_array.h"
|
|
7
|
+
#include "json_single_object.h"
|
|
8
|
+
#include "json_object_array.h"
|
|
9
|
+
#include "hash_linked_list.h"
|
|
10
|
+
#include "ss_alloc.h"
|
|
11
|
+
#include "fnv_64.h"
|
|
12
|
+
|
|
13
|
+
void json_builder_initialize(JSONDocumentBuilder *builder)
|
|
14
|
+
{
|
|
15
|
+
builder->memory_stack = calloc(1, sizeof(SSMemoryStack));
|
|
16
|
+
builder->memory_stack->stack_top = calloc(1, sizeof(SSMemoryStackNode));
|
|
17
|
+
|
|
18
|
+
builder->root_level = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
19
|
+
builder->root_level->next_child = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
20
|
+
builder->root_level->next_child_array = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
21
|
+
|
|
22
|
+
builder->root = (ArrayObjectJSON*)ss_alloc(builder->memory_stack, 1, sizeof(ArrayObjectJSON));
|
|
23
|
+
|
|
24
|
+
builder->root->next = (ArrayObjectJSON*)ss_alloc(builder->memory_stack, 1, sizeof(ArrayObjectJSON));
|
|
25
|
+
|
|
26
|
+
builder->resulting_json = NULL;
|
|
27
|
+
builder->root->identifier_int = 0;
|
|
28
|
+
builder->root->value_list = NULL;
|
|
29
|
+
builder->root->set_flag = 0;
|
|
30
|
+
|
|
31
|
+
builder->root_level->search_list = (HashList*)ss_alloc(builder->memory_stack, 1, sizeof(HashList));
|
|
32
|
+
|
|
33
|
+
builder->row_count = 0;
|
|
34
|
+
builder->json_char_count = 3; //Starts with "[]\0"
|
|
35
|
+
builder->max_depth = 0;
|
|
36
|
+
builder->max_real_depth = 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
void set_row_count(JSONDocumentBuilder *builder, unsigned long count)
|
|
40
|
+
{
|
|
41
|
+
builder->row_count = count;
|
|
42
|
+
initialize_search_list(builder->root_level, builder->memory_stack, count);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void initialize_search_list(JSONLevelBuilder* level, SSMemoryStack* memory_stack, unsigned long count)
|
|
46
|
+
{
|
|
47
|
+
hl_initialize(level->search_list, memory_stack, count);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
unsigned long get_row_count(JSONDocumentBuilder *builder)
|
|
51
|
+
{
|
|
52
|
+
return builder->row_count;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
void set_repeating_array_columns(JSONDocumentBuilder *builder, unsigned long* repeating)
|
|
56
|
+
{
|
|
57
|
+
builder->root_level->repeating_array_columns = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);
|
|
58
|
+
memcpy(builder->root_level->repeating_array_columns, repeating, sizeof(unsigned long) * builder->root_level->column_count);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void set_column_count(JSONDocumentBuilder *builder, unsigned long count)
|
|
62
|
+
{
|
|
63
|
+
builder->root_level->column_count = count;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
unsigned long get_column_count(JSONDocumentBuilder *builder)
|
|
67
|
+
{
|
|
68
|
+
return builder->root_level->column_count;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
void set_quote_array(JSONDocumentBuilder *builder, unsigned long* quotes)
|
|
72
|
+
{
|
|
73
|
+
builder->root_level->quote_array = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);
|
|
74
|
+
memcpy(builder->root_level->quote_array, quotes, sizeof(unsigned long) * (builder->root_level->column_count));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void set_hashing_array(JSONDocumentBuilder *builder, unsigned long* do_not_hashes)
|
|
78
|
+
{
|
|
79
|
+
builder->root_level->do_not_hash = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);
|
|
80
|
+
memcpy(builder->root_level->do_not_hash, do_not_hashes, sizeof(unsigned long) * (builder->root_level->column_count));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
void set_depth_array(
|
|
84
|
+
JSONDocumentBuilder *builder,
|
|
85
|
+
unsigned long* depths,
|
|
86
|
+
unsigned long max,
|
|
87
|
+
unsigned long* real_depths,
|
|
88
|
+
unsigned long max_real
|
|
89
|
+
)
|
|
90
|
+
{
|
|
91
|
+
builder->root_level->depth_array = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);
|
|
92
|
+
memcpy(builder->root_level->depth_array, depths, sizeof(unsigned long) * (builder->root_level->column_count));
|
|
93
|
+
|
|
94
|
+
builder->max_depth = max;
|
|
95
|
+
|
|
96
|
+
builder->root_level->real_depth_array = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);
|
|
97
|
+
memcpy(builder->root_level->real_depth_array, real_depths, sizeof(unsigned long) * (builder->root_level->column_count));
|
|
98
|
+
|
|
99
|
+
builder->max_real_depth = max_real;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
void set_single_node_key_names(JSONDocumentBuilder *builder, char** key_array, unsigned long* key_sizes)
|
|
103
|
+
{
|
|
104
|
+
builder->single_object_key_lengths = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);
|
|
105
|
+
builder->single_object_key_names = (char**)ss_alloc(builder->memory_stack, 1, sizeof(char*) * builder->root_level->column_count);
|
|
106
|
+
|
|
107
|
+
memcpy(builder->single_object_key_lengths, key_sizes, sizeof(unsigned long*) * (builder->root_level->column_count));
|
|
108
|
+
memcpy(builder->single_object_key_names, key_array, sizeof(char*) * (builder->root_level->column_count));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
void set_array_node_key_names(JSONDocumentBuilder *builder, char** key_array, unsigned long* key_sizes)
|
|
113
|
+
{
|
|
114
|
+
builder->array_object_key_lengths = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);
|
|
115
|
+
builder->array_object_key_names = (char**)ss_alloc(builder->memory_stack, 1, sizeof(char*) * builder->root_level->column_count);
|
|
116
|
+
|
|
117
|
+
memcpy(builder->array_object_key_lengths, key_sizes, sizeof(unsigned long*) * (builder->root_level->column_count));
|
|
118
|
+
memcpy(builder->array_object_key_names, key_array, sizeof(char*) * (builder->root_level->column_count));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
void set_column_names_sizes(JSONDocumentBuilder *builder, char** column_names, unsigned long* column_string_sizes)
|
|
122
|
+
{
|
|
123
|
+
builder->root_level->column_name_lengths = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);
|
|
124
|
+
builder->root_level->column_names = (char**)ss_alloc(builder->memory_stack, 1, sizeof(char*) * builder->root_level->column_count);
|
|
125
|
+
|
|
126
|
+
memcpy(builder->root_level->column_name_lengths, column_string_sizes, sizeof(unsigned long*) * (builder->root_level->column_count));
|
|
127
|
+
memcpy(builder->root_level->column_names, column_names, sizeof(char*) * (builder->root_level->column_count));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void set_mapping_array(JSONDocumentBuilder *builder, char** internal_map, unsigned long* internal_map_sizes)
|
|
131
|
+
{
|
|
132
|
+
builder->root_level->mapping_array_lengths = (unsigned long*)ss_alloc(builder->memory_stack, 1, sizeof(unsigned long) * builder->root_level->column_count);;
|
|
133
|
+
builder->root_level->mapping_array = (char**)ss_alloc(builder->memory_stack, 1, sizeof(char*) * builder->root_level->column_count);
|
|
134
|
+
|
|
135
|
+
memcpy(builder->root_level->mapping_array_lengths, internal_map_sizes, sizeof(unsigned long) * (builder->root_level->column_count));
|
|
136
|
+
memcpy(builder->root_level->mapping_array, internal_map, sizeof(char*) * (builder->root_level->column_count));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
void consume_row(
|
|
140
|
+
JSONDocumentBuilder *builder,
|
|
141
|
+
char** row_strings,
|
|
142
|
+
unsigned long* string_sizes,
|
|
143
|
+
unsigned long accessing_depth,
|
|
144
|
+
unsigned long visible_depth,
|
|
145
|
+
unsigned long column_count,
|
|
146
|
+
JSONObject* parent_object,
|
|
147
|
+
JSONLevelBuilder* level_definitions,
|
|
148
|
+
unsigned char parent_type,
|
|
149
|
+
int parent_identifier,
|
|
150
|
+
HashList* parent_search_list
|
|
151
|
+
)
|
|
152
|
+
{
|
|
153
|
+
uint64_t hash;
|
|
154
|
+
JSONObject* found_object;
|
|
155
|
+
JSONLevelBuilder* child_levels = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
156
|
+
JSONLevelBuilder* child_array_start = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
157
|
+
|
|
158
|
+
child_levels->next_child = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
159
|
+
child_levels->next_child_array = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
160
|
+
|
|
161
|
+
child_array_start->next_child = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
162
|
+
child_array_start->next_child_array = (JSONLevelBuilder*)ss_alloc(builder->memory_stack, 1, sizeof(JSONLevelBuilder));
|
|
163
|
+
|
|
164
|
+
if (accessing_depth == 0 && visible_depth == 0) {
|
|
165
|
+
level_definitions = builder->root_level;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
hash = calculate_run_hash(level_definitions, column_count, string_sizes, row_strings, accessing_depth, (accessing_depth + visible_depth));
|
|
169
|
+
|
|
170
|
+
found_object = find_or_create_node(
|
|
171
|
+
builder,
|
|
172
|
+
level_definitions,
|
|
173
|
+
child_levels,
|
|
174
|
+
child_array_start,
|
|
175
|
+
parent_object,
|
|
176
|
+
hash,
|
|
177
|
+
parent_type,
|
|
178
|
+
row_strings,
|
|
179
|
+
string_sizes,
|
|
180
|
+
(visible_depth + accessing_depth),
|
|
181
|
+
parent_search_list);
|
|
182
|
+
|
|
183
|
+
define_child_levels(builder, level_definitions, child_levels, hash, column_count, (accessing_depth + visible_depth));
|
|
184
|
+
|
|
185
|
+
initialize_child_levels(child_levels, builder->memory_stack);
|
|
186
|
+
set_single_object_child_level_definitions(level_definitions, child_levels, hash, column_count, (accessing_depth + visible_depth));
|
|
187
|
+
assign_single_object_data(level_definitions, child_levels, row_strings, string_sizes, column_count, (accessing_depth + visible_depth));
|
|
188
|
+
|
|
189
|
+
define_child_array_levels(builder, level_definitions, child_array_start, hash, column_count, accessing_depth, visible_depth, row_strings, string_sizes);
|
|
190
|
+
initialize_child_array_levels(child_array_start, builder->memory_stack);
|
|
191
|
+
set_array_object_child_level_definitions(level_definitions, child_array_start, hash, column_count, (accessing_depth + visible_depth));
|
|
192
|
+
assign_array_object_data(level_definitions, child_array_start, row_strings, string_sizes, column_count, (accessing_depth + visible_depth));
|
|
193
|
+
|
|
194
|
+
if (found_object) {
|
|
195
|
+
add_or_find_single_object_child_hashes(builder,
|
|
196
|
+
child_levels,
|
|
197
|
+
found_object,
|
|
198
|
+
parent_object,
|
|
199
|
+
hash,
|
|
200
|
+
parent_type,
|
|
201
|
+
parent_identifier);
|
|
202
|
+
|
|
203
|
+
add_or_find_array_object_child_hashes(builder,
|
|
204
|
+
level_definitions,
|
|
205
|
+
child_array_start,
|
|
206
|
+
accessing_depth,
|
|
207
|
+
visible_depth,
|
|
208
|
+
column_count,
|
|
209
|
+
string_sizes,
|
|
210
|
+
row_strings,
|
|
211
|
+
found_object
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
consume_single_objects(
|
|
215
|
+
builder,
|
|
216
|
+
child_levels,
|
|
217
|
+
found_object,
|
|
218
|
+
parent_search_list,
|
|
219
|
+
accessing_depth,
|
|
220
|
+
visible_depth
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
consume_array_objects(
|
|
224
|
+
builder,
|
|
225
|
+
child_array_start,
|
|
226
|
+
found_object,
|
|
227
|
+
accessing_depth,
|
|
228
|
+
visible_depth
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
void consume_single_objects (
|
|
234
|
+
JSONDocumentBuilder* builder,
|
|
235
|
+
JSONLevelBuilder* child_levels,
|
|
236
|
+
JSONObject* found_object,
|
|
237
|
+
HashList* parent_search_list,
|
|
238
|
+
unsigned long accessing_depth,
|
|
239
|
+
unsigned long visible_depth
|
|
240
|
+
)
|
|
241
|
+
{
|
|
242
|
+
while(child_levels->set_flag && parent_search_list->length) {
|
|
243
|
+
if (found_object->single_objects->set_flag) {
|
|
244
|
+
consume_row(builder,
|
|
245
|
+
child_levels->active_row_strings->row_strings,
|
|
246
|
+
child_levels->active_row_strings->string_lengths,
|
|
247
|
+
accessing_depth,
|
|
248
|
+
(visible_depth + 1),
|
|
249
|
+
child_levels->column_count,
|
|
250
|
+
found_object,
|
|
251
|
+
child_levels,
|
|
252
|
+
2,
|
|
253
|
+
child_levels->identifier_int,
|
|
254
|
+
parent_search_list
|
|
255
|
+
);
|
|
256
|
+
} else {
|
|
257
|
+
consume_row(builder,
|
|
258
|
+
child_levels->active_row_strings->row_strings,
|
|
259
|
+
child_levels->active_row_strings->string_lengths,
|
|
260
|
+
accessing_depth,
|
|
261
|
+
(visible_depth + 1),
|
|
262
|
+
child_levels->column_count,
|
|
263
|
+
found_object,
|
|
264
|
+
child_levels,
|
|
265
|
+
2,
|
|
266
|
+
child_levels->identifier_int,
|
|
267
|
+
parent_search_list
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
child_levels = child_levels->next_child;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
void consume_array_objects(JSONDocumentBuilder* builder,
|
|
275
|
+
JSONLevelBuilder* child_array_levels,
|
|
276
|
+
JSONObject* found_object,
|
|
277
|
+
unsigned long accessing_depth,
|
|
278
|
+
unsigned long visible_depth)
|
|
279
|
+
{
|
|
280
|
+
while(child_array_levels->set_flag) {
|
|
281
|
+
consume_row(builder,
|
|
282
|
+
child_array_levels->active_row_strings->row_strings,
|
|
283
|
+
child_array_levels->active_row_strings->string_lengths,
|
|
284
|
+
(accessing_depth + 1),
|
|
285
|
+
visible_depth,
|
|
286
|
+
child_array_levels->column_count,
|
|
287
|
+
found_object,
|
|
288
|
+
child_array_levels,
|
|
289
|
+
4,
|
|
290
|
+
child_array_levels->identifier_int,
|
|
291
|
+
child_array_levels->search_list
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
child_array_levels = child_array_levels->next_child_array;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
uint64_t calculate_run_hash(JSONLevelBuilder* level_definitions, unsigned long column_count, unsigned long* string_sizes, char** row_strings, unsigned long accessing_depth, unsigned long hashing_depth)
|
|
299
|
+
{
|
|
300
|
+
uint64_t hash = FNV_OFFSET;
|
|
301
|
+
unsigned long counter = 0;
|
|
302
|
+
unsigned long inner_counter = 0;
|
|
303
|
+
|
|
304
|
+
while(counter < column_count) {
|
|
305
|
+
inner_counter = 0;
|
|
306
|
+
|
|
307
|
+
if ((!level_definitions->do_not_hash[counter]) && (level_definitions->real_depth_array[counter] == accessing_depth)
|
|
308
|
+
&& (hashing_depth <= level_definitions->depth_array[counter]))
|
|
309
|
+
{
|
|
310
|
+
while (inner_counter < string_sizes[counter]) {
|
|
311
|
+
hash_byte(&hash, &row_strings[counter][inner_counter]);
|
|
312
|
+
inner_counter++;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
counter++;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return hash;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
uint64_t calculate_identified_hash(
|
|
322
|
+
JSONLevelBuilder* level_definitions,
|
|
323
|
+
unsigned long column_count,
|
|
324
|
+
unsigned long* string_sizes,
|
|
325
|
+
char** row_strings,
|
|
326
|
+
unsigned long accessing_depth,
|
|
327
|
+
unsigned long hashing_depth,
|
|
328
|
+
int test_identifier_length,
|
|
329
|
+
char* test_identifier)
|
|
330
|
+
{
|
|
331
|
+
uint64_t hash = FNV_OFFSET;
|
|
332
|
+
unsigned long counter = 0;
|
|
333
|
+
unsigned long inner_counter = 0;
|
|
334
|
+
int cursor;
|
|
335
|
+
int inner_identifier_length;
|
|
336
|
+
char* inner_test_identifier;
|
|
337
|
+
|
|
338
|
+
while(counter < column_count) {
|
|
339
|
+
if (level_definitions->real_depth_array[counter] == accessing_depth) {
|
|
340
|
+
cursor = 0;
|
|
341
|
+
|
|
342
|
+
read_identifier((accessing_depth - 1), level_definitions->mapping_array[counter], &cursor, &inner_identifier_length, level_definitions->mapping_array_lengths[counter]);
|
|
343
|
+
inner_test_identifier = level_definitions->mapping_array[counter] + cursor;
|
|
344
|
+
|
|
345
|
+
// TODO: check to see if we're looking at a 4, only hash on 4s
|
|
346
|
+
inner_counter = 0;
|
|
347
|
+
if ((!level_definitions->do_not_hash[counter])
|
|
348
|
+
&& (hashing_depth <= level_definitions->depth_array[counter])
|
|
349
|
+
&& (inner_identifier_length == test_identifier_length)) {
|
|
350
|
+
if (!memcmp(test_identifier, inner_test_identifier, test_identifier_length)) {
|
|
351
|
+
while (inner_counter < string_sizes[counter]) {
|
|
352
|
+
hash_byte(&hash, &row_strings[counter][inner_counter]);
|
|
353
|
+
inner_counter++;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
counter++;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return hash;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
char read_type(unsigned long depth_start,
|
|
365
|
+
char* mapped_value,
|
|
366
|
+
unsigned long mapped_value_length)
|
|
367
|
+
{
|
|
368
|
+
unsigned long cursor = 0;
|
|
369
|
+
unsigned long depth_counter = 0;
|
|
370
|
+
|
|
371
|
+
if (depth_start > 0) {
|
|
372
|
+
while (depth_counter < depth_start) {
|
|
373
|
+
if (cursor >= mapped_value_length) {
|
|
374
|
+
return 0;
|
|
375
|
+
}
|
|
376
|
+
else if (mapped_value[cursor] == '-') {
|
|
377
|
+
depth_counter++;
|
|
378
|
+
}
|
|
379
|
+
cursor++;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return mapped_value[cursor];
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
void read_identifier(char depth_start,
|
|
386
|
+
char* mapped_value,
|
|
387
|
+
int* cursor,
|
|
388
|
+
int* identifier_characters,
|
|
389
|
+
unsigned long mapped_value_length)
|
|
390
|
+
{
|
|
391
|
+
*cursor = 0;
|
|
392
|
+
unsigned char end_cursor = 0;
|
|
393
|
+
*identifier_characters = 0;
|
|
394
|
+
char depth_counter = 0;
|
|
395
|
+
|
|
396
|
+
if (depth_start > 0) {
|
|
397
|
+
while (depth_counter < depth_start) {
|
|
398
|
+
if (mapped_value[*cursor] == '-') {
|
|
399
|
+
depth_counter++;
|
|
400
|
+
}
|
|
401
|
+
*cursor += 1;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
*cursor += 2;
|
|
406
|
+
end_cursor = *cursor;
|
|
407
|
+
|
|
408
|
+
while (mapped_value[end_cursor] != '-' && end_cursor < mapped_value_length) {
|
|
409
|
+
*identifier_characters += 1;
|
|
410
|
+
end_cursor++;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
void define_child_levels(
|
|
415
|
+
JSONDocumentBuilder *builder,
|
|
416
|
+
JSONLevelBuilder* level_definitions,
|
|
417
|
+
JSONLevelBuilder* child_levels,
|
|
418
|
+
uint64_t hash,
|
|
419
|
+
unsigned long column_count,
|
|
420
|
+
unsigned long visible_depth
|
|
421
|
+
)
|
|
422
|
+
{
|
|
423
|
+
unsigned long counter = 0;
|
|
424
|
+
int test_identifier_length;
|
|
425
|
+
int identifier_int;
|
|
426
|
+
int cursor;
|
|
427
|
+
char* test_identifier;
|
|
428
|
+
char type;
|
|
429
|
+
|
|
430
|
+
while(counter < column_count) {
|
|
431
|
+
type = read_type(visible_depth, level_definitions->mapping_array[counter], level_definitions->mapping_array_lengths[counter]);
|
|
432
|
+
read_identifier(visible_depth, level_definitions->mapping_array[counter], &cursor, &test_identifier_length, level_definitions->mapping_array_lengths[counter]);
|
|
433
|
+
|
|
434
|
+
test_identifier = ss_alloc(builder->memory_stack, 1, test_identifier_length + 1);
|
|
435
|
+
memcpy(test_identifier, level_definitions->mapping_array[counter] + cursor, test_identifier_length);
|
|
436
|
+
test_identifier[test_identifier_length] = '\0';
|
|
437
|
+
identifier_int = atoi(test_identifier);
|
|
438
|
+
|
|
439
|
+
if (type == '2') {
|
|
440
|
+
count_increment_or_create_json_level_child(builder, child_levels, test_identifier_length, test_identifier, identifier_int, hash);
|
|
441
|
+
}
|
|
442
|
+
if ((level_definitions->real_depth_array[counter] == visible_depth) && (level_definitions->do_not_hash[counter]) && (!level_definitions->defined_flag)) {
|
|
443
|
+
level_definitions->contains_array_value_flag = 1;
|
|
444
|
+
}
|
|
445
|
+
counter++;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
void define_child_array_levels(
|
|
450
|
+
JSONDocumentBuilder *builder,
|
|
451
|
+
JSONLevelBuilder* level_definitions,
|
|
452
|
+
JSONLevelBuilder* child_array_start,
|
|
453
|
+
uint64_t hash,
|
|
454
|
+
unsigned long column_count,
|
|
455
|
+
unsigned long accessing_depth,
|
|
456
|
+
unsigned long visible_depth,
|
|
457
|
+
char** row_strings,
|
|
458
|
+
unsigned long* string_sizes)
|
|
459
|
+
{
|
|
460
|
+
unsigned long counter = 0;
|
|
461
|
+
int test_identifier_length;
|
|
462
|
+
int identifier_int;
|
|
463
|
+
int cursor;
|
|
464
|
+
char* test_identifier;
|
|
465
|
+
char type;
|
|
466
|
+
uint64_t child_hash;
|
|
467
|
+
|
|
468
|
+
while(counter < column_count) {
|
|
469
|
+
type = read_type(accessing_depth + visible_depth, level_definitions->mapping_array[counter], level_definitions->mapping_array_lengths[counter]);
|
|
470
|
+
read_identifier(accessing_depth + visible_depth, level_definitions->mapping_array[counter], &cursor, &test_identifier_length, level_definitions->mapping_array_lengths[counter]);
|
|
471
|
+
|
|
472
|
+
test_identifier = ss_alloc(builder->memory_stack, 1, test_identifier_length + 1);
|
|
473
|
+
memcpy(test_identifier, level_definitions->mapping_array[counter] + cursor, test_identifier_length);
|
|
474
|
+
test_identifier[test_identifier_length] = '\0';
|
|
475
|
+
identifier_int = atoi(test_identifier);
|
|
476
|
+
|
|
477
|
+
if (type == '4') {
|
|
478
|
+
child_hash = calculate_identified_hash(level_definitions, column_count, string_sizes, row_strings, (accessing_depth + 1), (accessing_depth + visible_depth + 1), test_identifier_length, test_identifier);
|
|
479
|
+
count_increment_or_create_json_level_child_array(builder, child_array_start, test_identifier_length, test_identifier, identifier_int, hash, child_hash);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if ((level_definitions->real_depth_array[counter] == accessing_depth) && (level_definitions->do_not_hash[counter]) && (!level_definitions->defined_flag)) {
|
|
483
|
+
level_definitions->contains_array_value_flag = 1;
|
|
484
|
+
}
|
|
485
|
+
counter++;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
char* finalize_json(JSONDocumentBuilder *builder)
|
|
490
|
+
{
|
|
491
|
+
unsigned long counter;
|
|
492
|
+
|
|
493
|
+
builder->resulting_json = ss_alloc(builder->memory_stack, 1, builder->json_char_count - 1); // Remove extra character from last comma
|
|
494
|
+
counter = 0;
|
|
495
|
+
memcpy(builder->resulting_json + counter, ob, 1);
|
|
496
|
+
counter++;
|
|
497
|
+
counter = finalize_object_array(builder, builder->root, counter);
|
|
498
|
+
|
|
499
|
+
memcpy(builder->resulting_json + counter, end, 1);
|
|
500
|
+
return builder->resulting_json;
|
|
501
|
+
}
|