diff --git a/src/userland/buffersTests/include/buffers.h b/src/userland/buffersTests/include/buffers.h index eaba462..afb0a0e 100644 --- a/src/userland/buffersTests/include/buffers.h +++ b/src/userland/buffersTests/include/buffers.h @@ -104,38 +104,41 @@ #define EXPAND1(...) EXPAND2(EXPAND2(EXPAND2(EXPAND2(__VA_ARGS__)))) #define EXPAND(...) EXPAND1(EXPAND1(EXPAND1(EXPAND1(__VA_ARGS__)))) -#define STRING_Length(x) stringLength(strlen(x)) +#define STRING_Length(x) msgPackStringLength(strlen(x)) #define ONE(...) 1 #define ARRAY_Length_id() ARRAY_Length -#define _INTEGER_LENGTH(x, type, ...) integerLength(x, type) +#define _INTEGER_LENGTH(x, type, ...) msgPackIntegerLength(x, type) #define INTEGER_Length(x, ...) _INTEGER_LENGTH(x, ##__VA_ARGS__ , Unsigned) #define INTEGER_Length_id() INTEGER_Length #define STRING_Length_id() STRING_Length #define MAP_Length_id() MAP_Length -#define ARRAY_Length(contents) arrayLength(contents(ONE, +)) + contents(LENGTH, +) -#define MAP_Length(contents) mapLength(contents(ONE, +)) + contents(LENGTH, +) +#define ARRAY_Length(contents) msgPackArrayLength(contents(ONE, +)) + contents(LENGTH, +) +#define MAP_Length(contents) msgPackMapLength(contents(ONE, +)) + contents(LENGTH, +) #define LENGTH(type, ...) DEFER(type##_Length_id)()(__VA_ARGS__) -#define _INTEGER_WRITE(x, type, ...) buffer = integerWrite(buffer, x, type); +#define _INTEGER_WRITE(x, type, ...) buffer = msgPackIntegerWrite(buffer, x, type); #define INTEGER_Write(x, ...) _INTEGER_WRITE(x, ##__VA_ARGS__ , Unsigned) -#define STRING_Write(x) buffer = stringWrite(buffer, x); +#define STRING_Write(x) buffer = msgPackStringWrite(buffer, x); #define INTEGER_Write_id() INTEGER_Write #define ARRAY_Write_id() ARRAY_Write #define STRING_Write_id() STRING_Write #define MAP_Write_id() MAP_Write -#define ARRAY_Write(contents) buffer = arrayWrite(buffer, contents(ONE, +)); contents(WRITE, NOTHING) -#define MAP_Write(contents) buffer = mapWrite(buffer, contents(ONE, +)); contents(WRITE, NOTHING) +#define ARRAY_Write(contents) buffer = msgPackArrayWrite(buffer, contents(ONE, +)); contents(WRITE, NOTHING) +#define MAP_Write(contents) buffer = msgPackMapWrite(buffer, contents(ONE, +)); contents(WRITE, NOTHING) #define WRITE(type, ...) DEFER(type##_Write_id)()(__VA_ARGS__) #define CONTENTS contents (LENGTH, +) +extern uint32_t msgPackReadUint(void *data); +extern intmax_t msgPackReadInt(void *data); + #define CREATE(name, definition) \ uint32_t name##Length = EXPAND(definition(LENGTH)); \ void *name = malloc(name##Length); \ @@ -151,7 +154,7 @@ uint8_t *buffer = (uint8_t *) data; \ uint8_t type = FirstByteToFormat[*buffer]; \ if (formatInfo[type].dataType != TYPE_INTEGER) catchError \ - readInt(data); \ + msgPackReadInt(data); \ }) #define _AS_UINT(data, catchError, catchNegative) \ @@ -159,7 +162,7 @@ uint8_t *buffer = (uint8_t *) data; \ uint8_t type = FirstByteToFormat[*buffer]; \ if (formatInfo[type].dataType != TYPE_INTEGER) catchError \ - intmax_t asInt = readInt(data); \ + intmax_t asInt = msgPackReadInt(data); \ if (asInt < 0) catchNegative \ (uint32_t) asInt; \ }) @@ -169,7 +172,7 @@ uint8_t *buffer = (uint8_t *) data; \ uint8_t type = FirstByteToFormat[*buffer]; \ if (formatInfo[type].dataType != TYPE_STRING) catchError \ - readStr(data); \ + msgPackReadStr(data); \ }) #define AS_INT(data, retval, ...) \ @@ -190,10 +193,10 @@ return retval; \ } \ void *elementName; \ - uint32_t maxElement = readArraySize(data, &elementName); \ + uint32_t maxElement = msgPackReadArraySize(data, &elementName); \ for (uint32_t i = 0; i < maxElement; i++) { \ (action); \ - elementName = seek(elementName); \ + elementName = msgPackSeek(elementName); \ } \ } @@ -205,12 +208,24 @@ printf("GET_FROM_INT: cannot convert '" #data "' to a map, got %s\n", formatInfo[type].name); \ return retval; \ } \ - mapGetFromInt(data, value); \ + msgPackMapGetFromInt(data, value); \ }) +#define GET_FROM_STRING(data, value, retval) \ + ({ \ + uint8_t *buffer = (uint8_t *)data; \ + uint8_t type = FirstByteToFormat[*buffer]; \ + if (formatInfo[type].dataType != TYPE_MAP) { \ + printf("GET_FROM_STRING: cannot convert '" #data "' to a map, got %s\n", formatInfo[type].name); \ + return retval; \ + } \ + msgPackMapGetFromString(data, value); \ + }) -extern uint32_t readUint(void *data); -extern intmax_t readInt(void *data); +typedef char * STRING; +typedef intmax_t INT; +#define _GET(type, name, retval, ...) type name = AS_##type(GET_FROM_STRING(data, #name, retval), retval); +#define GET(type, name, ...) _GET(type, name, ##__VA_ARGS__, -1) #endif // BUFFERS_H \ No newline at end of file diff --git a/src/userland/buffersTests/include/buffers.h b/src/userland/buffersTests/include/buffers.h index eaba462..afb0a0e 100644 --- a/src/userland/buffersTests/include/buffers.h +++ b/src/userland/buffersTests/include/buffers.h @@ -104,38 +104,41 @@ #define EXPAND1(...) EXPAND2(EXPAND2(EXPAND2(EXPAND2(__VA_ARGS__)))) #define EXPAND(...) EXPAND1(EXPAND1(EXPAND1(EXPAND1(__VA_ARGS__)))) -#define STRING_Length(x) stringLength(strlen(x)) +#define STRING_Length(x) msgPackStringLength(strlen(x)) #define ONE(...) 1 #define ARRAY_Length_id() ARRAY_Length -#define _INTEGER_LENGTH(x, type, ...) integerLength(x, type) +#define _INTEGER_LENGTH(x, type, ...) msgPackIntegerLength(x, type) #define INTEGER_Length(x, ...) _INTEGER_LENGTH(x, ##__VA_ARGS__ , Unsigned) #define INTEGER_Length_id() INTEGER_Length #define STRING_Length_id() STRING_Length #define MAP_Length_id() MAP_Length -#define ARRAY_Length(contents) arrayLength(contents(ONE, +)) + contents(LENGTH, +) -#define MAP_Length(contents) mapLength(contents(ONE, +)) + contents(LENGTH, +) +#define ARRAY_Length(contents) msgPackArrayLength(contents(ONE, +)) + contents(LENGTH, +) +#define MAP_Length(contents) msgPackMapLength(contents(ONE, +)) + contents(LENGTH, +) #define LENGTH(type, ...) DEFER(type##_Length_id)()(__VA_ARGS__) -#define _INTEGER_WRITE(x, type, ...) buffer = integerWrite(buffer, x, type); +#define _INTEGER_WRITE(x, type, ...) buffer = msgPackIntegerWrite(buffer, x, type); #define INTEGER_Write(x, ...) _INTEGER_WRITE(x, ##__VA_ARGS__ , Unsigned) -#define STRING_Write(x) buffer = stringWrite(buffer, x); +#define STRING_Write(x) buffer = msgPackStringWrite(buffer, x); #define INTEGER_Write_id() INTEGER_Write #define ARRAY_Write_id() ARRAY_Write #define STRING_Write_id() STRING_Write #define MAP_Write_id() MAP_Write -#define ARRAY_Write(contents) buffer = arrayWrite(buffer, contents(ONE, +)); contents(WRITE, NOTHING) -#define MAP_Write(contents) buffer = mapWrite(buffer, contents(ONE, +)); contents(WRITE, NOTHING) +#define ARRAY_Write(contents) buffer = msgPackArrayWrite(buffer, contents(ONE, +)); contents(WRITE, NOTHING) +#define MAP_Write(contents) buffer = msgPackMapWrite(buffer, contents(ONE, +)); contents(WRITE, NOTHING) #define WRITE(type, ...) DEFER(type##_Write_id)()(__VA_ARGS__) #define CONTENTS contents (LENGTH, +) +extern uint32_t msgPackReadUint(void *data); +extern intmax_t msgPackReadInt(void *data); + #define CREATE(name, definition) \ uint32_t name##Length = EXPAND(definition(LENGTH)); \ void *name = malloc(name##Length); \ @@ -151,7 +154,7 @@ uint8_t *buffer = (uint8_t *) data; \ uint8_t type = FirstByteToFormat[*buffer]; \ if (formatInfo[type].dataType != TYPE_INTEGER) catchError \ - readInt(data); \ + msgPackReadInt(data); \ }) #define _AS_UINT(data, catchError, catchNegative) \ @@ -159,7 +162,7 @@ uint8_t *buffer = (uint8_t *) data; \ uint8_t type = FirstByteToFormat[*buffer]; \ if (formatInfo[type].dataType != TYPE_INTEGER) catchError \ - intmax_t asInt = readInt(data); \ + intmax_t asInt = msgPackReadInt(data); \ if (asInt < 0) catchNegative \ (uint32_t) asInt; \ }) @@ -169,7 +172,7 @@ uint8_t *buffer = (uint8_t *) data; \ uint8_t type = FirstByteToFormat[*buffer]; \ if (formatInfo[type].dataType != TYPE_STRING) catchError \ - readStr(data); \ + msgPackReadStr(data); \ }) #define AS_INT(data, retval, ...) \ @@ -190,10 +193,10 @@ return retval; \ } \ void *elementName; \ - uint32_t maxElement = readArraySize(data, &elementName); \ + uint32_t maxElement = msgPackReadArraySize(data, &elementName); \ for (uint32_t i = 0; i < maxElement; i++) { \ (action); \ - elementName = seek(elementName); \ + elementName = msgPackSeek(elementName); \ } \ } @@ -205,12 +208,24 @@ printf("GET_FROM_INT: cannot convert '" #data "' to a map, got %s\n", formatInfo[type].name); \ return retval; \ } \ - mapGetFromInt(data, value); \ + msgPackMapGetFromInt(data, value); \ }) +#define GET_FROM_STRING(data, value, retval) \ + ({ \ + uint8_t *buffer = (uint8_t *)data; \ + uint8_t type = FirstByteToFormat[*buffer]; \ + if (formatInfo[type].dataType != TYPE_MAP) { \ + printf("GET_FROM_STRING: cannot convert '" #data "' to a map, got %s\n", formatInfo[type].name); \ + return retval; \ + } \ + msgPackMapGetFromString(data, value); \ + }) -extern uint32_t readUint(void *data); -extern intmax_t readInt(void *data); +typedef char * STRING; +typedef intmax_t INT; +#define _GET(type, name, retval, ...) type name = AS_##type(GET_FROM_STRING(data, #name, retval), retval); +#define GET(type, name, ...) _GET(type, name, ##__VA_ARGS__, -1) #endif // BUFFERS_H \ No newline at end of file diff --git a/src/userland/buffersTests/main.c b/src/userland/buffersTests/main.c index 8969144..57e8153 100644 --- a/src/userland/buffersTests/main.c +++ b/src/userland/buffersTests/main.c @@ -12,7 +12,7 @@ Formats FirstByteToFormat[256]; -uintmax_t readLength(void *data, int8_t size) { +uintmax_t msgPackReadLength(void *data, int8_t size) { if (size < 0) { return (*(uint8_t *)(data)) & ((1 << (-size)) - 1); } @@ -29,11 +29,11 @@ return 0; } -void *dumpPack(uint8_t *data, uint32_t indent) { +void *msgPackDump(uint8_t *data, uint32_t indent) { FormatInfo *info = &formatInfo[FirstByteToFormat[data[0]]]; uint32_t bytesToRead = 1; uint32_t dataOffset = 0, dataSize = 0; - uintmax_t length = readLength(data, info->readTypeParameter); + uintmax_t length = msgPackReadLength(data, info->readTypeParameter); switch (info->readType) { case Inline: break; @@ -74,7 +74,7 @@ case TYPE_NIL: printf("%s%s: %s\n", indentData, hexData, info->name); break; case TYPE_INTEGER: - printf("%s%s: %s(%i)\n", indentData, hexData, info->name, readInt(data)); break; + printf("%s%s: %s(%i)\n", indentData, hexData, info->name, msgPackReadInt(data)); break; case TYPE_BOOLEAN: printf("%s%s: %s(%s)\n", indentData, hexData, info->name, length ? "true" : "false"); break; // can't even print a float yet... @@ -88,14 +88,14 @@ case TYPE_ARRAY: printf("%s%s: %s(%i)\n", indentData, hexData, info->name, length); for (uint32_t i = 0; i < length; i++) { - next = dumpPack(next, indent + 2); + next = msgPackDump(next, indent + 2); } break; case TYPE_MAP: printf("%s%s: %s(%i)\n", indentData, hexData, info->name, length); for (uint32_t i = 0; i < length; i++) { - next = dumpPack(next, indent + 1); - next = dumpPack(next, indent + 2); + next = msgPackDump(next, indent + 1); + next = msgPackDump(next, indent + 2); } break; default: @@ -119,7 +119,7 @@ FORMATS(FILL_SPOTS_X, NOTHING); } -uint32_t stringLength(uint32_t strlength) { +uint32_t msgPackStringLength(uint32_t strlength) { if ((strlength & 0x1F) == strlength) { // fixstr return 1 + strlength; @@ -136,7 +136,7 @@ return 5 + strlength; } -void *stringWrite(void *buffer, char *string) { +void *msgPackStringWrite(void *buffer, char *string) { uint32_t length = strlen(string); uint8_t *bufferByte = buffer; if ((length & 0x1F) == length) { @@ -159,7 +159,7 @@ return buffer + length; } -uint32_t integerLength(int32_t value, IntegerType integerType) { +uint32_t msgPackIntegerLength(int32_t value, IntegerType integerType) { if ((value & 0x7F) == value || ((~value) & 0x1F) == ~value) { // fixint return 1; @@ -181,7 +181,7 @@ return 9; } -void *integerWrite(void *buffer, int32_t x, IntegerType type) { +void *msgPackIntegerWrite(void *buffer, int32_t x, IntegerType type) { if (x < 0 && type != Signed) { printf("integerWrite: %i is negative but type is Unsigned!\n", x); return buffer; @@ -231,7 +231,7 @@ return buffer; } -uint32_t arrayLength(uint32_t elementCount) { +uint32_t msgPackArrayLength(uint32_t elementCount) { if ((elementCount & formatInfo[FORMAT_FIXARRAY].readTypeParameter) == elementCount) { return 1; } @@ -245,7 +245,7 @@ return 1; } -void *arrayWrite(void *buffer, uint32_t elementCount) { +void *msgPackArrayWrite(void *buffer, uint32_t elementCount) { uint8_t *bufferByte = buffer; if ((elementCount & 0xF) == elementCount) { *bufferByte = formatInfo[FORMAT_FIXARRAY].min + elementCount; @@ -265,15 +265,15 @@ return buffer; } -uint32_t mapLength(uint32_t elementCount) { +uint32_t msgPackMapLength(uint32_t elementCount) { if (elementCount % 2) { printf("map: bad element count %i\n", elementCount); return 0; } - return arrayLength(elementCount / 2); + return msgPackArrayLength(elementCount / 2); } -void *mapWrite(void *buffer, uint32_t elementCount) { +void *msgPackMapWrite(void *buffer, uint32_t elementCount) { uint8_t *bufferByte = buffer; if (elementCount % 2) { printf("map: bad element count %i\n", elementCount); @@ -296,7 +296,7 @@ } // for reading values from a buffer: malloc is very slow, so only use it sparingly, when reutrning a value. -intmax_t readInt(void *data) { +intmax_t msgPackReadInt(void *data) { uint8_t *buffer = (uint8_t *) data; uint8_t format = FirstByteToFormat[*buffer]; FormatInfo *info = &formatInfo[format]; @@ -338,8 +338,8 @@ return 0; } -uint32_t readUint(void *data) { - intmax_t asInt = readInt(data); +uint32_t msgPackReadUint(void *data) { + intmax_t asInt = msgPackReadInt(data); if (asInt < 0) { printf("readUint: value %i is negative\n", asInt); return 0; @@ -347,7 +347,7 @@ return asInt; } -char *readStr(void *data) { +char *msgPackReadStr(void *data) { uint8_t *buffer = (uint8_t *) data; uint8_t format = FirstByteToFormat[*buffer]; FormatInfo *info = &formatInfo[format]; @@ -365,14 +365,14 @@ } else if (format == FORMAT_STR32) { offset = 5; } - uint32_t size = readLength(data, offset); + uint32_t size = msgPackReadLength(data, info->readTypeParameter); char *str = malloc(size + 1); memcpy(data + offset, str, size); str[size] = 0; return str; } -uintmax_t readArraySize(void *data, void **firstElement) { +uintmax_t msgPackReadArraySize(void *data, void **firstElement) { uint8_t *buffer = (uint8_t *) data; uint8_t format = FirstByteToFormat[*buffer]; FormatInfo *info = &formatInfo[format]; @@ -388,10 +388,10 @@ case FORMAT_ARRAY32: *firstElement = data + 5; } - return readLength(data, info->readTypeParameter); + return msgPackReadLength(data, info->readTypeParameter); } -uintmax_t readMapSize(void *data, void **firstElement) { +uintmax_t msgPackReadMapSize(void *data, void **firstElement) { uint8_t *buffer = data; uint8_t format = FirstByteToFormat[*buffer]; FormatInfo *info = &formatInfo[format]; @@ -407,14 +407,14 @@ case FORMAT_MAP32: *firstElement = data + 5; break; } - return readLength(data, info->readTypeParameter); + return msgPackReadLength(data, info->readTypeParameter); } -void *seek(void *data) { +void *msgPackSeek(void *data) { uint8_t *buffer = (uint8_t *) data; uint8_t format = FirstByteToFormat[*buffer]; FormatInfo *info = &formatInfo[format]; - uint32_t length = readLength(data, info->readTypeParameter); + uint32_t length = msgPackReadLength(data, info->readTypeParameter); if (info->dataType == TYPE_MAP) { length <<= 1; } @@ -434,7 +434,7 @@ data += 1 + info->readTypeParameter; READ_ELEMENTS: for (uint8_t i = 0; i < length; i++) { - data = seek(data); + data = msgPackSeek(data); } return data; } @@ -443,7 +443,7 @@ return NULL; } -void *mapGetFromInt(void *data, uintmax_t searchValue) { +void *msgPackMapGetFromInt(void *data, uintmax_t searchValue) { uint8_t *buffer = data; uint8_t format = FirstByteToFormat[*buffer]; FormatInfo *info = &formatInfo[format]; @@ -452,23 +452,58 @@ return 0; } uint8_t *element; - uint32_t pairCount = readMapSize(data, (void *)&element); + uint32_t pairCount = msgPackReadMapSize(data, (void *)&element); for (uintmax_t i = 0; i < pairCount; i++) { if (formatInfo[FirstByteToFormat[*element]].dataType != TYPE_INTEGER) { - element = seek(element); - element = seek(element); + element = msgPackSeek(element); + element = msgPackSeek(element); } - if (readInt(element) == searchValue) { - return seek(element); + if (msgPackReadInt(element) == searchValue) { + return msgPackSeek(element); } - element = seek(element); - element = seek(element); + element = msgPackSeek(element); + element = msgPackSeek(element); } printf("mapGetFromInt: key %i not found!\n", searchValue); // TODO: return something sensible here / throw an actual exception return NULL; } +void *msgPackMapGetFromString(void *data, char *searchValue) { + uint8_t *buffer = data; + uint8_t format = FirstByteToFormat[*buffer]; + FormatInfo *info = &formatInfo[format]; + if (info->dataType != TYPE_MAP) { + printf("mapGetFromString cannot convert %s to a map\n", info->name); + return 0; + } + uint8_t *element; + uint32_t pairCount = msgPackReadMapSize(data, (void *)&element); + for (uintmax_t i = 0; i < pairCount; i++) { + if (formatInfo[FirstByteToFormat[*element]].dataType != TYPE_STRING) { + element = msgPackSeek(element); + element = msgPackSeek(element); + } + char *key = msgPackReadStr(element); + bool equal = true; + for (uint32_t i = 0; searchValue[i]; i++) { + if (key[i] != searchValue[i]) { + equal = false; + break; + } + } + free(key); + if (equal) { + return msgPackSeek(element); + } + element = msgPackSeek(element); + element = msgPackSeek(element); + } + printf("mapGetFromString: key '%s' not found!\n", searchValue); + // TODO: return something sensible here / throw an actual exception + return NULL; +} + #define SAMPLE_2_ARRAY_CONTENT(X, S) \ X(INTEGER, 1) S \ X(STRING, "hi") S \ @@ -483,11 +518,22 @@ X(STRING, "hello") S \ X(STRING, "world") S \ X(INTEGER, 2) S \ - X(STRING, "Number 2") + X(STRING, "Number 2") S \ + X(STRING, "number") S \ + X(INTEGER, 1) #define SAMPLE_3(X) \ X(MAP, SAMPLE_3_MAP_CONTENTS) +uint32_t testFunction(void *data) { + GET(STRING, hello); + GET(INT, number); + + printf("parameters: hello=%s, number=%i\n", hello, number); + free(hello); + return 0; +} + int32_t main() { static bool intitialized = false; if (!intitialized) { @@ -495,9 +541,9 @@ initialize(); } CREATE(test, SAMPLE_3); - printf("value from key int(2):\n"); - dumpPack(GET_FROM_INT(test, 2, -1), 0); - printf("\n\n"); - dumpPack(test, 0); + msgPackDump(test, 0); + + testFunction(test); + free(test); } \ No newline at end of file