|
49 | 49 | * undefined, so checking with \ref cbor_value_get_type or \ref
|
50 | 50 | * cbor_value_is_text_string is recommended.
|
51 | 51 | *
|
52 |
| - * If \c malloc returns a NULL pointer, this function will return error |
53 |
| - * condition \ref CborErrorOutOfMemory. |
54 |
| - * |
55 | 52 | * On success, \c *buffer will contain a valid pointer that must be freed by
|
56 |
| - * calling \c free(). This is the case even for zero-length strings. |
57 |
| - * |
58 |
| - * The \a next pointer, if not null, will be updated to point to the next item |
59 |
| - * after this string. If \a value points to the last item, then \a next will be |
| 53 | + * calling \c free(). This is the case even for zero-length strings. The \a |
| 54 | + * next pointer, if not null, will be updated to point to the next item after |
| 55 | + * this string. If \a value points to the last item, then \a next will be |
60 | 56 | * invalid.
|
61 | 57 | *
|
| 58 | + * If \c malloc returns a NULL pointer, this function will return error |
| 59 | + * condition \ref CborErrorOutOfMemory. In this case, \c *buflen should contain |
| 60 | + * the number of bytes necessary to copy this string and \a value will be |
| 61 | + * updated to point to the next element. On all other failure cases, the values |
| 62 | + * contained in \c *buffer, \c *buflen and \a next are undefined and mustn't be |
| 63 | + * used (for example, calling \c{free()}). |
| 64 | + * |
62 | 65 | * This function may not run in constant time (it will run in O(n) time on the
|
63 | 66 | * number of chunks). It requires constant memory (O(1)) in addition to the
|
64 | 67 | * malloc'ed block.
|
|
80 | 83 | * undefined, so checking with \ref cbor_value_get_type or \ref
|
81 | 84 | * cbor_value_is_byte_string is recommended.
|
82 | 85 | *
|
83 |
| - * If \c malloc returns a NULL pointer, this function will return error |
84 |
| - * condition \ref CborErrorOutOfMemory. |
85 |
| - * |
86 | 86 | * On success, \c *buffer will contain a valid pointer that must be freed by
|
87 |
| - * calling \c free(). This is the case even for zero-length strings. |
88 |
| - * |
89 |
| - * The \a next pointer, if not null, will be updated to point to the next item |
90 |
| - * after this string. If \a value points to the last item, then \a next will be |
| 87 | + * calling \c free(). This is the case even for zero-length strings. The \a |
| 88 | + * next pointer, if not null, will be updated to point to the next item after |
| 89 | + * this string. If \a value points to the last item, then \a next will be |
91 | 90 | * invalid.
|
92 | 91 | *
|
| 92 | + * If \c malloc returns a NULL pointer, this function will return error |
| 93 | + * condition \ref CborErrorOutOfMemory. In this case, \c *buflen should contain |
| 94 | + * the number of bytes necessary to copy this string and \a value will be |
| 95 | + * updated to point to the next element. On all other failure cases, the values |
| 96 | + * contained in \c *buffer, \c *buflen and \a next are undefined and mustn't be |
| 97 | + * used (for example, calling \c{free()}). |
| 98 | + * |
93 | 99 | * This function may not run in constant time (it will run in O(n) time on the
|
94 | 100 | * number of chunks). It requires constant memory (O(1)) in addition to the
|
95 | 101 | * malloc'ed block.
|
|
98 | 104 | */
|
99 | 105 | CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t *buflen, CborValue *next)
|
100 | 106 | {
|
| 107 | + const CborValue it = *value; // often value == next |
101 | 108 | CborError err;
|
| 109 | + void *tmpbuf; |
102 | 110 | cbor_assert(buffer);
|
103 | 111 | cbor_assert(buflen);
|
104 | 112 | *buflen = SIZE_MAX;
|
105 |
| - err = _cbor_value_copy_string(value, NULL, buflen, NULL); |
| 113 | + err = _cbor_value_copy_string(&it, NULL, buflen, next); |
106 | 114 | if (err)
|
107 | 115 | return err;
|
108 | 116 |
|
109 | 117 | ++*buflen;
|
110 |
| - *buffer = cbor_malloc(*buflen); |
111 |
| - if (!*buffer) { |
| 118 | + tmpbuf = cbor_malloc(*buflen); |
| 119 | + if (!tmpbuf) { |
112 | 120 | /* out of memory */
|
113 | 121 | return CborErrorOutOfMemory;
|
114 | 122 | }
|
115 |
| - err = _cbor_value_copy_string(value, *buffer, buflen, next); |
| 123 | + err = _cbor_value_copy_string(&it, tmpbuf, buflen, next); |
116 | 124 | if (err) {
|
117 |
| - cbor_free(*buffer); |
| 125 | + /* This shouldn't have happened! We've iterated once. */ |
| 126 | + cbor_free(tmpbuf); |
118 | 127 | return err;
|
119 | 128 | }
|
| 129 | + *buffer = tmpbuf; |
120 | 130 | return CborNoError;
|
121 | 131 | }
|
0 commit comments