/** * Create and return a CCNxInterest whose Name contains our commend (e.g. "fetch" or "list"), * and, optionally, the name of a target object (e.g. "file.txt"). The newly created CCNxInterest * must eventually be released by calling ccnxInterest_Release(). * * @param command The command to embed in the created CCNxInterest. * @param targetName The name of the content, if any, that the command applies to. * * @return A newly created CCNxInterest for the specified command and targetName. */ static CCNxInterest * _createInterest(const char *command, const char *targetName) { CCNxName *interestName = ccnxName_CreateFromURI(tutorialCommon_DomainPrefix); // Start with the prefix. We append to this. // Create a NameSegment for our command, which we will append after the prefix we just created. PARCBuffer *commandBuffer = parcBuffer_WrapCString((char *) command); CCNxNameSegment *commandSegment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, commandBuffer); parcBuffer_Release(&commandBuffer); // Append the new command segment to the prefix ccnxName_Append(interestName, commandSegment); ccnxNameSegment_Release(&commandSegment); // If we have a target, then create another NameSegment for it and append that. if (targetName != NULL) { // Create a NameSegment for our target object PARCBuffer *targetBuf = parcBuffer_WrapCString((char *) targetName); CCNxNameSegment *targetSegment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, targetBuf); parcBuffer_Release(&targetBuf); // Append it to the ccnxName. ccnxName_Append(interestName, targetSegment); ccnxNameSegment_Release(&targetSegment); } CCNxInterest *result = ccnxInterest_CreateSimple(interestName); ccnxName_Release(&interestName); return result; }
LONGBOW_TEST_CASE(Global, ccnxTlvCodecName_Encode) { uint8_t truthBytes[] = { 0x10, 0x20, 0x00, 0x0E, 0x00, CCNxNameLabelType_NAME, 0x00, 0x0A, 'b', 'r', 'a', 'n', 'd', 'y', 'w', 'i', 'n', 'e' }; PARCBuffer *truth = parcBuffer_Wrap(truthBytes, sizeof(truthBytes), 0, sizeof(truthBytes)); CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); ccnxCodecTlvEncoder_Initialize(encoder); PARCBuffer *buffer = parcBuffer_WrapCString("brandywine"); CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buffer); CCNxName *name = ccnxName_Append(ccnxName_Create(), segment); ccnxNameSegment_Release(&segment); parcBuffer_Release(&buffer); ccnxCodecSchemaV1NameCodec_Encode(encoder, 0x1020, name); ccnxCodecTlvEncoder_Finalize(encoder); PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); if (!parcBuffer_Equals(truth, test)) { printf("Buffers do not match\n"); printf("Excpected:\n"); parcBuffer_Display(truth, 3); printf("Got:\n"); parcBuffer_Display(test, 3); assertTrue(parcBuffer_Equals(truth, test), "Buffers do not match"); } ccnxName_Release(&name); parcBuffer_Release(&test); ccnxCodecTlvEncoder_Destroy(&encoder); parcBuffer_Release(&truth); }
CCNxInterestPayloadId * ccnxInterestPayloadId_CreateAsSHA256Hash(const PARCBuffer *data) { CCNxInterestPayloadId *result = parcObject_CreateInstance(CCNxInterestPayloadId); PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); parcCryptoHasher_Init(hasher); parcCryptoHasher_UpdateBuffer(hasher, data); PARCCryptoHash *hash = parcCryptoHasher_Finalize(hasher); parcCryptoHasher_Release(&hasher); PARCBuffer *hashData = parcCryptoHash_GetDigest(hash); PARCBuffer *codedHash = parcBuffer_Allocate(parcBuffer_Capacity(hashData) + 1); parcBuffer_PutUint8(codedHash, CCNxInterestPayloadId_TypeCode_RFC6920_SHA256); parcBuffer_PutBuffer(codedHash, hashData); parcBuffer_Flip(codedHash); result->nameSegment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_PAYLOADID, codedHash); parcBuffer_Release(&codedHash); parcCryptoHash_Release(&hash); return result; }
CCNxNameSegment * ccnxNameSegment_CreateTypeValueArray(CCNxNameLabelType type, size_t length, const char array[length]) { PARCBuffer *value = parcBuffer_PutArray(parcBuffer_Allocate(length), length, (const uint8_t *) array); parcBuffer_Flip(value); CCNxNameSegment *result = ccnxNameSegment_CreateTypeValue(type, value); parcBuffer_Release(&value); return result; }
CCNxInterestPayloadId * ccnxInterestPayloadId_Create(const PARCBuffer *data, uint8_t type) { CCNxInterestPayloadId *result = parcObject_CreateInstance(CCNxInterestPayloadId); parcBuffer_AssertValid(data); PARCBuffer *buffer = parcBuffer_Allocate(parcBuffer_Capacity(data) + 1); assertTrue(type > CCNxInterestPayloadId_TypeCode_App, "App type must be greater than 0x80"); parcBuffer_PutUint8(buffer, type); parcBuffer_PutBuffer(buffer, data); parcBuffer_Flip(buffer); result->nameSegment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_PAYLOADID, buffer); parcBuffer_Release(&buffer); return result; }
LONGBOW_TEST_CASE(Global, ccnxTlvCodecName_Decode_RightType) { PARCBuffer *buffer = parcBuffer_WrapCString("brandywine"); CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buffer); CCNxName *truth = ccnxName_Append(ccnxName_Create(), segment); ccnxNameSegment_Release(&segment); parcBuffer_Release(&buffer); uint8_t decodeBytes[] = { 0x10, 0x20, 0x00, 0x0E, 0x00, CCNxNameLabelType_NAME, 0x00, 0x0A, 'b', 'r', 'a', 'n', 'd', 'y', 'w', 'i', 'n', 'e' }; PARCBuffer *decodeBuffer = parcBuffer_Wrap(decodeBytes, sizeof(decodeBytes), 0, sizeof(decodeBytes)); CCNxCodecTlvDecoder *decoder = ccnxCodecTlvDecoder_Create(decodeBuffer); CCNxName *test = ccnxCodecSchemaV1NameCodec_Decode(decoder, 0x1020); assertTrue(ccnxName_Equals(truth, test), "Name segments do not match"); ccnxName_Release(&test); ccnxCodecTlvDecoder_Destroy(&decoder); parcBuffer_Release(&decodeBuffer); ccnxName_Release(&truth); }