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
lex.cpp
00001 #include <ctype.h> 00002 #include <string.h> 00003 #include "lex.h" 00004 #include "logging.h" 00005 00006 const char* skipHTTPHeader(const char* p) 00007 { 00008 const char* ptr = p; 00009 if (p) 00010 ptr = strstr(p, "\r\n\r\n"); 00011 00012 if (ptr) { 00013 return ptr+4; 00014 } else { 00015 return NULL; 00016 } 00017 } 00018 00019 const char* lex(const char *p, Token& t) 00020 { 00021 if (p == NULL) { 00022 t.type = Token::NONE; 00023 t.p = NULL; 00024 t.len = 0; 00025 return NULL; 00026 } 00027 t.type = Token::NONE; 00028 size_t i = 0; 00029 while (p[i] && isspace(p[i])) ++i; 00030 bool opening = false; 00031 if (p[i] == '"') { 00032 opening = true; 00033 ++i; 00034 } 00035 size_t j = i; 00036 size_t dots = 0; 00037 bool hasChar = false; 00038 bool escaping = false; 00039 bool hasDigit = false; 00040 for (;p[j]; ++j) { 00041 if (p[j] == '"') { 00042 if (!opening) { // inline quote 00043 t.type = Token::ERROR; 00044 } else if (!escaping) { // escaping quote 00045 escaping = true; 00046 } else { 00047 hasChar = true; 00048 escaping = false; 00049 } 00050 } else { 00051 if (escaping && opening) { 00052 break; 00053 } else if (p[j] == '.') { 00054 hasChar = true; 00055 dots++; 00056 } else if (p[j] == ',' || iscntrl(p[j])) { 00057 if (opening) 00058 hasChar = true; 00059 else 00060 break; 00061 } else if (isdigit(p[j])) { 00062 hasDigit = true; 00063 } else { 00064 hasChar = true; 00065 } 00066 } 00067 } 00068 t.p = p+i; 00069 size_t k = j; 00070 while (k > i && (p[k]==',' || isspace(p[k]))) --k; 00071 t.len = k-i+1; 00072 if (escaping && opening) { 00073 opening = false; 00074 t.len -= 1; 00075 } 00076 if (t.type != Token::ERROR) { 00077 if (opening) { 00078 t.type = Token::ERROR; 00079 } else if (hasChar) { 00080 t.type = Token::STRING; 00081 } else if (hasDigit) { 00082 switch (dots) { 00083 case 0: t.type = Token::INT; break; 00084 case 1: t.type = Token::FLOAT; break; 00085 default: t.type = Token::STRING; break; 00086 } 00087 } else { 00088 t.type = Token::NONE; 00089 } 00090 } 00091 while (p[j]) { 00092 if (isspace(p[j])) { 00093 ++j; 00094 } else if (p[j]==',') { 00095 ++j; 00096 break; 00097 } else { 00098 break; 00099 } 00100 } 00101 return p+j; 00102 } 00103 00104 const char* lexConfig(const char* p, Token& tok) 00105 { 00106 size_t j = 0; 00107 for (; p[j] && !isgraph(p[j]); ++j); 00108 size_t i = j; 00109 tok.p = p+j; 00110 if (p[i] == 0) { 00111 tok.type = Token::NONE; 00112 } else if (p[i] == '=') { 00113 ++i; 00114 tok.type = Token::ASSIGN; 00115 } else if (p[i] == ';') { 00116 ++i; 00117 tok.type = Token::SEMICOLON; 00118 } else if (isalpha(p[i])) { 00119 for (++i; isalnum(p[i]); ++i); 00120 tok.type = Token::STRING; 00121 } else if (isdigit(p[i])) { 00122 for (++i; isdigit(p[i]); ++i); 00123 if (p[i] == '.') { 00124 for (++i; isdigit(p[i]); ++i); 00125 tok.type = Token::FLOAT; 00126 } else if (isalnum(p[i])) { 00127 for (++i; isalnum(p[i]); ++i); 00128 tok.type = Token::STRING; 00129 } else { 00130 tok.type = Token::INT; 00131 } 00132 } else { 00133 aError("lexConfig: %c\n", p[i]); 00134 for (++i; isgraph(p[i]); ++i); 00135 tok.type = Token::ERROR; 00136 } 00137 tok.len = i - j; 00138 for (; p[i] && !isgraph(p[i]); ++i); 00139 return p+i; 00140 } 00141 00142 size_t strncpyEscape(char* dest, const char *source, size_t num) 00143 { 00144 if (source == NULL) return 0; 00145 size_t i = 0, j = 0; 00146 for (bool escaping = false; i < num; ++i) { 00147 if (source[i] != '"') { 00148 dest[j++] = source[i]; 00149 } else { 00150 if (escaping) { 00151 dest[j++] = source[i]; 00152 escaping = false; 00153 } else { 00154 escaping = true; 00155 } 00156 } 00157 } 00158 return j; 00159 }
Generated on Wed Jul 13 2022 19:40:51 by 1.7.2