static inline int parseString(const struct Reader* reader,
                              const struct Allocator* allocator,
                              String** output)
{
    #define BUFF_SZ (1<<8)
    #define BUFF_MAX (1<<20)

    int curSize = BUFF_SZ;
    struct Allocator* localAllocator = Allocator_child(allocator);
    uint8_t* buffer = localAllocator->malloc(curSize, localAllocator);
    if (readUntil('"', reader) || reader->read(buffer, 1, reader)) {
        printf("Unterminated string\n");
        localAllocator->free(localAllocator);
        return OUT_OF_CONTENT_TO_READ;
    }
    for (int i = 0; i < BUFF_MAX - 1; i++) {
        if (buffer[i] == '\\') {
            // \x01 (skip the x)
            reader->skip(1, reader);
            uint8_t hex[2];
            if (reader->read((char*)hex, 2, reader)) {
                printf("Unexpected end of input parsing escape sequence\n");
                localAllocator->free(localAllocator);
                return OUT_OF_CONTENT_TO_READ;
            }
            int byte = Hex_decodeByte(hex[0], hex[1]);
            if (byte == -1) {
                printf("Invalid escape \"%c%c\" after \"%.*s\"\n",hex[0],hex[1],i+1,buffer);
                localAllocator->free(localAllocator);
                return UNPARSABLE;
            }
            buffer[i] = (uint8_t) byte;
        } else if (buffer[i] == '"') {
            *output = String_newBinary((char*)buffer, i, allocator);
            localAllocator->free(localAllocator);
            return 0;
        }
        if (i == curSize - 1) {
            curSize <<= 1;
            buffer = localAllocator->realloc(buffer, curSize, localAllocator);
        }
        if (reader->read(buffer + i + 1, 1, reader)) {
            if (i+1 <= 20) {
                printf("Unterminated string \"%.*s\"\n", i+1, buffer);
            } else {
                printf("Unterminated string starting with \"%.*s...\"\n", 20, buffer);
            }
            localAllocator->free(localAllocator);
            return OUT_OF_CONTENT_TO_READ;
        }
    }

    printf("Maximum string length of %d bytes exceeded.\n",BUFF_SZ);
    localAllocator->free(localAllocator);
    return UNPARSABLE;

    #undef BUFF_SZ
    #undef BUFF_MAX
}
Beispiel #2
0
int Hex_decode(uint8_t* output,
               const uint32_t outLength,
               const uint8_t* hex,
               const uint32_t length)
{
    if (length % 1) {
        return Hex_BAD_INPUT;
    } else if (outLength < (length / 2)) {
        return Hex_TOO_BIG;
    } else if (outLength > (length / 2)) {
        output[length / 2] = '\0';
    }

    for (uint32_t i = 0; i < length; i += 2) {
        int byte = Hex_decodeByte(hex[i], hex[i + 1]);
        if (byte == -1) {
            return Hex_BAD_INPUT;
        }
        output[i / 2] = (uint8_t) byte;
    }

    return length / 2;
}