pcb defect detetcion application
[ealt-edge.git] / example-apps / PDD / pcb-defect-detection / data / lib_coco / common / gason.cpp
diff --git a/example-apps/PDD/pcb-defect-detection/data/lib_coco/common/gason.cpp b/example-apps/PDD/pcb-defect-detection/data/lib_coco/common/gason.cpp
new file mode 100755 (executable)
index 0000000..0f2c00e
--- /dev/null
@@ -0,0 +1,335 @@
+// https://github.com/vivkin/gason - pulled January 10, 2016
+#include "gason.h"
+#include <stdlib.h>
+
+#define JSON_ZONE_SIZE 4096
+#define JSON_STACK_SIZE 32
+
+const char *jsonStrError(int err) {
+    switch (err) {
+#define XX(no, str) \
+    case JSON_##no: \
+        return str;
+        JSON_ERRNO_MAP(XX)
+#undef XX
+    default:
+        return "unknown";
+    }
+}
+
+void *JsonAllocator::allocate(size_t size) {
+    size = (size + 7) & ~7;
+
+    if (head && head->used + size <= JSON_ZONE_SIZE) {
+        char *p = (char *)head + head->used;
+        head->used += size;
+        return p;
+    }
+
+    size_t allocSize = sizeof(Zone) + size;
+    Zone *zone = (Zone *)malloc(allocSize <= JSON_ZONE_SIZE ? JSON_ZONE_SIZE : allocSize);
+    if (zone == nullptr)
+        return nullptr;
+    zone->used = allocSize;
+    if (allocSize <= JSON_ZONE_SIZE || head == nullptr) {
+        zone->next = head;
+        head = zone;
+    } else {
+        zone->next = head->next;
+        head->next = zone;
+    }
+    return (char *)zone + sizeof(Zone);
+}
+
+void JsonAllocator::deallocate() {
+    while (head) {
+        Zone *next = head->next;
+        free(head);
+        head = next;
+    }
+}
+
+static inline bool isspace(char c) {
+    return c == ' ' || (c >= '\t' && c <= '\r');
+}
+
+static inline bool isdelim(char c) {
+    return c == ',' || c == ':' || c == ']' || c == '}' || isspace(c) || !c;
+}
+
+static inline bool isdigit(char c) {
+    return c >= '0' && c <= '9';
+}
+
+static inline bool isxdigit(char c) {
+    return (c >= '0' && c <= '9') || ((c & ~' ') >= 'A' && (c & ~' ') <= 'F');
+}
+
+static inline int char2int(char c) {
+    if (c <= '9')
+        return c - '0';
+    return (c & ~' ') - 'A' + 10;
+}
+
+static double string2double(char *s, char **endptr) {
+    char ch = *s;
+    if (ch == '-')
+        ++s;
+
+    double result = 0;
+    while (isdigit(*s))
+        result = (result * 10) + (*s++ - '0');
+
+    if (*s == '.') {
+        ++s;
+
+        double fraction = 1;
+        while (isdigit(*s)) {
+            fraction *= 0.1;
+            result += (*s++ - '0') * fraction;
+        }
+    }
+
+    if (*s == 'e' || *s == 'E') {
+        ++s;
+
+        double base = 10;
+        if (*s == '+')
+            ++s;
+        else if (*s == '-') {
+            ++s;
+            base = 0.1;
+        }
+
+        unsigned int exponent = 0;
+        while (isdigit(*s))
+            exponent = (exponent * 10) + (*s++ - '0');
+
+        double power = 1;
+        for (; exponent; exponent >>= 1, base *= base)
+            if (exponent & 1)
+                power *= base;
+
+        result *= power;
+    }
+
+    *endptr = s;
+    return ch == '-' ? -result : result;
+}
+
+static inline JsonNode *insertAfter(JsonNode *tail, JsonNode *node) {
+    if (!tail)
+        return node->next = node;
+    node->next = tail->next;
+    tail->next = node;
+    return node;
+}
+
+static inline JsonValue listToValue(JsonTag tag, JsonNode *tail) {
+    if (tail) {
+        auto head = tail->next;
+        tail->next = nullptr;
+        return JsonValue(tag, head);
+    }
+    return JsonValue(tag, nullptr);
+}
+
+int jsonParse(char *s, char **endptr, JsonValue *value, JsonAllocator &allocator) {
+    JsonNode *tails[JSON_STACK_SIZE];
+    JsonTag tags[JSON_STACK_SIZE];
+    char *keys[JSON_STACK_SIZE];
+    JsonValue o;
+    int pos = -1;
+    bool separator = true;
+    JsonNode *node;
+    *endptr = s;
+
+    while (*s) {
+        while (isspace(*s)) {
+            ++s;
+            if (!*s) break;
+        }
+        *endptr = s++;
+        switch (**endptr) {
+        case '-':
+            if (!isdigit(*s) && *s != '.') {
+                *endptr = s;
+                return JSON_BAD_NUMBER;
+            }
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            o = JsonValue(string2double(*endptr, &s));
+            if (!isdelim(*s)) {
+                *endptr = s;
+                return JSON_BAD_NUMBER;
+            }
+            break;
+        case '"':
+            o = JsonValue(JSON_STRING, s);
+            for (char *it = s; *s; ++it, ++s) {
+                int c = *it = *s;
+                if (c == '\\') {
+                    c = *++s;
+                    switch (c) {
+                    case '\\':
+                    case '"':
+                    case '/':
+                        *it = c;
+                        break;
+                    case 'b':
+                        *it = '\b';
+                        break;
+                    case 'f':
+                        *it = '\f';
+                        break;
+                    case 'n':
+                        *it = '\n';
+                        break;
+                    case 'r':
+                        *it = '\r';
+                        break;
+                    case 't':
+                        *it = '\t';
+                        break;
+                    case 'u':
+                        c = 0;
+                        for (int i = 0; i < 4; ++i) {
+                            if (isxdigit(*++s)) {
+                                c = c * 16 + char2int(*s);
+                            } else {
+                                *endptr = s;
+                                return JSON_BAD_STRING;
+                            }
+                        }
+                        if (c < 0x80) {
+                            *it = c;
+                        } else if (c < 0x800) {
+                            *it++ = 0xC0 | (c >> 6);
+                            *it = 0x80 | (c & 0x3F);
+                        } else {
+                            *it++ = 0xE0 | (c >> 12);
+                            *it++ = 0x80 | ((c >> 6) & 0x3F);
+                            *it = 0x80 | (c & 0x3F);
+                        }
+                        break;
+                    default:
+                        *endptr = s;
+                        return JSON_BAD_STRING;
+                    }
+                } else if ((unsigned int)c < ' ' || c == '\x7F') {
+                    *endptr = s;
+                    return JSON_BAD_STRING;
+                } else if (c == '"') {
+                    *it = 0;
+                    ++s;
+                    break;
+                }
+            }
+            if (!isdelim(*s)) {
+                *endptr = s;
+                return JSON_BAD_STRING;
+            }
+            break;
+        case 't':
+            if (!(s[0] == 'r' && s[1] == 'u' && s[2] == 'e' && isdelim(s[3])))
+                return JSON_BAD_IDENTIFIER;
+            o = JsonValue(JSON_TRUE);
+            s += 3;
+            break;
+        case 'f':
+            if (!(s[0] == 'a' && s[1] == 'l' && s[2] == 's' && s[3] == 'e' && isdelim(s[4])))
+                return JSON_BAD_IDENTIFIER;
+            o = JsonValue(JSON_FALSE);
+            s += 4;
+            break;
+        case 'n':
+            if (!(s[0] == 'u' && s[1] == 'l' && s[2] == 'l' && isdelim(s[3])))
+                return JSON_BAD_IDENTIFIER;
+            o = JsonValue(JSON_NULL);
+            s += 3;
+            break;
+        case ']':
+            if (pos == -1)
+                return JSON_STACK_UNDERFLOW;
+            if (tags[pos] != JSON_ARRAY)
+                return JSON_MISMATCH_BRACKET;
+            o = listToValue(JSON_ARRAY, tails[pos--]);
+            break;
+        case '}':
+            if (pos == -1)
+                return JSON_STACK_UNDERFLOW;
+            if (tags[pos] != JSON_OBJECT)
+                return JSON_MISMATCH_BRACKET;
+            if (keys[pos] != nullptr)
+                return JSON_UNEXPECTED_CHARACTER;
+            o = listToValue(JSON_OBJECT, tails[pos--]);
+            break;
+        case '[':
+            if (++pos == JSON_STACK_SIZE)
+                return JSON_STACK_OVERFLOW;
+            tails[pos] = nullptr;
+            tags[pos] = JSON_ARRAY;
+            keys[pos] = nullptr;
+            separator = true;
+            continue;
+        case '{':
+            if (++pos == JSON_STACK_SIZE)
+                return JSON_STACK_OVERFLOW;
+            tails[pos] = nullptr;
+            tags[pos] = JSON_OBJECT;
+            keys[pos] = nullptr;
+            separator = true;
+            continue;
+        case ':':
+            if (separator || keys[pos] == nullptr)
+                return JSON_UNEXPECTED_CHARACTER;
+            separator = true;
+            continue;
+        case ',':
+            if (separator || keys[pos] != nullptr)
+                return JSON_UNEXPECTED_CHARACTER;
+            separator = true;
+            continue;
+        case '\0':
+            continue;
+        default:
+            return JSON_UNEXPECTED_CHARACTER;
+        }
+
+        separator = false;
+
+        if (pos == -1) {
+            *endptr = s;
+            *value = o;
+            return JSON_OK;
+        }
+
+        if (tags[pos] == JSON_OBJECT) {
+            if (!keys[pos]) {
+                if (o.getTag() != JSON_STRING)
+                    return JSON_UNQUOTED_KEY;
+                keys[pos] = o.toString();
+                continue;
+            }
+            if ((node = (JsonNode *) allocator.allocate(sizeof(JsonNode))) == nullptr)
+                return JSON_ALLOCATION_FAILURE;
+            tails[pos] = insertAfter(tails[pos], node);
+            tails[pos]->key = keys[pos];
+            keys[pos] = nullptr;
+        } else {
+            if ((node = (JsonNode *) allocator.allocate(sizeof(JsonNode) - sizeof(char *))) == nullptr)
+                return JSON_ALLOCATION_FAILURE;
+            tails[pos] = insertAfter(tails[pos], node);
+        }
+        tails[pos]->value = o;
+    }
+    return JSON_BREAKING_BAD;
+}