From a1da7c7b4ab920a9f291dee632fe9fdb2c8a595b Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sun, 13 Aug 2023 03:11:40 +0000 Subject: [PATCH] Json now uses Int64 for integers. This should fix all timestamp errors on 32-bit systems in Cytoplasm and Telodendria. --- src/Json.c | 47 ++++++++++++++++++++++++++++++++++++++------- src/include/Int64.h | 22 ++++----------------- src/include/Json.h | 7 ++++--- tools/j2s.c | 7 ++++--- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/Json.c b/src/Json.c index 8441e93..83ad602 100644 --- a/src/Json.c +++ b/src/Json.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -43,7 +44,7 @@ struct JsonValue HashMap *object; Array *array; char *string; - long integer; + Int64 integer; double floating; int boolean:1; } as; @@ -200,7 +201,7 @@ JsonValueAsString(JsonValue * value) } JsonValue * -JsonValueInteger(long integer) +JsonValueInteger(Int64 integer) { JsonValue *value; @@ -216,12 +217,12 @@ JsonValueInteger(long integer) return value; } -long +Int64 JsonValueAsInteger(JsonValue * value) { if (!value || value->type != JSON_INTEGER) { - return 0; + return Int64Create(0, 0); } return value->as.integer; @@ -605,6 +606,8 @@ JsonEncodeValue(JsonValue * value, Stream * out, int level) Array *arr; int length = 0; + char ibuf[INT64_STRBUF]; + switch (value->type) { case JSON_OBJECT: @@ -641,7 +644,8 @@ JsonEncodeValue(JsonValue * value, Stream * out, int level) length += JsonEncodeString(value->as.string, out); break; case JSON_INTEGER: - length += StreamPrintf(out, "%ld", value->as.integer); + Int64Str(value->as.integer, 10, ibuf, INT64_STRBUF); + length += StreamPrintf(out, "%s", ibuf); break; case JSON_FLOAT: length += StreamPrintf(out, "%f", value->as.floating); @@ -979,7 +983,7 @@ JsonTokenSeek(JsonParserState * state) break; } - if (state->tokenLen >= allocated) + if (state->tokenLen + 1 >= allocated) { char *tmp; @@ -1119,6 +1123,10 @@ JsonDecodeValue(JsonParserState * state) JsonValue *value; char *strValue; + Int64 iValue; + size_t i; + int neg; + switch (state->tokenType) { case TOKEN_OBJECT_OPEN: @@ -1138,7 +1146,32 @@ JsonDecodeValue(JsonParserState * state) Free(strValue); break; case TOKEN_INTEGER: - value = JsonValueInteger(atol(state->token)); + iValue = Int64Create(0, 0); + i = 0; + neg = 0; + + while (state->token[i]) + { + int d; + + if (i == 0 && !neg && state->token[i] == '-') + { + neg = 1; + i++; + continue; + } + + d = state->token[i] - '0'; + iValue = Int64Mul(iValue, Int64Create(0, 10)); + iValue = Int64Add(iValue, Int64Create(0, d)); + i++; + } + + if (neg) + { + iValue = Int64Neg(iValue); + } + value = JsonValueInteger(iValue); break; case TOKEN_FLOAT: value = JsonValueFloat(atof(state->token)); diff --git a/src/include/Int64.h b/src/include/Int64.h index 8e917dd..08083c1 100644 --- a/src/include/Int64.h +++ b/src/include/Int64.h @@ -122,25 +122,11 @@ typedef signed long Int64; #define Int64Neg(x) (Int64Add(Int64Not(x), Int64Create(0, 1))) /** - * For platforms that do not have a native integer large enough to - * store a 64 bit integer, this struct is used. i[0] contains the low - * bits of integer, and i[1] contains the high bits of the integer. - * .Pp - * This struct should not be accessed directly, because UInt64 may not - * actually be this struct, it might be an actual integer type. For - * maximum portability, only use the functions defined here to - * manipulate 64 bit integers. + * The internal bit representation of a signed integer is identical + * to an unsigned integer, the difference is in the algorithms and + * the way the bits are interpreted. */ -typedef struct -{ - /* - * Unsigned, because we will deal with the sign bits ourselves. - * This also allows well-defined casting between signed and - * unsigned integers. - */ - UInt32 i[2]; -} Int64; - +typedef UInt64 Int64; /** * Create a new signed 64 bit integer using the given high and low diff --git a/src/include/Json.h b/src/include/Json.h index 03bcfae..4185260 100644 --- a/src/include/Json.h +++ b/src/include/Json.h @@ -71,6 +71,7 @@ #include #include #include +#include #include #include @@ -101,7 +102,7 @@ typedef enum JsonType JSON_OBJECT, /* Maps to a HashMap of JsonValues */ JSON_ARRAY, /* Maps to an Array of JsonValues */ JSON_STRING, /* Maps to a null-terminated C string */ - JSON_INTEGER, /* Maps to a C long */ + JSON_INTEGER, /* Maps to an Int64 */ JSON_FLOAT, /* Maps to a C double */ JSON_BOOLEAN /* Maps to a C integer of either 0 or 1 */ } JsonType; @@ -151,7 +152,7 @@ extern char * JsonValueAsString(JsonValue *); * Encode a number as a JSON value that can be added to an object or * an array. */ -extern JsonValue * JsonValueInteger(long); +extern JsonValue * JsonValueInteger(Int64); /** * Unwrap a JSON value that represents a number. This function will @@ -159,7 +160,7 @@ extern JsonValue * JsonValueInteger(long); * misleading. Check the type of the value before making assumptions * about its value. */ -extern long JsonValueAsInteger(JsonValue *); +extern Int64 JsonValueAsInteger(JsonValue *); /** * Encode a floating point number as a JSON value that can be added diff --git a/tools/j2s.c b/tools/j2s.c index c05bf2f..fe3bde8 100644 --- a/tools/j2s.c +++ b/tools/j2s.c @@ -443,6 +443,7 @@ Main(Array * args) StreamPrintf(headerFile, "#include \n"); StreamPrintf(headerFile, "#include \n"); + StreamPrintf(headerFile, "#include \n"); StreamPutc(headerFile, '\n'); @@ -491,7 +492,7 @@ Main(Array * args) } else if (StrEquals(fieldType, "integer")) { - cType = "long"; + cType = "Int64"; } else if (StrEquals(fieldType, "boolean")) { @@ -664,7 +665,7 @@ Main(Array * args) if (StrEquals(fieldType, "integer")) { - cType = "long"; + cType = "Int64"; } else if (StrEquals(fieldType, "float")) { @@ -907,7 +908,7 @@ Main(Array * args) if (StrEquals(fieldType, "integer")) { - cType = "long"; + cType = "Int64"; } else if (StrEquals(fieldType, "float")) {