aboutsummaryrefslogtreecommitdiffstats
path: root/libccnx-common/ccnx/common/ccnx_Name.h
diff options
context:
space:
mode:
Diffstat (limited to 'libccnx-common/ccnx/common/ccnx_Name.h')
-rwxr-xr-xlibccnx-common/ccnx/common/ccnx_Name.h738
1 files changed, 738 insertions, 0 deletions
diff --git a/libccnx-common/ccnx/common/ccnx_Name.h b/libccnx-common/ccnx/common/ccnx_Name.h
new file mode 100755
index 00000000..83cb78ff
--- /dev/null
+++ b/libccnx-common/ccnx/common/ccnx_Name.h
@@ -0,0 +1,738 @@
+/*
+ * 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_Name.h
+ * @ingroup Naming
+ * @brief The basic CCNx Name.
+ *
+ * This implements an RFC3986 URI compliant identifier in which each path segment carries a label.
+ * This allows differentiation between resources with otherwise similar identifiers that are not related.
+ * For example, one resource could be named `"/parc/csl/7"` meaning the 7th version of `"/parc/csl"`,
+ * while another could mean the 7th page of the resource.
+ * With labeled segments, the two resources would have unambiguous names,
+ * such as `"/parc/csl/version=7"` and `"/parc/csl/page=7"`.
+ *
+ */
+#ifndef libccnx_ccnx_Name_h
+#define libccnx_ccnx_Name_h
+
+#include <parc/algol/parc_HashCode.h>
+#include <ccnx/common/ccnx_NameSegment.h>
+
+struct ccnx_name;
+/**
+ * @typedef CCNxName
+ * @brief An RFC3986 URI compliant identifier in which each path segment carries a label.
+ */
+typedef struct ccnx_name CCNxName;
+
+/**
+ * Create a new instance of `CCNxName`, initialized from the given string representation of an LCI URI,
+ * using dynamically allocated memory.
+ *
+ * The URI must be a well-formed URI.
+ *
+ * The `CCNxName` instance must be released by calling {@link ccnxName_Release}.
+ *
+ * @param [in] uri A null-terminated string representation of the CCNx Name.
+ * @return non-NULL A pointer to a `CCNxName` instance initialised from the given URI.
+ * @return NULL An error occured parsing the URI, or the URI contained an invalid specification.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/csl/media/h2162");
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_CreateFromCString(const char *uri);
+
+/**
+ * Create a new instance of `CCNxName`, initialized from the given `PARCURI` representation of an LCI URI,
+ * using dynamically allocated memory.
+ *
+ * The URI must be a well-formed LCI URI.
+ *
+ * The `CCNxName` instance must be released by calling {@link ccnxName_Release}.
+ *
+ * @param [in] uri A valid instance of PARCURI.
+ * @return non-NULL A pointer to a `CCNxName` instance initialised from the given URI.
+ * @return NULL An error occured parsing the URI, or the URI contained an invalid specification.
+ *
+ * Example:
+ * @code
+ * {
+ * PARCURI *uri = parcURI_Parse("lci:/parc/csl/media/h2162");
+ * CCNxName *name = ccnxName_CreateFromCString(uri);
+ *
+ * parcURI_Release(&uri);
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_FromURI(const PARCURI *uri);
+
+/**
+ * Create a new instance of `CCNxName` from the given format string and variable number of parameters.
+ *
+ * @param [in] format A pointer to a nul-terminated printf format string
+ * @param [in] ... A variable number of parameters.
+ *
+ * @return non-NULL A pointer to a valid CCNxName instance.
+ * @return NULL An error occurred.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFormatString("lci://%s/object", "parc.com");
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_CreateFormatString(const char *restrict format, ...);
+
+/**
+ * Create a new instance of `CCNxName`, initialized from a string representation of a LCI URI contained in the given PARCBuffer,
+ * starting at the current position and terminating with a zero-byte in the buffer.
+ * using dynamically allocated memory.
+ *
+ * The URI must be a well-formed URI.
+ *
+ * The `CCNxName` instance must be released by calling {@link ccnxName_Release}.
+ *
+ * @param [in] uri A null-terminated string representation of the CCNx Name.
+ * @return non-NULL A pointer to a `CCNxName` instance initialised from the given URI.
+ * @return NULL An error occured parsing the URI, or the URI contained an invalid specification.
+ *
+ * Example:
+ * @code
+ * {
+ * PARCBuffer *buffer = parcBuffer_AllocateCString("lci:/parc/csl/media/h2162");
+ * CCNxName *name = ccnxName_CreateFromBuffer(buffer);
+ *
+ * ccnxName_Release(&name);
+ * parcBuffer_Release(&buffer);
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_CreateFromBuffer(const PARCBuffer *buffer);
+
+/**
+ * Increase the number of references to a `CCNxName` instance.
+ *
+ * Note that new `CCNxName` is not created,
+ * only that the given `CCNxName` reference count is incremented.
+ * Discard the reference by invoking {@link ccnxName_Release}.
+ *
+ * @param [in] name A pointer to the original `CCNxName`.
+ * @return The value of the input parameter @p name.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *original = ccnxName_Create();
+ *
+ * CCNxName *reference = ccnxName_Acquire(original);
+ *
+ * ccnxName_Release(&original);
+ * ccnxName_Release(&reference);
+ * }
+ * @endcode
+ *
+ * @see ccnxName_Release
+ */
+CCNxName *ccnxName_Acquire(const CCNxName *name);
+
+/**
+ * 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] nameP A pointer to a pointer to the instance to release.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_Create(...);
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ *
+ * @see {@link ccnxName_Acquire}
+ */
+void ccnxName_Release(CCNxName **nameP);
+
+#ifdef Libccnx_DISABLE_VALIDATION
+# define ccnxName_OptionalAssertValid(_instance_)
+#else
+# define ccnxName_OptionalAssertValid(_instance_) ccnxName_AssertValid(_instance_)
+#endif
+
+/**
+ * Assert that an instance of `CCNxName` 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] name A pointer to a `CCNxName` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/ccn/things/p1e");
+ *
+ * ccnxName_AssertValid(name);
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+void ccnxName_AssertValid(const CCNxName *name);
+
+/**
+ * Determine if an instance of `CCNxName` 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 types.
+ *
+ * @param [in] name A pointer to a `CCNxName` instance.
+ * @return true If the instance is valid.
+ * @return false if the instance is not valid.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/ccn/things/p1e");
+ *
+ * if (ccnxName_IsValid(name) == true) {
+ * ...
+ * }
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+bool ccnxName_IsValid(const CCNxName *name);
+
+/**
+ * Append a representation of the specified `CCNxName` instance to the given
+ * {@link PARCBufferComposer}.
+ *
+ * The CCN URI representing the {@link CCNxNameSegment}'s associated with this `CCNxName` is
+ * appended to the supplied {@link PARCBufferComposer}.
+ *
+ * @param [in] name A pointer to a `CCNxName` instance whose representation should be appended to the @p composer.
+ * @param [in,out] composer A pointer to a `PARCBufferComposer` instance to be modified.
+ *
+ * @return NULL Cannot allocate memory.
+ * @return non-NULL The @p composer.
+ *
+ * Example:
+ * @code
+ * {
+ * PARCBufferComposer *result = parcBufferComposer_Create();
+ *
+ * ccnxName_BuildString(instance, result);
+ *
+ * char *string = parcBuffer_ToString(parcBufferComposer_ProduceBuffer(result));
+ * printf("Hello: %s\n", string);
+ * parcMemory_Deallocate(string);
+ *
+ * parcBufferComposer_Release(&result);
+ * }
+ * @endcode
+ *
+ * @see `CCNxNameSegment`
+ */
+PARCBufferComposer *ccnxName_BuildString(const CCNxName *name, PARCBufferComposer *composer);
+
+/**
+ * Produce a null-terminated string representation of the specified instance.
+ *
+ * The non-null result must be freed by the caller via {@link parcMemory_Deallocate}.
+ *
+ * @param [in] name A pointer to the `CCNxName` instance.
+ *
+ * @return NULL Cannot allocate memory.
+ * @return non-NULL A pointer to an allocated,
+ * null-terminated C string that must be deallocated via `parcMemory_Deallocate()`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *instance = ccnxName_Create();
+ *
+ * char *string = ccnxName_ToString(instance);
+ *
+ * if (string != NULL) {
+ * printf("Hello: %s\n", string);
+ * parcMemory_Deallocate(string);
+ * } else {
+ * printf("Cannot allocate memory\n");
+ * }
+ *
+ * ccnxName_Release(&instance);
+ * }
+ * @endcode
+ *
+ * @see {@link ccnxName_BuildString}
+ * @see {@link ccnxName_Display}
+ * @see {@link parcMemory_Deallocate}
+ */
+char *ccnxName_ToString(const CCNxName *name);
+
+/**
+ * Print a human readable representation of the given `CCNxName`.
+ *
+ * @param [in] name A pointer to the `CCNxName` 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/11");
+ *
+ * ccnxInterest_Display(name, 0);
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+void ccnxName_Display(const CCNxName *name, int indentation);
+
+/**
+ * Append a {@link CCNxNameSegment} to the given `CCNxName`.
+ *
+ * Append the `CCNxNameSegment` to the given `CCNxName`.
+ * The given `CCNxName` is modified.
+ *
+ * @param [in,out] name The base `CCNxName` to append the @p segment to.
+ * @param [in] segment The segment to append to @p name.
+ * @return The modifed @p name.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name1 = ccnxName_CreateFromCString("lci:/a/b/c/d");
+ * CCNxName *name2 = ccnxName_Create();
+ *
+ * CCNxNameSegment *segment = ccnxName_GetSegment(name1, 0);
+ *
+ * ccnxName_Append(name2, segment);
+ *
+ * ccnxName_Release(&name1);
+ * ccnxName_Release(&name2);
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_Append(CCNxName *name, const CCNxNameSegment *segment);
+
+/**
+ * Determine if a `CCNxName` is starts with another.
+ *
+ * Each {@link CCNxNameSegment} in @p prefix is tested against the corresponding `CCNxNameSegment`
+ * in @p name.
+ *
+ * @param [in] name A pointer to a `CCNxName` instance.
+ * @param [in] prefix A pointer to a `CCNxName` instance to be tested as a prefix of `name`.
+ *
+ * @return `true` If the given @p name starts with @p prefix.
+ * @return `false` If the given @p name does not start with @p prefix.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/csl/sensors/radiation/17");
+ * CCNxName *prefix = ccnxName_CreateFromCString("lci:/parc/csl");
+ *
+ * if (ccnxName_StartsWith(name, prefix)) {
+ * ...
+ * }
+ *
+ * ccnxName_Release(&name);
+ * ccnxName_Release(&prefix);
+ * }
+ * @endcode
+ */
+bool ccnxName_StartsWith(const CCNxName *name, const CCNxName *prefix);
+
+/**
+ * Create a copy of the specified `CCNxName` instance, producing a new, independent, instance
+ * from dynamically allocated memory.
+ *
+ * This a deep copy. All referenced memory is copied. The created instance of `CCNxName` must
+ * be released by calling {@link ccnxName_Release}().
+ *
+ * @param [in] originalName The `CCNxName` to copy
+ * @return A new, independent copy of the given `CCNxName`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *originalName = ccnxName_CreateFromCString("lci:/parc/csl/sensors/radiation/17");
+ * CCNxName *copy = ccnxName_Copy(originalName);
+ *
+ * ...
+ *
+ * ccnxName_Release(&originalName);
+ * ccnxName_Release(&copy);
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_Copy(const CCNxName *originalName);
+
+/**
+ * Determine if two `CCNxName` instances are equal.
+ *
+ * The following equivalence relations on non-null `CCNxName` instances are maintained:
+ *
+ * * It is reflexive: for any non-null reference value x, `ccnxName_Equals(x, x)` must return true.
+ *
+ * * It is symmetric: for any non-null reference values x and y, `ccnxName_Equals(x, y)` must return true if and only if
+ * `ccnxName_Equals(y x)` returns true.
+ *
+ * * It is transitive: for any non-null reference values x, y, and z, if
+ * `ccnxName_Equals(x, y)` returns true and
+ * `ccnxName_Equals(y, z)` returns true,
+ * then `ccnxName_Equals(x, z)` must return true.
+ *
+ * * It is consistent: for any non-null reference values x and y, multiple invocations of `ccnxName_Equals(x, y)`
+ * consistently return true or consistently return false.
+ *
+ * * For any non-null reference value x, `ccnxName_Equals(x, NULL)` must return false.
+ *
+ * @param [in] name1 A pointer to a `CCNxName` instance.
+ * @param [in] name2 A pointer to a `CCNxName` instance.
+ *
+ * @return True If the given `CCNxName` instances are equal
+ * @return False Otherwise
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *orig = ccnxName_CreateFromCString("lci:/parc/csl/sensors/radiation/17");
+ * CCNxName *copy = ccnxName_Copy(orig);
+ *
+ * if (ccnxName_Equals(orig, copy)) {
+ * // true
+ * } else {
+ * // false
+ * }
+ * ccnxName_Release(&orig);
+ * ccnxName_Release(&copy);
+ * }
+ * @endcode
+ *
+ * @see {@link ccnxName_Compare}
+ */
+bool ccnxName_Equals(const CCNxName *name1, const CCNxName *name2);
+
+/**
+ * Create a new `CCNxName` object
+ *
+ * The instance is reference counted with an initial count of 1.
+ * Additional references are acquired via the function {@link ccnxName_Acquire}
+ * and these references are inidividually released via {@link ccnxName_Release}
+ *
+ * @return A pointer to a new instance of a `CCNxName`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_Create();
+ *
+ * ...
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_Create(void);
+
+/**
+ * Compare @p name1 to @p name2 using CCNx canonical ordering (shortlex).
+ *
+ * `NULL` is considered the shortest name, so `(NULL, non-NULL) -> -1` and
+ * `(NULL, NULL) -> 0`, `(non-NULL, NULL) -> +1`.
+ *
+ * @param [in] name1 A pointer to a `CCNxName` instance.
+ * @param [in] name2 A pointer to a `CCNxName` instance.
+ *
+ * Returns:
+ * <ul>
+ * <li>-1 for name1 < name2</li>
+ * <li> 0 for name1 = name2</li>
+ * <li>+1 for name1 > name2</li>
+ * </ul>
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *orig = ccnxName_CreateFromCString("lci:/parc/csl/sensors/radiation/17");
+ * CCNxName *copy = ccnxName_Copy(orig);
+ *
+ * if (ccnxName_Compare(orig, copy)) {
+ * ...
+ * }
+ *
+ * ccnxName_Release(&orig);
+ * ccnxName_Release(&copy);
+ * }
+ * @endcode
+ *
+ * @see {@link ccnxName_Equals}
+ */
+int ccnxName_Compare(const CCNxName *name1, const CCNxName *name2);
+
+/**
+ * Return a pointer to the {@link CCNxNameSegment} instance for the specified `CCNxName` at the given index.
+ * The index must be greater than or equal to zero and less than {@link ccnxName_GetSegmentCount}().
+ *
+ * @param [in] name The target `CCNxName`
+ * @param [in] index The index into the @p name from which to retrieve the `CCNxNameSegment`.
+ *
+ * @return A pointer to a `CCNxNameSegment`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/csl/things/b00se");
+ * CCNxNameSegment *segment2 = ccnxName_GetSegment(name, 2);
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+CCNxNameSegment *ccnxName_GetSegment(const CCNxName *name, size_t index);
+
+/**
+ * Get the number of `CCNxNameSegments` in the specified `CCNxName`.
+ *
+ * @param [in] name A pointer to an instance of `CCNxName`.
+ *
+ * @return The number of name segments in @p name.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/csl/things/b00se");
+ * size_t segmentCount = ccnxName_GetSegmentCount(name);
+ *
+ * printf("Number of segments: %d\n", segmentCount);
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+size_t ccnxName_GetSegmentCount(const CCNxName *name);
+
+/**
+ * Return a hashcode for the given `CCNxName`.
+ *
+ * Whenever `HashCode()` is invoked on the same object more than once within the same execution environment,
+ * the HashCode function must consistently return the same integer, provided no information used in Equals()
+ * comparisons on the same object is modified.
+ *
+ * This integer need not remain consistent from one execution of an application to another execution of the same application.
+ *
+ * If two objects are equal according to the Equals() function,
+ * then calling the hashCode method on each of the two objects must produce the same integer result.
+ *
+ * It is not required that if two objects are unequal according to the Equals() function,
+ * then calling the Equals() method on each of the two objects must produce distinct integer results.
+ * However, the programmer should be aware that producing distinct integer results for unequal objects
+ * may improve the performance of some data structures.
+ *
+ * @param name [in] A pointer to an instance of `CCNxName`.
+ * @return A uint32_t hash code.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/ccn/things/r00");
+ *
+ * uint32_t hashCode = ccnx_LeftMostHashCode(name);
+ *
+ * ccnxName_Release(&name);
+ * {
+ * @endcode
+ */
+PARCHashCode ccnxName_HashCode(const CCNxName *name);
+
+/**
+ * Return a hash of the leftmost @p count {@link CCNxNameSegment}s in a `CCNxName`.
+ *
+ * See @{link ccnxName_HashCode} for more information.
+ *
+ * @param [in] name A pointer to a `CCNxName` instance.
+ * @param [in] count The number, starting from the left, of path segments to use to compute the hash.
+ *
+ * @return A uint32_t hash code.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/ccn/things/r00");
+ *
+ * uint32_t hashCode = ccnx_LeftMostHashCode(name, 2);
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ */
+PARCHashCode ccnxName_LeftMostHashCode(const CCNxName *name, size_t count);
+
+/**
+ * Trim @p numberToRemove segments from the end of the specified `CCNxName`.
+ *
+ * If @p numberToRemove is greater than the number of segments in the name,
+ * all segments are removed.
+ * If @p numberToRemove is 0, nothing happens.
+ * The name segments are destroyed.
+ *
+ * @param [in,out] name A pointer to a `CCNxName` instance to trim.
+ * @param [in] numberToRemove The number of rightmost segments to remove from the name.
+ *
+ * @return The value of @p name
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *name = ccnxName_CreateFromCString("lci:/parc/ccn/things/b00se");
+ *
+ * name = ccnxName_Trim(name, 2);
+ *
+ * ccnxName_Release(&name);
+ * }
+ * @endcode
+ *
+ */
+CCNxName *ccnxName_Trim(CCNxName *name, size_t numberToRemove);
+
+/**
+ * Compose a new CCNxName instance consisting of the given @prefix appended with @p suffix as a `CCNxNameLabelType_NAME`.
+ *
+ * @param [in] prefix A pointer to a valid CCNxName instance containing the prefix of the new name.
+ * @param [in] suffix A pointer to a nul-terminated C string that is appended to the new name.
+ *
+ * @return non-NULL A pointer to a valid CCNxName instance.
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_ComposeNAME(const CCNxName *prefix, const char *suffix);
+
+
+/**
+ * Get the Nth segment number of the given `CCNxName`
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [in] name A pointer to a valid `CCNxName` instance.
+ * @param [in] nthNumber The nth segment number in the given name, or SIZE_MAX
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+uint64_t ccnxName_GetNthSegmentNumber(const CCNxName *name, size_t nthNumber);
+
+/**
+ * <#One Line Description#>
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in#> | <#out#> | <#in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+uint64_t ccnxName_GetSegmentNumber(const CCNxName *name);
+
+/**
+ * Create a new CCNxName instance composed of the given CCNxName with the parsed result of the format string appended.
+ *
+ * @param [in] baseName The base name of the new CCNxName
+ * @param [in] format A printf(3) format string
+ *
+ * @return non-NULL A pointer to a valid `CCNxName` segment.
+ * @return NULL The object could not be created.
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_ComposeFormatString(const CCNxName *baseName, const char *restrict format, ...);
+
+/**
+ * Create a CCNxName that is a prefix of another.
+ *
+ * If the specified length is greater than the number of segments available,
+ * the result is a new name that is a copy of the old name.
+ *
+ * @param [in] name A pointer to a valid `CCNxName` instance.
+ * @param [in] length The number of `CCNxNameSegments` the prefix must include.
+ *
+ * @return non-NULL A pointer to a valid CCNxName.
+ * @return NULL An error occurred.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxName *a = ccnxName_CreateFromCString("ccnx:/a/b/c");
+ *
+ * CCNxName *prefix = ccnxName_CreatePrefix(a, 1);
+ *
+ * // prefix is equal to the name "ccnx:/a"
+ *
+ * ccnxName_Release(&a);
+ * ccnxName_Release(&prefix);
+ * ccnxName_Release(&actual);
+ * }
+ * @endcode
+ */
+CCNxName *ccnxName_CreatePrefix(const CCNxName *name, size_t length);
+#endif // libccnx_ccnx_Name_h