1/*
2 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3 *
4 * libcbor is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See LICENSE for details.
6 */
7
8#ifndef LIBCBOR_STRINGS_H
9#define LIBCBOR_STRINGS_H
10
11#include "cbor/cbor_export.h"
12#include "cbor/common.h"
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18/*
19 * ============================================================================
20 * String manipulation
21 * ============================================================================
22 */
23
24/** Returns the length of the underlying string in bytes
25 *
26 * There can be fewer unicode character than bytes (see
27 * `cbor_string_codepoint_count`). For definite strings only.
28 *
29 * @param item[borrow] a definite string
30 * @return length of the string. Zero if no chunk has been attached yet
31 */
32_CBOR_NODISCARD CBOR_EXPORT size_t cbor_string_length(const cbor_item_t *item);
33
34/** The number of codepoints in this string
35 *
36 * Might differ from length if there are multibyte ones
37 *
38 * @param item[borrow] A string
39 * @return The number of codepoints in this string
40 */
41_CBOR_NODISCARD CBOR_EXPORT size_t
42cbor_string_codepoint_count(const cbor_item_t *item);
43
44/** Is the string definite?
45 *
46 * @param item[borrow] a string
47 * @return Is the string definite?
48 */
49_CBOR_NODISCARD CBOR_EXPORT bool cbor_string_is_definite(
50    const cbor_item_t *item);
51
52/** Is the string indefinite?
53 *
54 * @param item[borrow] a string
55 * @return Is the string indefinite?
56 */
57_CBOR_NODISCARD CBOR_EXPORT bool cbor_string_is_indefinite(
58    const cbor_item_t *item);
59
60/** Get the handle to the underlying string
61 *
62 * Definite items only. Modifying the data is allowed. In that case, the caller
63 * takes responsibility for the effect on items this item might be a part of
64 *
65 * @param item[borrow] A definite string
66 * @return The address of the underlying string. `NULL` if no data have been
67 * assigned yet.
68 */
69_CBOR_NODISCARD CBOR_EXPORT cbor_mutable_data
70cbor_string_handle(const cbor_item_t *item);
71
72/** Set the handle to the underlying string
73 *
74 *
75 * \rst
76 * .. warning:: Using a pointer to a stack allocated constant is a common
77 *  mistake. Lifetime of the string will expire when it goes out of scope and
78 *  the CBOR item will be left inconsistent.
79 * \endrst
80 *
81 * @param item[borrow] A definite string
82 * @param data The memory block. The caller gives up the ownership of the block.
83 * libcbor will deallocate it when appropriate using its free function
84 * @param length Length of the data block
85 */
86CBOR_EXPORT void cbor_string_set_handle(
87    cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data,
88    size_t length);
89
90/** Get the handle to the array of chunks
91 *
92 * Manipulations with the memory block (e.g. sorting it) are allowed, but the
93 * validity and the number of chunks must be retained.
94 *
95 * @param item[borrow] A indefinite string
96 * @return array of #cbor_string_chunk_count definite strings
97 */
98_CBOR_NODISCARD CBOR_EXPORT cbor_item_t **cbor_string_chunks_handle(
99    const cbor_item_t *item);
100
101/** Get the number of chunks this string consist of
102 *
103 * @param item[borrow] A indefinite string
104 * @return The chunk count. 0 for freshly created items.
105 */
106_CBOR_NODISCARD CBOR_EXPORT size_t
107cbor_string_chunk_count(const cbor_item_t *item);
108
109/** Appends a chunk to the string
110 *
111 * Indefinite strings only.
112 *
113 * May realloc the chunk storage.
114 *
115 * @param item[borrow] An indefinite string
116 * @param item[incref] A definite string
117 * @return true on success. false on realloc failure. In that case, the refcount
118 * of `chunk` is not increased and the `item` is left intact.
119 */
120_CBOR_NODISCARD CBOR_EXPORT bool cbor_string_add_chunk(cbor_item_t *item,
121                                                       cbor_item_t *chunk);
122
123/** Creates a new definite string
124 *
125 * The handle is initialized to `NULL` and length to 0
126 *
127 * @return **new** definite string. `NULL` on malloc failure.
128 */
129_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_definite_string(void);
130
131/** Creates a new indefinite string
132 *
133 * The chunks array is initialized to `NULL` and chunkcount to 0
134 *
135 * @return **new** indefinite string. `NULL` on malloc failure.
136 */
137_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_indefinite_string(void);
138
139/** Creates a new string and initializes it
140 *
141 * The `val` will be copied to a newly allocated block
142 *
143 * @param val A null-terminated UTF-8 string
144 * @return A **new** string with content `handle`. `NULL` on malloc failure.
145 */
146_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_string(const char *val);
147
148/** Creates a new string and initializes it
149 *
150 * The `handle` will be copied to a newly allocated block
151 *
152 * @param val A UTF-8 string, at least \p length long (excluding the null byte)
153 * @return A **new** string with content `handle`. `NULL` on malloc failure.
154 */
155_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_stringn(const char *val,
156                                                            size_t length);
157
158#ifdef __cplusplus
159}
160#endif
161
162#endif  // LIBCBOR_STRINGS_H
163