bool ccnxCodecSchemaV1FixedHeaderDecoder_Decode(CCNxCodecTlvDecoder *decoder, CCNxTlvDictionary *packetDictionary) { if (ccnxCodecTlvDecoder_EnsureRemaining(decoder, _fixedHeaderBytes)) { PARCBuffer *buffer = ccnxCodecTlvDecoder_GetValue(decoder, _fixedHeaderBytes); bool success = ccnxTlvDictionary_PutBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader, buffer); // validation parcBuffer_SetPosition(buffer, _fixedHeader_VersionOffset); uint8_t version = parcBuffer_GetUint8(buffer); parcBuffer_SetPosition(buffer, _fixedHeader_PacketLengthOffset); uint16_t packetLength = parcBuffer_GetUint16(buffer); parcBuffer_SetPosition(buffer, _fixedHeader_HopLimitOffset); uint8_t hopLimit = parcBuffer_GetUint8(buffer); parcBuffer_SetPosition(buffer, _fixedHeader_HeaderLengthOffset); uint8_t headerLength = parcBuffer_GetUint8(buffer); if (version != 1) { CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_VERSION, __func__, __LINE__, _fixedHeader_VersionOffset); ccnxCodecTlvDecoder_SetError(decoder, error); ccnxCodecError_Release(&error); success = false; } else if (packetLength < _fixedHeaderBytes) { CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_PACKETLENGTH_TOO_SHORT, __func__, __LINE__, _fixedHeader_PacketTypeOffset); ccnxCodecTlvDecoder_SetError(decoder, error); ccnxCodecError_Release(&error); success = false; } else if (headerLength < _fixedHeaderBytes) { CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_HEADERLENGTH_TOO_SHORT, __func__, __LINE__, _fixedHeader_HeaderLengthOffset); ccnxCodecTlvDecoder_SetError(decoder, error); ccnxCodecError_Release(&error); success = false; } else if (packetLength < headerLength) { CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_PACKETLENGTHSHORTER, __func__, __LINE__, _fixedHeader_PacketTypeOffset); ccnxCodecTlvDecoder_SetError(decoder, error); ccnxCodecError_Release(&error); success = false; } // decoder now points to just past the fixed header parcBuffer_Release(&buffer); // Set the hoplimit in the dictionary. ccnxTlvDictionary_PutInteger(packetDictionary, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_HOPLIMIT, hopLimit); return success; } else { CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_DECODE, __func__, __LINE__, ccnxCodecTlvDecoder_Position(decoder)); ccnxCodecTlvDecoder_SetError(decoder, error); ccnxCodecError_Release(&error); return false; } }
uint16_t parcBuffer_GetUint16(PARCBuffer *buffer) { uint8_t high = parcBuffer_GetUint8(buffer); uint8_t low = parcBuffer_GetUint8(buffer); uint16_t result = (high << 8) | low; return result; }
PARCBuffer * parcJSONParser_ParseString(PARCJSONParser *parser) { PARCBuffer *result = NULL; PARCBuffer *buffer = _getBuffer(parser); if (parcBuffer_GetUint8(buffer) == '"') { // skip the initial '"' character starting the string. PARCBufferComposer *composer = parcBufferComposer_Create(); while (parcBuffer_Remaining(buffer)) { uint8_t c = parcBuffer_GetUint8(buffer); if (c == '"') { // This is the only successful way to exit this while loop. result = parcBufferComposer_ProduceBuffer(composer); break; } else if (c == '\\') { c = parcBuffer_GetUint8(buffer); if (c == '"') { // this special character passes directly into the composed string. } else if (c == '\\') { // this special character passes directly into the composed string. } else if (c == '/') { // this special character passes directly into the composed string. } else if (c == 'b') { c = '\b'; } else if (c == 'f') { c = '\f'; } else if (c == 'n') { c = '\n'; } else if (c == 'r') { c = '\r'; } else if (c == 't') { c = '\t'; } else if (c == 'u') { // Not supporting unicode at this point. trapNotImplemented("Unicode is not supported."); } } else if (iscntrl(c)) { // !! Syntax Error. break; } parcBufferComposer_PutChar(composer, c); } parcBufferComposer_Release(&composer); } return result; }
static PARCBufferComposer * _buildStringString(const PARCJSONValue *value, PARCBufferComposer *composer, bool compact) { parcBufferComposer_PutChar(composer, '"'); while (parcBuffer_Remaining(value->value.string)) { uint8_t c = parcBuffer_GetUint8(value->value.string); if (c == '"') { parcBufferComposer_PutString(composer, "\\\""); } else if (c == '\b') { parcBufferComposer_PutString(composer, "\\b"); } else if (c == '\f') { parcBufferComposer_PutString(composer, "\\f"); } else if (c == '\n') { parcBufferComposer_PutString(composer, "\\n"); } else if (c == '\r') { parcBufferComposer_PutString(composer, "\\r"); } else if (c == '\t') { parcBufferComposer_PutString(composer, "\\t"); } else if ((c == '/') && !compact) { parcBufferComposer_PutString(composer, "\\/"); } else if (c == '\\') { parcBufferComposer_PutString(composer, "\\\\"); } else { parcBufferComposer_PutChar(composer, c); } } parcBuffer_Rewind(value->value.string); parcBufferComposer_PutChar(composer, '"'); return composer; }
uint8_t ccnxInterestPayloadId_GetType(const CCNxInterestPayloadId *id) { PARCBuffer *data = ccnxNameSegment_GetValue(id->nameSegment); parcBuffer_Rewind(data); uint8_t type = parcBuffer_GetUint8(data); return type; }
uint64_t parcBuffer_GetUint64(PARCBuffer *buffer) { uint64_t result = 0; for (int i = 0; i < sizeof(uint64_t); i++) { result = result << 8 | parcBuffer_GetUint8(buffer); } return result; }
bool parcJSONParser_Next(PARCJSONParser *parser, char *value) { bool result = false; parcJSONParser_SkipIgnored(parser); if (parcJSONParser_Remaining(parser) > 0) { *value = (char) parcBuffer_GetUint8(parser->buffer); result = true; } return result; }
bool parcBuffer_SkipOver(PARCBuffer *buffer, size_t length, const uint8_t bytesToSkipOver[length]) { while (parcBuffer_Remaining(buffer) > 0) { uint8_t character = parcBuffer_GetUint8(buffer); if (memchr(bytesToSkipOver, character, length) == NULL) { parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) - 1); return true; } } return false; }
int ccnxCodecSchemaV1FixedHeaderDecoder_GetFlags(CCNxTlvDictionary *packetDictionary) { PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); if (fixedHeader != NULL) { parcBuffer_SetPosition(fixedHeader, _fixedHeader_FlagsOffset); uint8_t flags = parcBuffer_GetUint8(fixedHeader); return flags; } return -1; }
LONGBOW_TEST_CASE(JSON, parcJSON_ParseBuffer_WithExcess) { char *string = "{ \"string\" : \"string\", \"null\" : null, \"true\" : true, \"false\" : false, \"integer\" : 31415, \"float\" : 3.141500, \"array\" : [ null, false, true, 31415, \"string\", [ null, false, true, 31415, \"string\" ], { } ] }Xhowdy"; PARCBuffer *buffer = parcBuffer_WrapCString((char *) string); PARCJSON *json = parcJSON_ParseBuffer(buffer); char actual = parcBuffer_GetUint8(buffer); assertTrue(actual == 'X', "Expected buffer position to point to X, actual %x", actual); parcBuffer_Release(&buffer); parcJSON_Release(&json); }
bool parcJSONParser_RequireString(PARCJSONParser *parser, const char *string) { PARCBuffer *buffer = _getBuffer(parser); for (const char *requiredCharacter = string; *requiredCharacter != 0; requiredCharacter++) { uint8_t actualCharacter = parcBuffer_GetUint8(buffer); if (actualCharacter != *requiredCharacter) { return false; } } return true; }
bool parcBuffer_SkipTo(PARCBuffer *buffer, size_t length, const uint8_t bytesToSkipTo[length]) { bool result = false; while (parcBuffer_Remaining(buffer) > 0) { uint8_t character = parcBuffer_GetUint8(buffer); if (memchr(bytesToSkipTo, character, length) != NULL) { parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) - 1); result = true; break; } } return result; }
int ccnxCodecSchemaV1FixedHeaderDecoder_GetHeaderLength(CCNxTlvDictionary *packetDictionary) { int length = -1; PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); if (fixedHeader != NULL) { parcBuffer_SetPosition(fixedHeader, _fixedHeader_HeaderLengthOffset); uint8_t headerLength = parcBuffer_GetUint8(fixedHeader); // 8 is the minimum size of headerLength if (headerLength >= _fixedHeaderBytes) { length = headerLength; } } return length; }
bool ccnxCodecTlvUtilities_GetVarInt(PARCBuffer *input, size_t length, uint64_t *output) { assertNotNull(input, "Parameter input must be non-null"); assertNotNull(output, "Parameter output must be non-null"); bool success = false; if (length >= 1 && length <= 8 && parcBuffer_Remaining(input) >= length) { uint64_t value = 0; for (int i = 0; i < length; i++) { value = value << 8 | parcBuffer_GetUint8(input); } *output = value; success = true; } return success; }
char parcJSONParser_NextChar(PARCJSONParser *parser) { parcJSONParser_SkipIgnored(parser); return (char) parcBuffer_GetUint8(parser->buffer); }