/* * Copyright (c) 2017 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file ccnx_NameSegment.h * @ingroup Naming * @brief A path segment of a CCNx Name * * An RFC3986 compliant implementation of URI segments, where each path segment carries a label. * See {@link CCNxName} for more information. * */ #ifndef libccnx_ccnx_NameSegment_h #define libccnx_ccnx_NameSegment_h #include #include #include #include #include #include struct ccnx_name_Segment; /** * @typedef CCNxNameSegment * @brief A path segment of a `CCNxName` */ typedef struct ccnx_name_segment CCNxNameSegment; /** * Create a CCNxNameSegment instance initialised with the given type and value. * * @param [in] type A valid CCNxNameLabelType * @param [in] value A valid PARCBuffer containing the value of the name segment. * * @return non-NULL A pointer to a valid CCNxNameSegment instance. * @return NULL An error occurred. * * Example: * @code * { * PARCBuffer *value = parcBuffer_WrapCString("value"); * * CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, value); * * parcBuffer_Release(&value); * } * @endcode */ CCNxNameSegment *ccnxNameSegment_CreateTypeValue(CCNxNameLabelType type, const PARCBuffer *value); /** * Create a CCNxNameSegment instance initialised with the given type and value taken from the given array of bytes. * * @param [in] type A valid CCNxNameLabelType * @param [in] length The number of bytes in @p array. * @param [in] array A pointer to a buffer containing the bytes for the value of the name segment. * * @return non-NULL A pointer to a valid CCNxNameSegment instance. * @return NULL An error occurred. * * Example: * @code * { * CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValueArray(CCNxNameLabelType_NAME, 5, "value"); * } * @endcode */ CCNxNameSegment *ccnxNameSegment_CreateTypeValueArray(CCNxNameLabelType type, size_t length, const char *array); /** * Parse a `CCNxNameSegment` from a {@link PARCURISegment} consisting of type specification and value. * * The name must be in conformance with `draft-mosko-icnrg-ccnxlabeledcontent-00` * * Names that use mnemonic values for labels, must conform to thier respective specifications. * See `draft-scott-icnrg-ccnxnameregistry-00` for a list of assigned names and type values. * * @param [in] uriSegment A pointer to a valid `PARCURISegment` * @return non-NULL A pointer to an allocated `CCNxNameSegment` which must eventually be released by calling * {@link ccnxNameSegment_Release}(). * @return NULL An error occurred. * @see `ccnxNameSegment_Release()` * * Example: * @code * { * char *lciSegment = CCNxNameLabel_Name "=" "abcde"; * PARC_URISegment *uriSegment = parcURISegment_Parse(lciSegment, NULL); * * CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(uriSegment); * * CCNxNameLabelType type = ccnxNameSegment_GetType(actual); * assertTrue(CCNxNameLabelType_NAME == type, "Expected %04x, actual %04x", 0x20, type); * * ccnxNameSegment_Release(&actual); * parcURISegment_Release(&uriSegment); * } * @endcode */ CCNxNameSegment *ccnxNameSegment_ParseURISegment(const PARCURISegment *uriSegment); /** * Create a new `CCNxNameSegment` by copying the given `CCNxNameSegment`. This is a deep copy, * and the created instance must eventually be released by calling {@link ccnxNameSegment_Release}(). * * @param [in] segment A `CCNxNameSegment` pointer. * @return An allocated `CCNxNameSegment` which must eventually be released by calling {@link ccnxNameSegment_Release}(). * * Example: * @code * { * PARCBuffer *value = parcBuffer_WrapCString("hello"); * CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, value); * * CCNxNameSegment *copy = ccnxNameSegment_Copy(segment); * * ccnxNameSegment_Release(&segment); * ccnxNameSegment_Copy(©); * parcBuffer_Release(&value); * } * @endcode */ CCNxNameSegment *ccnxNameSegment_Copy(const CCNxNameSegment *segment); /** * Determine if two `CCNxNameSegment` instances are equal. * * The following equivalence relations on non-null `CCNxNameSegment` instances are maintained: * * * It is reflexive: for any non-null reference value x, `ccnxNameSegment_Equal(x, x)` must return true. * * * It is symmetric: for any non-null reference values x and y, `ccnxNameSegment_Equal(x, y)` must return true if and only if * `ccnxNameSegment_Equal(y x)` returns true. * * * It is transitive: for any non-null reference values x, y, and z, if * `ccnxNameSegment_Equal(x, y)` returns true and * `ccnxNameSegment_Equal(y, z)` returns true, * then `ccnxNameSegment_Equal(x, z)` must return true. * * * It is consistent: for any non-null reference values x and y, multiple invocations of `ccnxNameSegment_Equal(x, y)` * consistently return true or consistently return false. * * * For any non-null reference value x, `ccnxNameSegment_Equal(x, NULL)` must return false. * * @param [in] segmentA A pointer to a `CCNxNameSegment` instance. * @param [in] segmentB A pointer to a `CCNxNameSegment` instance to be compared to `segmentA`. * * @return `true` if the given `CCNxNameSegment` instances are equal. * * Example: * @code * { * char *lciSegment = CCNxNameLabelType_Label_Chunk "=" "123"; * PARC_URISegment *uriSegment = parcURISegment_Parse(lciSegment, NULL); * CCNxNameSegment *segmentA = ccnxNameSegment_ParseURISegment(uriSegment); * * PARCBuffer *buf = parcBuffer_WrapCString("123"); * CCNxNameSegment *segmentB = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_CHUNK, buf); * * if (ccnxNameSegment_Equals(expected, actual)) { * // true * } else { * // false * } * ccnxNameSegment_Release(&segmentA); * ccnxNameSegment_Release(&segmentB); * parcURISegment_Release(&uriSegment); * parcBuffer_Release(&buf); * } * @endcode */ bool ccnxNameSegment_Equals(const CCNxNameSegment *segmentA, const CCNxNameSegment *segmentB); /** * A signum function comparing two `CCNxNameSegment` instances. * * Used to determine the ordering relationship of two `CCNxNameSegment` instances. * * @param [in] segmentA A pointer to a `CCNxNameSegment` instance. * @param [in] segmentB A pointer to a `CCNxNameSegment` instance to be compared to `segmentA`. * * @return 0 if `segmentA` and `segmentB` are equivalent * @return < 0 if `segmentA` < `segmentB` * @return > 0 if `segmentA` > `segmentB` * * Example: * @code * { * PARCBuffer *valueA = parcBuffer_WrapCString("apple"); * CCNxNameSegment *segmentA = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, valueA); * * PARCBuffer *valueB = parcBuffer_WrapCString("banana"); * CCNxNameSegment *segmentB = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, valueB); * * int signum = ccnxNameSegment_Compare(segmentA, segmentB); * * ccnxNameSegment_Release(&segmentA); * parcBuffer_Release(&bufA); * ccnxNameSegment_Release(&segmentB); * parcBuffer_Release(&bufB); * } * @endcode */ int ccnxNameSegment_Compare(const CCNxNameSegment *segmentA, const CCNxNameSegment *segmentB); /** * Get a pointer to the underlying PARCBuffer storing the value of the given `CCNxNameSegment`. * * A new reference to the instance is not created. * If the caller requires a reference to live beyond the lifetime of the `CCNxNameSegment` * it must acquire a reference via {@link parcBuffer_Acquire}. * * Any modifications to the buffer's position, limit or mark will affect subsequent use of the buffer. * * @param [in] segment A pointer to a `CCNxNameSegment` instance. * @return A pointer to the underlying @link PARCBuffer. * * Example: * @code * { * PARC_URISegment *uriSegment = parcURISegment_Parse("label:param=value"); * * CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(uriSegment); * * PARCBuffer *value = ccnxNameSegment_GetValue(actual); * * ccnxNameSegment_Release(&actual); * parcURISegment_Release(&uriSegment); * } * @endcode * * @see {@link ccnxNameSegment_Length}() */ PARCBuffer *ccnxNameSegment_GetValue(const CCNxNameSegment *segment); /** * Get a pointer to the underlying PARCBuffer storing the parameter of the given `CCNxNameSegment`. * * A new reference to the instance is not created. * If the caller requires a reference to live beyond the lifetime of the `CCNxNameSegment` * it must acquire a reference via {@link parcBuffer_Acquire}. * * Any modifications to the buffer's position, limit or mark will affect subsequent use of the buffer. * * @param [in] segment A pointer to a `CCNxNameSegment` instance. * @return NULL The given `CCNxNameSegment` does not specify a parameter value. * @return non-NULL A pointer to the underlying `PARCBuffer`. * * Example: * @code * { * CCNxNameSegment *segment = ccnxNameSegment_ParseURISegment("label:param=value"); * * PARCBuffer *parameter = ccnxNameSegment_GetParameter(segment); * * ccnxNameSegment_Release(&segment); * } * @endcode * * @see {@link ccnxNameSegment_Length}() */ PARCBuffer *ccnxNameSegment_GetParameter(const CCNxNameSegment *segment); /** * Produce a nul-terminated C string representation of the given `CCNxNameSegment`. * * A string representation, such as "1=foo". * * @param [in] segment A CCNxNameSegment pointer. * @return An allocated null-terminated byte array that must be deallocated by `{@link parcMemory_Deallocate}()`. * * Example: * @code * { * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/csl/sensors/radiation/212"); * CCNxNameSegment *segment = ccnxName_GetSegment(name, 3); * * char *string = ccnxNameSegment_ToString(segment); * printf("Hello: %s\n", string); * * parcMemory_Deallocate(string); * ccnxName_Release(&name); * } * @endcode * * @see `parcMemory_Deallocate` */ char *ccnxNameSegment_ToString(const CCNxNameSegment *segment); /** * Print a human readable representation of the given `CCNxNameSegment`. * * @param [in] segment A pointer to the instance to display. * @param [in] indentation The level of indentation to use to pretty-print the output. * * Example: * @code * { * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/csl/sensors/radiation/212"); * CCNxNameSegment *segment = ccnxName_GetSegment(name, 3); * * ccnxNameSegment_Display(segment, 0); * * ccnxName_Release(&name); * } * @endcode * */ void ccnxNameSegment_Display(const CCNxNameSegment *segment, int indentation); /** * Append a printable-character representation of the specified instance to the given {@link PARCBufferComposer}. * * @param [in] segment A pointer to the `CCNxNameSegment` instance. * @param [in,out] composer A pointer to the `PARCBufferComposer` instance onto which to append our printable representation. * * @return NULL Cannot allocate memory. * @return non-NULL The @p composer. * * Example: * @code * { * PARCBufferComposer *result = parcBufferComposer_Create(); * * ccnxNameSegment_BuildString(instance, result); * * char *string = parcBuffer_ToString(parcBufferComposer_ProduceBuffer(result)); * printf("Hello: %s\n", string); * parcMemory_Deallocate(string); * * parcBufferComposer_Release(&result); * } * @endcode * * @see PARCBufferComposer */ PARCBufferComposer *ccnxNameSegment_BuildString(const CCNxNameSegment *segment, PARCBufferComposer *composer); /** * Return the length of the specified `CCNxNameSegment`, in bytes. * * @param [in] segment A pointer to a `CCNxNameSegment` instance. * @return The number of bytes for the value of the given `CCNxNameSegment`. * * Example: * @code * { * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/csl/sensors/humidity/12"); * CCNxNameSegment *segment = ccnxName_GetSegment(name, 3); * * int length = ccnxNameSegment_Length(segment); * * ccnxName_Release(&name); * } * @endcode */ size_t ccnxNameSegment_Length(const CCNxNameSegment *segment); /** * Get the label of the given `CCNxNameSegment`. * * @param [in] segment A pointer to a `CCNxNameSegment` instance. * @return non-NULL A pointer to a PARCBuffer instance containing the label. * @return NULL The CCNxNameSegment instance does not have a label. * * Example: * @code * { * PARCBuffer *buf = parcBuffer_WrapCString("apple"); * CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf); * * CCNxNameLabelType type = ccnxNameSegment_GetType(segment); * * ccnxNameSegment_Release(&segment); * parcBuffer_Release(&buf); * } * @endcode * * @see `CCNxNameLabelType` */ PARCBuffer *ccnxNameSegment_GetLabel(const CCNxNameSegment *segment); /** * Get the {@link CCNxNameLabelType} of the given `CCNxNameSegment`. * * @param [in] segment A pointer to a `CCNxNameSegment` instance. * @return The `CCNxNameLabelType` of the specified `CCNxNameSegment` instance. * * Example: * @code * { * PARCBuffer *buf = parcBuffer_WrapCString("apple"); * CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf); * * CCNxNameLabelType type = ccnxNameSegment_GetType(segment); * * ccnxNameSegment_Release(&segment); * parcBuffer_Release(&buf); * } * @endcode * * @see `CCNxNameLabelType` */ CCNxNameLabelType ccnxNameSegment_GetType(const CCNxNameSegment *segment); /** * Return a hashcode for the given `CCNxNameSegment`. * * Whenever `HashCode()` is invoked on the same instance more than once within the same execution environment, * the HashCode function must consistently return the same value, provided no information used in its corresponding * `Equals()` comparisons on the same instance is modified. * * This value need not remain consistent from one execution of an application to another execution of the same application. * * If two instances are equal according to the `Equals()` function, * then calling the `HashCode` function on each of the two objects must produce the same integer result. * * It is not required that if two instances are unequal according to the `Equals()` function, * then calling the HashCode() method on each of the two instances must produce distinct integer results. * However, the programmer should be aware that producing distinct results for unequal instances * may improve the performance of some data structures. * * @param segment A pointer to a `CCNxNameSegment` instance. * @return An unsigned 32-bit integer hash code value. * * Example: * @code * { * PARCBuffer *bufA =parcBuffer_WrapCString("Test"); * * CCNxNameSegment *segmentA = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufA); * * uint32_t hashCode = ccnxNameSegment_HashCode(segmentA); * * ccnxNameSegment_Release(&segmentA); * parcBuffer_Release(&bufA); * } * @endcode * * @see `parcHash32Bits_Hash` */ PARCHashCode ccnxNameSegment_HashCode(const CCNxNameSegment *segment); /** * Increase the number of references to a `CCNxNameSegment`. * * Note that a new `CCNxNameSegment` is not created, * only that the given `CCNxNameSegment` reference count is incremented. * Discard the reference by invoking {@link ccnxNameSegment_Release}(). * * @param [in] segment A pointer to the original instance. * @return The value of the input parameter @p instance. * * Example: * @code * { * ... * * CCNxNameSegment *segment = ccnxNameSegment_Acquire(instance); * * ccnxNameSegment_Release(&segment); * * } * @endcode * * @see ccnxNameSegment_Release */ CCNxNameSegment *ccnxNameSegment_Acquire(const CCNxNameSegment *segment); /** * Release a previously acquired reference to the specified instance, * decrementing the reference count for the instance. * * The pointer to the instance is set to NULL as a side-effect of this function. * * If the invocation causes the last reference to the instance to be released, * the instance is deallocated and the instance's implementation will perform * additional cleanup and release other privately held references. * * @param [in,out] segmentP A pointer to a pointer to the instance to release. * * * Example: * @code * { * ... * * CCNxNameSegment *segment = ccnxNameSegment_Acquire(instance); * * ccnxNameSegment_Release(&segment); * * } * @endcode * * @see ccnxNameSegment_Acquire */ void ccnxNameSegment_Release(CCNxNameSegment **segmentP); #ifdef Libccnx_DISABLE_VALIDATION # define ccnxNameSegment_OptionalAssertValid(_instance_) #else # define ccnxNameSegment_OptionalAssertValid(_instance_) ccnxNameSegment_AssertValid(_instance_) #endif /** * Assert that an instance of `CCNxNameSegment` is valid. * * If the instance is not valid, terminate via {@link trapIllegalValue} * * Valid means the internal state of the type is consistent with its * required current or future behaviour. * This may include the validation of internal instances of types. * * @param [in] segment A pointer to the instance to check. * * Example: * @code * { * ... * * ccnxNameSegment_AssertValid(segment); * * } * @endcode */ void ccnxNameSegment_AssertValid(const CCNxNameSegment *segment); /** * Determine if an instance of `CCNxNameSegment` is valid. * * Valid means the internal state of the type is consistent with its * required current or future behaviour. * This may include the validation of internal instances of referenced objects. * * @param [in] segment A pointer to the instance to check. * * @return true The instance is valid. * @return false The instance is not valid. * * Example: * @code * { * ... * * ccnxNameSegment_IsValid(segment); * * } * @endcode */ bool ccnxNameSegment_IsValid(const CCNxNameSegment *segment); #endif // libccnx_ccnx_NameSegment_h