Official reference client implementation for Cumulocity SmartREST on u-blox C027.

Dependencies:   C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed

Fork of MbedSmartRestMain by Vincent Wochnik

util/lex.cpp

Committer:
xinlei
Date:
2016-08-08
Revision:
139:f8ab852e83e7
Parent:
99:e369fc75c000

File content as of revision 139:f8ab852e83e7:

#include <ctype.h>
#include <string.h>
#include "lex.h"
#include "logging.h"

const char* skipHTTPHeader(const char* p)
{
        const char* ptr = p;
        if (p)
                ptr = strstr(p, "\r\n\r\n");

        if (ptr) {
                return ptr+4;
        } else {
                return NULL;
        }
}

const char* lex(const char *p, Token& t)
{
        if (p == NULL) {
                t.type = Token::NONE;
                t.p = NULL;
                t.len = 0;
                return NULL;
        }
        t.type = Token::NONE;
        size_t i = 0;
        while (p[i] && isspace(p[i])) ++i;
        bool opening = false;
        if (p[i] == '"') {
                opening = true;
                ++i;
        }
        size_t j = i;
        size_t dots = 0;
        bool hasChar = false;
        bool escaping = false;
        bool hasDigit = false;
        for (;p[j]; ++j) {
                if (p[j] == '"') {
                        if (!opening) { // inline quote
                                t.type = Token::ERROR;
                        } else if (!escaping) { // escaping quote
                                escaping = true;
                        } else {
                                hasChar = true;
                                escaping = false;
                        }
                } else {
                        if (escaping && opening) {
                                break;
                        } else if (p[j] == '.') {
                                hasChar = true;
                                dots++;
                        } else if (p[j] == ',' || iscntrl(p[j])) {
                                if (opening)
                                        hasChar = true;
                                else
                                        break;
                        } else if (isdigit(p[j])) {
                                hasDigit = true;
                        } else {
                                hasChar = true;
                        }
                }
        }
        t.p = p+i;
        size_t k = j;
        while (k > i && (p[k]==',' || isspace(p[k]))) --k;
        t.len = k-i+1;
        if (escaping && opening) {
                opening = false;
                t.len -= 1;
        }
        if (t.type != Token::ERROR) {
                if (opening) {
                        t.type = Token::ERROR;
                } else if (hasChar) {
                        t.type = Token::STRING;
                } else if (hasDigit) {
                        switch (dots) {
                        case 0: t.type = Token::INT; break;
                        case 1: t.type = Token::FLOAT; break;
                        default: t.type = Token::STRING; break;
                        }
                } else {
                        t.type = Token::NONE;
                }
        }
        while (p[j]) {
                if (isspace(p[j])) {
                        ++j;
                } else if (p[j]==',') {
                        ++j;
                        break;
                } else {
                        break;
                }
        }
        return p+j;
}

const char* lexConfig(const char* p, Token& tok)
{
        size_t j = 0;
        for (; p[j] && !isgraph(p[j]); ++j);
        size_t i = j;
        tok.p = p+j;
        if (p[i] == 0) {
                tok.type = Token::NONE;
        } else if (p[i] == '=') {
                ++i;
                tok.type = Token::ASSIGN;
        } else if (p[i] == ';') {
                ++i;
                tok.type = Token::SEMICOLON;
        } else if (isalpha(p[i])) {
                for (++i; isalnum(p[i]); ++i);
                tok.type = Token::STRING;
        } else if (isdigit(p[i])) {
                for (++i; isdigit(p[i]); ++i);
                if (p[i] == '.') {
                        for (++i; isdigit(p[i]); ++i);
                        tok.type = Token::FLOAT;
                } else if (isalnum(p[i])) {
                        for (++i; isalnum(p[i]); ++i);
                        tok.type = Token::STRING;
                } else {
                        tok.type = Token::INT;
                }
        } else {
                aError("lexConfig: %c\n", p[i]);
                for (++i; isgraph(p[i]); ++i);
                tok.type = Token::ERROR;
        }
        tok.len = i - j;
        for (; p[i] && !isgraph(p[i]); ++i);
        return p+i;
}

size_t strncpyEscape(char* dest, const char *source, size_t num)
{
        if (source == NULL) return 0;
        size_t i = 0, j = 0;
        for (bool escaping = false; i < num; ++i) {
                if (source[i] != '"') {
                        dest[j++] = source[i];
                } else {
                        if (escaping) {
                                dest[j++] = source[i];
                                escaping = false;
                        } else {
                                escaping = true;
                        }
                }
        }
        return j;
}