-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdecode.c
114 lines (99 loc) · 3.8 KB
/
decode.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "decode.h"
// decode_cjson_op decodes a cJSON item into an op.
ot_err decode_cjson_op(cJSON* json, ot_op* op) {
cJSON* error_code = cJSON_GetObjectItem(json, "errorCode");
if (error_code != NULL) {
return error_code->valueint;
}
cJSON* client_idf = cJSON_GetObjectItem(json, "clientId");
if (client_idf == NULL) {
return OT_ERR_CLIENT_ID_MISSING;
}
op->client_id = (uint32_t)client_idf->valueint;
cJSON* parentf = cJSON_GetObjectItem(json, "parent");
if (parentf == NULL) {
return OT_ERR_PARENT_MISSING;
}
memset(op->parent, 0, 20);
hextoa(op->parent, 20, parentf->valuestring, strlen(parentf->valuestring));
cJSON* hashf = cJSON_GetObjectItem(json, "hash");
if (hashf == NULL) {
return OT_ERR_HASH_MISSING;
}
memset(op->hash, 0, 20);
hextoa(op->hash, 20, hashf->valuestring, strlen(hashf->valuestring));
cJSON* components = cJSON_GetObjectItem(json, "components");
if (components == NULL) {
return OT_ERR_COMPONENTS_MISSING;
}
int size = cJSON_GetArraySize(components);
for (int i = 0; i < size; ++i) {
cJSON* item = cJSON_GetArrayItem(components, i);
char* type = cJSON_GetObjectItem(item, "type")->valuestring;
if (memcmp(type, "skip", 4) == 0) {
ot_comp* skip = array_append(&op->comps);
skip->type = OT_SKIP;
skip->value.skip.count =
(uint32_t)cJSON_GetObjectItem(item, "count")->valueint;
} else if (memcmp(type, "insert", 6) == 0) {
ot_comp* insert = array_append(&op->comps);
insert->type = OT_INSERT;
char* text = cJSON_GetObjectItem(item, "text")->valuestring;
size_t text_size = sizeof(char) * (strlen(text) + 1);
insert->value.insert.text = malloc(text_size);
memcpy(insert->value.insert.text, text, text_size);
} else if (memcmp(type, "delete", 6) == 0) {
ot_comp* delete = array_append(&op->comps);
delete->type = OT_DELETE;
delete->value.delete.count =
(uint32_t)cJSON_GetObjectItem(item, "count")->valueint;
} else if (memcmp(type, "openElement", 11) == 0) {
ot_comp* open_elem = array_append(&op->comps);
open_elem->type = OT_OPEN_ELEMENT;
open_elem->value.open_element.elem =
cJSON_GetObjectItem(item, "element")->valuestring;
} else if (memcmp(type, "closeElement", 12) == 0) {
ot_comp* open_elem = array_append(&op->comps);
open_elem->type = OT_CLOSE_ELEMENT;
} else if (memcmp(type, "formattingBoundary", 18) == 0) {
ot_comp* open_elem = array_append(&op->comps);
open_elem->type = OT_FORMATTING_BOUNDARY;
} else {
return OT_ERR_INVALID_COMPONENT;
}
}
return OT_ERR_NONE;
}
// TODO: Finish implementing decoding of formatting boundaries.
ot_err ot_decode(ot_op* op, const char* json) {
cJSON* root = cJSON_Parse(json);
if (root == NULL) {
return OT_ERR_INVALID_JSON;
}
ot_err err = decode_cjson_op(root, op);
cJSON_Delete(root);
return err;
}
ot_err ot_decode_doc(ot_doc* doc, const char* const json) {
cJSON* root = cJSON_Parse(json);
if (root == NULL) {
return OT_ERR_INVALID_JSON;
}
int max = cJSON_GetArraySize(root);
for (int i = 0; i < max; ++i) {
cJSON* item = cJSON_GetArrayItem(root, i);
ot_op* op = ot_new_op();
ot_err err = decode_cjson_op(item, op);
if (err != OT_ERR_NONE) {
cJSON_Delete(root);
return err;
}
err = ot_doc_append(doc, &op);
if (err != OT_ERR_NONE) {
cJSON_Delete(root);
return err;
}
}
cJSON_Delete(root);
return OT_ERR_NONE;
}