The Pubnub C-core library. It's home is on https://github.com/pubnub/c_core, this is a copy

Dependents:   Pubnub_c_core_mbed2_pal Pubnub_c_core_mbed2_pal Pubnub_c_core_mbed2_pal2

Committer:
sveljko
Date:
Tue Nov 22 22:21:39 2016 +0000
Revision:
2:d85e42c1125d
Parent:
0:d13755cfb705
Added `pubnub_helper` module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sveljko 0:d13755cfb705 1 /* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */
sveljko 0:d13755cfb705 2 #include "pubnub_json_parse.h"
sveljko 0:d13755cfb705 3
sveljko 0:d13755cfb705 4 #include <string.h>
sveljko 0:d13755cfb705 5
sveljko 0:d13755cfb705 6
sveljko 0:d13755cfb705 7 char const* pbjson_skip_whitespace(char const *start, char const *end)
sveljko 0:d13755cfb705 8 {
sveljko 0:d13755cfb705 9 for (; start < end; ++start) {
sveljko 0:d13755cfb705 10 switch (*start) {
sveljko 0:d13755cfb705 11 case ' ':
sveljko 0:d13755cfb705 12 case '\t':
sveljko 0:d13755cfb705 13 case '\r':
sveljko 0:d13755cfb705 14 case '\n':
sveljko 0:d13755cfb705 15 break;
sveljko 0:d13755cfb705 16 default:
sveljko 0:d13755cfb705 17 return start;
sveljko 0:d13755cfb705 18 }
sveljko 0:d13755cfb705 19 }
sveljko 0:d13755cfb705 20 return start;
sveljko 0:d13755cfb705 21 }
sveljko 0:d13755cfb705 22
sveljko 0:d13755cfb705 23
sveljko 0:d13755cfb705 24 char const* pbjson_find_end_string(char const *start, char const *end)
sveljko 0:d13755cfb705 25 {
sveljko 0:d13755cfb705 26 bool in_escape = false;
sveljko 0:d13755cfb705 27
sveljko 0:d13755cfb705 28 for (; start < end; ++start) {
sveljko 0:d13755cfb705 29 switch (*start) {
sveljko 0:d13755cfb705 30 case '"':
sveljko 0:d13755cfb705 31 if (!in_escape) {
sveljko 0:d13755cfb705 32 return start;
sveljko 0:d13755cfb705 33 }
sveljko 0:d13755cfb705 34 break;
sveljko 0:d13755cfb705 35 case '\\':
sveljko 0:d13755cfb705 36 in_escape = !in_escape;
sveljko 0:d13755cfb705 37 break;
sveljko 0:d13755cfb705 38 case '\0':
sveljko 0:d13755cfb705 39 return start;
sveljko 0:d13755cfb705 40 default:
sveljko 0:d13755cfb705 41 in_escape = false;
sveljko 0:d13755cfb705 42 break;
sveljko 0:d13755cfb705 43 }
sveljko 0:d13755cfb705 44 }
sveljko 0:d13755cfb705 45
sveljko 0:d13755cfb705 46 return start;
sveljko 0:d13755cfb705 47 }
sveljko 0:d13755cfb705 48
sveljko 0:d13755cfb705 49
sveljko 0:d13755cfb705 50 char const *pbjson_find_end_primitive(char const *start, char const *end)
sveljko 0:d13755cfb705 51 {
sveljko 0:d13755cfb705 52 for (; start < end; ++start) {
sveljko 0:d13755cfb705 53 switch (*start) {
sveljko 0:d13755cfb705 54 case ' ':
sveljko 0:d13755cfb705 55 case '\t':
sveljko 0:d13755cfb705 56 case '\r':
sveljko 0:d13755cfb705 57 case '\n':
sveljko 0:d13755cfb705 58 case ',':
sveljko 0:d13755cfb705 59 case '}':
sveljko 0:d13755cfb705 60 case ']':
sveljko 0:d13755cfb705 61 return start-1;
sveljko 0:d13755cfb705 62 case '\0':
sveljko 0:d13755cfb705 63 return start;
sveljko 0:d13755cfb705 64 default:
sveljko 0:d13755cfb705 65 break;
sveljko 0:d13755cfb705 66 }
sveljko 0:d13755cfb705 67 }
sveljko 0:d13755cfb705 68 return start;
sveljko 0:d13755cfb705 69 }
sveljko 0:d13755cfb705 70
sveljko 0:d13755cfb705 71
sveljko 0:d13755cfb705 72 char const *pbjson_find_end_complex(char const *start, char const *end)
sveljko 0:d13755cfb705 73 {
sveljko 0:d13755cfb705 74 bool in_string = false, in_escape = false;
sveljko 0:d13755cfb705 75 int bracket_level = 0, brace_level = 0;
sveljko 0:d13755cfb705 76 char c;
sveljko 0:d13755cfb705 77 char const *s;
sveljko 0:d13755cfb705 78
sveljko 0:d13755cfb705 79 for (s = start, c = *s; (c != '\0') && (s < end); ++s, c = *s) {
sveljko 0:d13755cfb705 80 if (!in_string) {
sveljko 0:d13755cfb705 81 switch (c) {
sveljko 0:d13755cfb705 82 case '{':
sveljko 0:d13755cfb705 83 ++brace_level;
sveljko 0:d13755cfb705 84 break;
sveljko 0:d13755cfb705 85 case '}':
sveljko 0:d13755cfb705 86 if ((--brace_level == 0) && (0 == bracket_level)) {
sveljko 0:d13755cfb705 87 return s;
sveljko 0:d13755cfb705 88 }
sveljko 0:d13755cfb705 89 break;
sveljko 0:d13755cfb705 90 case '[':
sveljko 0:d13755cfb705 91 ++bracket_level;
sveljko 0:d13755cfb705 92 break;
sveljko 0:d13755cfb705 93 case ']':
sveljko 0:d13755cfb705 94 if ((--bracket_level == 0) && (0 == brace_level)) {
sveljko 0:d13755cfb705 95 return s;
sveljko 0:d13755cfb705 96 }
sveljko 0:d13755cfb705 97 break;
sveljko 0:d13755cfb705 98 case '"':
sveljko 0:d13755cfb705 99 in_string = true;
sveljko 0:d13755cfb705 100 in_escape = false;
sveljko 0:d13755cfb705 101 break;
sveljko 0:d13755cfb705 102 default:
sveljko 0:d13755cfb705 103 break;
sveljko 0:d13755cfb705 104 }
sveljko 0:d13755cfb705 105 }
sveljko 0:d13755cfb705 106 else {
sveljko 0:d13755cfb705 107 switch (c) {
sveljko 0:d13755cfb705 108 case '"':
sveljko 0:d13755cfb705 109 if (!in_escape) {
sveljko 0:d13755cfb705 110 in_string = false;
sveljko 0:d13755cfb705 111 }
sveljko 0:d13755cfb705 112 break;
sveljko 0:d13755cfb705 113 case '\\':
sveljko 0:d13755cfb705 114 in_escape = !in_escape;
sveljko 0:d13755cfb705 115 break;
sveljko 0:d13755cfb705 116 default:
sveljko 0:d13755cfb705 117 in_escape = false;
sveljko 0:d13755cfb705 118 break;
sveljko 0:d13755cfb705 119 }
sveljko 0:d13755cfb705 120 }
sveljko 0:d13755cfb705 121 }
sveljko 0:d13755cfb705 122 return s;
sveljko 0:d13755cfb705 123 }
sveljko 0:d13755cfb705 124
sveljko 0:d13755cfb705 125
sveljko 0:d13755cfb705 126 char const *pbjson_find_end_element(char const *start, char const *end)
sveljko 0:d13755cfb705 127 {
sveljko 0:d13755cfb705 128 switch (*start) {
sveljko 0:d13755cfb705 129 case '"':
sveljko 0:d13755cfb705 130 return pbjson_find_end_string(start+1, end);
sveljko 0:d13755cfb705 131 case '{':
sveljko 0:d13755cfb705 132 case '[':
sveljko 0:d13755cfb705 133 return pbjson_find_end_complex(start, end);
sveljko 0:d13755cfb705 134 default:
sveljko 0:d13755cfb705 135 return pbjson_find_end_primitive(start+1, end);
sveljko 0:d13755cfb705 136 }
sveljko 0:d13755cfb705 137 }
sveljko 0:d13755cfb705 138
sveljko 0:d13755cfb705 139
sveljko 0:d13755cfb705 140 enum pbjson_object_name_parse_result pbjson_get_object_value(struct pbjson_elem const *p, char const *name, struct pbjson_elem *parsed)
sveljko 0:d13755cfb705 141 {
sveljko 0:d13755cfb705 142 char const *s = pbjson_skip_whitespace(p->start, p->end);
sveljko 0:d13755cfb705 143 unsigned name_len = strlen(name);
sveljko 0:d13755cfb705 144 bool found = false;
sveljko 0:d13755cfb705 145 char const *end;
sveljko 0:d13755cfb705 146
sveljko 0:d13755cfb705 147 if (0 == name_len) {
sveljko 0:d13755cfb705 148 return jonmpInvalidKeyName;
sveljko 0:d13755cfb705 149 }
sveljko 0:d13755cfb705 150 if (*s != '{') {
sveljko 0:d13755cfb705 151 return jonmpNoStartCurly;
sveljko 0:d13755cfb705 152 }
sveljko 0:d13755cfb705 153 while (s < p->end) {
sveljko 0:d13755cfb705 154 s = pbjson_skip_whitespace(s+1, p->end);
sveljko 0:d13755cfb705 155 if (s == p->end) {
sveljko 0:d13755cfb705 156 return jonmpKeyMissing;
sveljko 0:d13755cfb705 157 }
sveljko 0:d13755cfb705 158 if (*s != '"') {
sveljko 0:d13755cfb705 159 return jonmpKeyNotString;
sveljko 0:d13755cfb705 160 }
sveljko 0:d13755cfb705 161 end = pbjson_find_end_string(s+1, p->end);
sveljko 0:d13755cfb705 162 if (end == p->end) {
sveljko 0:d13755cfb705 163 return jonmpStringNotTerminated;
sveljko 0:d13755cfb705 164 }
sveljko 0:d13755cfb705 165 if (*end != '"') {
sveljko 0:d13755cfb705 166 return jonmpStringNotTerminated;
sveljko 0:d13755cfb705 167 }
sveljko 0:d13755cfb705 168 found = (end-s-1 == name_len) && (0 == memcmp(s+1, name, name_len));
sveljko 0:d13755cfb705 169 s = pbjson_skip_whitespace(end+1, p->end);
sveljko 0:d13755cfb705 170 if (s == p->end) {
sveljko 0:d13755cfb705 171 return jonmpMissingColon;
sveljko 0:d13755cfb705 172 }
sveljko 0:d13755cfb705 173 if (*s != ':') {
sveljko 0:d13755cfb705 174 return jonmpMissingColon;
sveljko 0:d13755cfb705 175 }
sveljko 0:d13755cfb705 176 s = pbjson_skip_whitespace(s+1, p->end);
sveljko 0:d13755cfb705 177 end = pbjson_find_end_element(s, p->end);
sveljko 0:d13755cfb705 178 if (found) {
sveljko 0:d13755cfb705 179 parsed->start = s;
sveljko 0:d13755cfb705 180 parsed->end = end+1;
sveljko 0:d13755cfb705 181 return jonmpOK;
sveljko 0:d13755cfb705 182 }
sveljko 0:d13755cfb705 183 s = pbjson_skip_whitespace(end+1, p->end);
sveljko 0:d13755cfb705 184 if (*s != ',') {
sveljko 0:d13755cfb705 185 if (*s == '}') {
sveljko 0:d13755cfb705 186 break;
sveljko 0:d13755cfb705 187 }
sveljko 0:d13755cfb705 188 return jonmpMissingValueSeparator;
sveljko 0:d13755cfb705 189 }
sveljko 0:d13755cfb705 190 }
sveljko 0:d13755cfb705 191
sveljko 0:d13755cfb705 192 return (s < p->end) ? jonmpKeyNotFound : jonmpObjectIncomplete;
sveljko 0:d13755cfb705 193 }
sveljko 0:d13755cfb705 194
sveljko 0:d13755cfb705 195
sveljko 0:d13755cfb705 196 bool pbjson_elem_equals_string(struct pbjson_elem const *e, char const *s)
sveljko 0:d13755cfb705 197 {
sveljko 0:d13755cfb705 198 char const *p = e->start;
sveljko 0:d13755cfb705 199 for (p = e->start; p != e->end; ++p, ++s) {
sveljko 0:d13755cfb705 200 if (*p != *s) {
sveljko 0:d13755cfb705 201 return false;
sveljko 0:d13755cfb705 202 }
sveljko 0:d13755cfb705 203 }
sveljko 0:d13755cfb705 204 return *s == '\0';
sveljko 0:d13755cfb705 205 }
sveljko 0:d13755cfb705 206
sveljko 0:d13755cfb705 207
sveljko 0:d13755cfb705 208 char const *pbjson_object_name_parse_result_2_string(enum pbjson_object_name_parse_result e)
sveljko 0:d13755cfb705 209 {
sveljko 0:d13755cfb705 210 switch (e) {
sveljko 0:d13755cfb705 211 case jonmpNoStartCurly: return "No Start Curly";
sveljko 0:d13755cfb705 212 case jonmpKeyMissing: return "Key Missing";
sveljko 0:d13755cfb705 213 case jonmpKeyNotString: return "Key Not String";
sveljko 0:d13755cfb705 214 case jonmpStringNotTerminated: return "String Not Terminated";
sveljko 0:d13755cfb705 215 case jonmpMissingColon: return "Missing Colon";
sveljko 0:d13755cfb705 216 case jonmpObjectIncomplete: return "Object Incomplete";
sveljko 0:d13755cfb705 217 case jonmpMissingValueSeparator: return "Missing Value Separator";
sveljko 0:d13755cfb705 218 case jonmpKeyNotFound: return "Key Not Found";
sveljko 0:d13755cfb705 219 case jonmpInvalidKeyName: return "Invalid Key Name";
sveljko 0:d13755cfb705 220 case jonmpOK: return "OK";
sveljko 0:d13755cfb705 221 default: return "?!?";
sveljko 0:d13755cfb705 222 }
sveljko 0:d13755cfb705 223 }