libcbor  0.5.0
libcbor is a C library for parsing and generating CBOR, the general-purpose schema-less binary data format.
strings.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2017 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 #include <string.h>
9 #include "strings.h"
10 #include "internal/memory_utils.h"
11 
13 {
14  cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
15  *item = (cbor_item_t) {
16  .refcount = 1,
17  .type = CBOR_TYPE_STRING,
18  .metadata = {.string_metadata = {_CBOR_METADATA_DEFINITE, 0}}
19  };
20  return item;
21 }
22 
24 {
25  cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
26  *item = (cbor_item_t) {
27  .refcount = 1,
28  .type = CBOR_TYPE_STRING,
29  .metadata = {.string_metadata = {.type = _CBOR_METADATA_INDEFINITE, .length = 0}},
30  .data = _CBOR_MALLOC(sizeof(struct cbor_indefinite_string_data))
31  };
32  *((struct cbor_indefinite_string_data *) item->data) = (struct cbor_indefinite_string_data) {
33  .chunk_count = 0,
34  .chunk_capacity = 0,
35  .chunks = NULL,
36  };
37  return item;
38 }
39 
40 cbor_item_t *cbor_build_string(const char *val)
41 {
43  size_t len = strlen(val);
44  unsigned char * handle = _CBOR_MALLOC(len);
45  memcpy(handle, val, len);
46  cbor_string_set_handle(item, handle, len);
47  return item;
48 }
49 
50 cbor_item_t *cbor_build_stringn(const char *val, size_t length)
51 {
53  unsigned char * handle = _CBOR_MALLOC(length);
54  memcpy(handle, val, length);
55  cbor_string_set_handle(item, handle, length);
56  return item;
57 }
58 
60 {
61  assert(cbor_isa_string(item));
62  assert(cbor_string_is_definite(item));
63  item->data = data;
64  item->metadata.string_metadata.length = length;
65 }
66 
68 {
69  assert(cbor_isa_string(item));
70  assert(cbor_string_is_indefinite(item));
71  return ((struct cbor_indefinite_string_data *) item->data)->chunks;
72 }
73 
75 {
76  assert(cbor_isa_string(item));
77  assert(cbor_string_is_indefinite(item));
78  return ((struct cbor_indefinite_string_data *) item->data)->chunk_count;
79 
80 }
81 
83 {
84  assert(cbor_isa_string(item));
85  assert(cbor_string_is_indefinite(item));
86  struct cbor_indefinite_string_data *data = (struct cbor_indefinite_string_data *) item->data;
87  if (data->chunk_count == data->chunk_capacity) {
88  /* We need more space */
89  if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {
90  return false;
91  }
92 
93  data->chunk_capacity = data->chunk_capacity == 0 ? 1 : CBOR_BUFFER_GROWTH * (data->chunk_capacity);
94  cbor_item_t **new_chunks_data = _cbor_realloc_multiple(data->chunks, sizeof(cbor_item_t *), data->chunk_capacity);
95 
96  if (new_chunks_data == NULL) {
97  return false;
98  }
99 
100  data->chunks = new_chunks_data;
101  }
102  data->chunks[data->chunk_count++] = cbor_incref(chunk);
103  return true;
104 }
105 
106 size_t cbor_string_length(const cbor_item_t *item)
107 {
108  assert(cbor_isa_string(item));
109  return item->metadata.string_metadata.length;
110 }
111 
112 unsigned char *cbor_string_handle(const cbor_item_t *item)
113 {
114  assert(cbor_isa_string(item));
115  return item->data;
116 }
117 
119 {
120  assert(cbor_isa_string(item));
122 }
123 
125 {
126  assert(cbor_isa_string(item));
128 }
129 
131 {
132  return !cbor_string_is_definite(item);
133 }
struct cbor_item_t cbor_item_t
The item handle.
cbor_item_t ** chunks
Definition: data.h:167
void cbor_string_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length)
Set the handle to the underlying string.
Definition: strings.c:59
cbor_item_t * cbor_build_stringn(const char *val, size_t length)
Creates a new string and initializes it.
Definition: strings.c:50
3 - strings
Definition: data.h:28
union cbor_item_metadata metadata
Discriminated by type.
Definition: data.h:151
unsigned char * cbor_string_handle(const cbor_item_t *item)
Get the handle to the underlying string.
Definition: strings.c:112
void * _cbor_realloc_multiple(void *pointer, size_t item_size, size_t item_count)
Overflow-proof contiguous array reallocation.
Definition: memory_utils.c:39
cbor_item_t * cbor_new_indefinite_string()
Creates a new indefinite string.
Definition: strings.c:23
bool cbor_isa_string(const cbor_item_t *item)
Does the item have the appropriate major type?
Definition: common.c:33
cbor_item_t ** cbor_string_chunks_handle(const cbor_item_t *item)
Get the handle to the array of chunks.
Definition: strings.c:67
#define CBOR_RESTRICT_POINTER
Definition: common.h:33
#define _CBOR_MALLOC
Definition: common.h:84
size_t refcount
Reference count - initialize to 0.
Definition: data.h:153
cbor_item_t * cbor_new_definite_string()
Creates a new definite string.
Definition: strings.c:12
unsigned char * cbor_mutable_data
Definition: data.h:21
size_t cbor_string_chunk_count(const cbor_item_t *item)
Get the number of chunks this string consist of.
Definition: strings.c:74
cbor_item_t * cbor_incref(cbor_item_t *item)
Increases the reference count by one.
Definition: common.c:93
size_t codepoint_count
Definition: data.h:90
Defines cbor_item_t::data structure for indefinite strings and bytestrings.
Definition: data.h:164
struct _cbor_string_metadata string_metadata
Definition: data.h:141
cbor_item_t * cbor_build_string(const char *val)
Creates a new string and initializes it.
Definition: strings.c:40
size_t cbor_string_codepoint_count(const cbor_item_t *item)
The number of codepoints in this string.
Definition: strings.c:118
bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk)
Appends a chunk to the string.
Definition: strings.c:82
bool cbor_string_is_definite(const cbor_item_t *item)
Is the string definite?
Definition: strings.c:124
unsigned char * data
Raw data block - interpretation depends on metadata.
Definition: data.h:157
_cbor_dst_metadata type
Definition: data.h:91
size_t cbor_string_length(const cbor_item_t *item)
Returns the length of the underlying string.
Definition: strings.c:106
bool _cbor_safe_to_multiply(size_t a, size_t b)
Can a and b be multiplied without overflowing size_t?
Definition: memory_utils.c:25
The item handle.
Definition: data.h:149
bool cbor_string_is_indefinite(const cbor_item_t *item)
Is the string indefinite?
Definition: strings.c:130