xref: /openbsd/lib/libcbor/src/cbor/strings.c (revision 4dcc46c4)
1da0d961cSdjm /*
2d3425be1Sdjm  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3da0d961cSdjm  *
4da0d961cSdjm  * libcbor is free software; you can redistribute it and/or modify
5da0d961cSdjm  * it under the terms of the MIT license. See LICENSE for details.
6da0d961cSdjm  */
7da0d961cSdjm 
8da0d961cSdjm #include "strings.h"
99e5c2ddcSdjm #include <string.h>
10da0d961cSdjm #include "internal/memory_utils.h"
11da0d961cSdjm 
cbor_new_definite_string(void)12*4dcc46c4Sdjm cbor_item_t *cbor_new_definite_string(void) {
13*4dcc46c4Sdjm   cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
149e5c2ddcSdjm   _CBOR_NOTNULL(item);
15da0d961cSdjm   *item = (cbor_item_t){
16da0d961cSdjm       .refcount = 1,
17da0d961cSdjm       .type = CBOR_TYPE_STRING,
189e5c2ddcSdjm       .metadata = {.string_metadata = {_CBOR_METADATA_DEFINITE, 0}}};
19da0d961cSdjm   return item;
20da0d961cSdjm }
21da0d961cSdjm 
cbor_new_indefinite_string(void)22*4dcc46c4Sdjm cbor_item_t *cbor_new_indefinite_string(void) {
23*4dcc46c4Sdjm   cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
249e5c2ddcSdjm   _CBOR_NOTNULL(item);
25da0d961cSdjm   *item = (cbor_item_t){
26da0d961cSdjm       .refcount = 1,
27da0d961cSdjm       .type = CBOR_TYPE_STRING,
289e5c2ddcSdjm       .metadata = {.string_metadata = {.type = _CBOR_METADATA_INDEFINITE,
299e5c2ddcSdjm                                        .length = 0}},
30*4dcc46c4Sdjm       .data = _cbor_malloc(sizeof(struct cbor_indefinite_string_data))};
319e5c2ddcSdjm   _CBOR_DEPENDENT_NOTNULL(item, item->data);
329e5c2ddcSdjm   *((struct cbor_indefinite_string_data *)item->data) =
339e5c2ddcSdjm       (struct cbor_indefinite_string_data){
34da0d961cSdjm           .chunk_count = 0,
35da0d961cSdjm           .chunk_capacity = 0,
36da0d961cSdjm           .chunks = NULL,
37da0d961cSdjm       };
38da0d961cSdjm   return item;
39da0d961cSdjm }
40da0d961cSdjm 
cbor_build_string(const char * val)419e5c2ddcSdjm cbor_item_t *cbor_build_string(const char *val) {
42da0d961cSdjm   cbor_item_t *item = cbor_new_definite_string();
439e5c2ddcSdjm   _CBOR_NOTNULL(item);
44da0d961cSdjm   size_t len = strlen(val);
45*4dcc46c4Sdjm   unsigned char *handle = _cbor_malloc(len);
469e5c2ddcSdjm   _CBOR_DEPENDENT_NOTNULL(item, handle);
47da0d961cSdjm   memcpy(handle, val, len);
48da0d961cSdjm   cbor_string_set_handle(item, handle, len);
49da0d961cSdjm   return item;
50da0d961cSdjm }
51da0d961cSdjm 
cbor_build_stringn(const char * val,size_t length)529e5c2ddcSdjm cbor_item_t *cbor_build_stringn(const char *val, size_t length) {
53da0d961cSdjm   cbor_item_t *item = cbor_new_definite_string();
549e5c2ddcSdjm   _CBOR_NOTNULL(item);
55*4dcc46c4Sdjm   unsigned char *handle = _cbor_malloc(length);
569e5c2ddcSdjm   _CBOR_DEPENDENT_NOTNULL(item, handle);
57da0d961cSdjm   memcpy(handle, val, length);
58da0d961cSdjm   cbor_string_set_handle(item, handle, length);
59da0d961cSdjm   return item;
60da0d961cSdjm }
61da0d961cSdjm 
cbor_string_set_handle(cbor_item_t * item,cbor_mutable_data CBOR_RESTRICT_POINTER data,size_t length)629e5c2ddcSdjm void cbor_string_set_handle(cbor_item_t *item,
639e5c2ddcSdjm                             cbor_mutable_data CBOR_RESTRICT_POINTER data,
649e5c2ddcSdjm                             size_t length) {
65*4dcc46c4Sdjm   CBOR_ASSERT(cbor_isa_string(item));
66*4dcc46c4Sdjm   CBOR_ASSERT(cbor_string_is_definite(item));
67da0d961cSdjm   item->data = data;
68da0d961cSdjm   item->metadata.string_metadata.length = length;
69da0d961cSdjm }
70da0d961cSdjm 
cbor_string_chunks_handle(const cbor_item_t * item)719e5c2ddcSdjm cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *item) {
72*4dcc46c4Sdjm   CBOR_ASSERT(cbor_isa_string(item));
73*4dcc46c4Sdjm   CBOR_ASSERT(cbor_string_is_indefinite(item));
74da0d961cSdjm   return ((struct cbor_indefinite_string_data *)item->data)->chunks;
75da0d961cSdjm }
76da0d961cSdjm 
cbor_string_chunk_count(const cbor_item_t * item)779e5c2ddcSdjm size_t cbor_string_chunk_count(const cbor_item_t *item) {
78*4dcc46c4Sdjm   CBOR_ASSERT(cbor_isa_string(item));
79*4dcc46c4Sdjm   CBOR_ASSERT(cbor_string_is_indefinite(item));
80da0d961cSdjm   return ((struct cbor_indefinite_string_data *)item->data)->chunk_count;
81da0d961cSdjm }
82da0d961cSdjm 
cbor_string_add_chunk(cbor_item_t * item,cbor_item_t * chunk)839e5c2ddcSdjm bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk) {
84*4dcc46c4Sdjm   CBOR_ASSERT(cbor_isa_string(item));
85*4dcc46c4Sdjm   CBOR_ASSERT(cbor_string_is_indefinite(item));
869e5c2ddcSdjm   struct cbor_indefinite_string_data *data =
879e5c2ddcSdjm       (struct cbor_indefinite_string_data *)item->data;
88da0d961cSdjm   if (data->chunk_count == data->chunk_capacity) {
89da0d961cSdjm     if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {
90da0d961cSdjm       return false;
91da0d961cSdjm     }
92da0d961cSdjm 
93d3425be1Sdjm     size_t new_chunk_capacity =
94d3425be1Sdjm         data->chunk_capacity == 0 ? 1
959e5c2ddcSdjm                                   : CBOR_BUFFER_GROWTH * (data->chunk_capacity);
969e5c2ddcSdjm     cbor_item_t **new_chunks_data = _cbor_realloc_multiple(
979e5c2ddcSdjm         data->chunks, sizeof(cbor_item_t *), new_chunk_capacity);
98da0d961cSdjm 
99da0d961cSdjm     if (new_chunks_data == NULL) {
100da0d961cSdjm       return false;
101da0d961cSdjm     }
102da0d961cSdjm 
1039e5c2ddcSdjm     data->chunk_capacity = new_chunk_capacity;
104da0d961cSdjm     data->chunks = new_chunks_data;
105da0d961cSdjm   }
106da0d961cSdjm   data->chunks[data->chunk_count++] = cbor_incref(chunk);
107da0d961cSdjm   return true;
108da0d961cSdjm }
109da0d961cSdjm 
cbor_string_length(const cbor_item_t * item)1109e5c2ddcSdjm size_t cbor_string_length(const cbor_item_t *item) {
111*4dcc46c4Sdjm   CBOR_ASSERT(cbor_isa_string(item));
112da0d961cSdjm   return item->metadata.string_metadata.length;
113da0d961cSdjm }
114da0d961cSdjm 
cbor_string_handle(const cbor_item_t * item)1159e5c2ddcSdjm unsigned char *cbor_string_handle(const cbor_item_t *item) {
116*4dcc46c4Sdjm   CBOR_ASSERT(cbor_isa_string(item));
117da0d961cSdjm   return item->data;
118da0d961cSdjm }
119da0d961cSdjm 
cbor_string_codepoint_count(const cbor_item_t * item)1209e5c2ddcSdjm size_t cbor_string_codepoint_count(const cbor_item_t *item) {
121*4dcc46c4Sdjm   CBOR_ASSERT(cbor_isa_string(item));
122da0d961cSdjm   return item->metadata.string_metadata.codepoint_count;
123da0d961cSdjm }
124da0d961cSdjm 
cbor_string_is_definite(const cbor_item_t * item)1259e5c2ddcSdjm bool cbor_string_is_definite(const cbor_item_t *item) {
126*4dcc46c4Sdjm   CBOR_ASSERT(cbor_isa_string(item));
127da0d961cSdjm   return item->metadata.string_metadata.type == _CBOR_METADATA_DEFINITE;
128da0d961cSdjm }
129da0d961cSdjm 
cbor_string_is_indefinite(const cbor_item_t * item)1309e5c2ddcSdjm bool cbor_string_is_indefinite(const cbor_item_t *item) {
131da0d961cSdjm   return !cbor_string_is_definite(item);
132da0d961cSdjm }
133