aboutsummaryrefslogtreecommitdiff
path: root/client/parse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'client/parse.cpp')
-rw-r--r--client/parse.cpp74
1 files changed, 47 insertions, 27 deletions
diff --git a/client/parse.cpp b/client/parse.cpp
index 6eca774..5672ff2 100644
--- a/client/parse.cpp
+++ b/client/parse.cpp
@@ -1,14 +1,13 @@
-#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <netinet/in.h>
#include "parse.h"
-static int parse_string(const char* str, char* data, size_t* offset) {
+static int parse_string(const char * str, char * data, size_t * offset) {
char closing = str[0];
char escape = false;
- bool scan = data == NULL;
int i = 0;
size_t len = strlen(str);
@@ -23,7 +22,7 @@ static int parse_string(const char* str, char* data, size_t* offset) {
return -i;
}
- for (i = 1; i < len && str[i] != '\0'; i++) {
+ for (i = 1; i < len && str[i] != '\0'; i++, *offset += 1) {
char c = str[i];
// TODO: handle escaped characters
@@ -31,16 +30,16 @@ static int parse_string(const char* str, char* data, size_t* offset) {
if (c == closing)
return i + 1; // +1 for closing quote
- *offset += 1;
+ if (data != NULL)
+ data[*offset] = c;
}
return -i;
}
-static int parse_hexstr(const char* str, char* data, size_t* offset) {
+static int parse_hexstr(const char * str, char * data, size_t * offset) {
const char* ifs = IFS;
size_t len = strcspn(str, ifs);
- bool scan = data == NULL;
int i = 0;
// check if token contains at least one colon
@@ -56,6 +55,10 @@ static int parse_hexstr(const char* str, char* data, size_t* offset) {
while (c < len) { // count bytes in bytestring
if (strspn(str + c, SET_HEX) != 2)
return -i -c;
+
+ if (data != NULL)
+ data[*offset] = strtol(str + c, NULL, 16) & 0xff;
+
c += 2;
*offset += 1;
@@ -70,10 +73,9 @@ static int parse_hexstr(const char* str, char* data, size_t* offset) {
return i;
}
-static int parse_number(const char* str, char* data, size_t* offset) {
+static int parse_number(const char * str, char * data, size_t * offset) {
const char* ifs = IFS;
size_t len = strcspn(str, ifs);
- bool scan = data == NULL;
int i = 0;
int base = 10;
bool bytestring = false;
@@ -94,8 +96,8 @@ static int parse_number(const char* str, char* data, size_t* offset) {
size_t len_ok = strspn(str + i, set) + i;
if (len != len_ok) return -len_ok;
- if (base == 10) *offset += 1;
- else if (base == 16) {
+ size_t size = 1; // default integer size in bytes
+ if (base == 16) {
size_t prefixless = len - i;
switch (prefixless) {
case 2: // 8-bit (2 hex characters)
@@ -106,40 +108,58 @@ static int parse_number(const char* str, char* data, size_t* offset) {
default:
return -i;
}
- *offset += prefixless / 2;
+ size = prefixless / 2;
}
+ if (data != NULL) {
+ unsigned long number = strtol(str + i, NULL, base);
+ long long mask = (1 << 8 * size) - 1;
+ number &= mask;
+ switch (size) {
+ case 1:
+ data[*offset] = number & 0xff;
+ break;
+ case 2:
+ number = htons(number);
+ data[*offset + 1] = (number) & 0xff;
+ data[*offset + 0] = (number >>= 8) & 0xff;
+ break;
+ case 4:
+ number = htonl(number);
+ data[*offset + 3] = (number) & 0xff;
+ data[*offset + 2] = (number >>= 8) & 0xff;
+ data[*offset + 1] = (number >>= 8) & 0xff;
+ data[*offset + 0] = (number >>= 8) & 0xff;
+ break;
+ }
+ }
+
+ *offset += size;
i += len;
return i;
}
-static int _strtodata_main(const char* str, char* _data, size_t* offset) {
+static int _strtodata_main(const char * str, char* data, size_t * offset) {
const char* ifs = IFS;
size_t len = strlen(str);
- size_t i = 0;
-
- while (i < len) {
+ int i, run;
+ for (i = 0; i < len; i += run) {
i += strspn(&str[i], ifs); // skip whitespace
if (str[i] == '\0') break; // end of string
- int run;
- char* data = _data == NULL ? NULL : _data + *offset;
- if ((run = parse_string(str + i, data, offset)) > 0) goto format_ok;
- if ((run = parse_hexstr(str + i, data, offset)) > 0) goto format_ok;
- if ((run = parse_number(str + i, data, offset)) > 0) goto format_ok;
-
- return -i + run; // no format detected
+ if ((run = parse_string(str + i, data, offset)) > 0) continue;
+ if ((run = parse_hexstr(str + i, data, offset)) > 0) continue;
+ if ((run = parse_number(str + i, data, offset)) > 0) continue;
-format_ok:
- i += run;
- continue;
+ // no format detected
+ return -i + run;
}
return i;
}
-int strtodata(const char* str, char** data, size_t* size) {
+int strtodata(const char * str, char ** data, size_t * size) {
*size = 0;
// 1st pass: check data format