Soletta™ Framework
Framework for making IoT devices

Full online documentation | C API Index
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sol-buffer.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Soletta (TM) Project
3  *
4  * Copyright (C) 2015 Intel Corporation. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #pragma once
20 
21 #include <assert.h>
22 
23 #include <errno.h>
24 #include <sol-str-slice.h>
25 #include <sol-types.h>
26 #include <stdarg.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #ifdef __cplusplus
33 #define SOL_BUFFER_C_CAST
34 #else
35 #define SOL_BUFFER_C_CAST (struct sol_buffer)
36 #endif
37 
100 };
101 
109 #define SOL_BUFFER_NEEDS_NUL_BYTE(buf) (!((buf)->flags & SOL_BUFFER_FLAGS_NO_NUL_BYTE))
110 
116 #define SOL_BUFFER_CAN_RESIZE(buf) \
117  (!(buf->flags & (SOL_BUFFER_FLAGS_FIXED_CAPACITY | SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED)))
118 
130 typedef struct sol_buffer {
131  void *data;
132  size_t capacity;
133  size_t used;
135 } sol_buffer;
136 
146 };
147 
153 #define SOL_BUFFER_INIT_EMPTY SOL_BUFFER_C_CAST { .data = NULL, .capacity = 0, .used = 0, .flags = SOL_BUFFER_FLAGS_DEFAULT }
154 
164 #define SOL_BUFFER_INIT_FLAGS(data_, size_, flags_) SOL_BUFFER_C_CAST { .data = data_, .capacity = size_, .used = 0, .flags = (enum sol_buffer_flags)(flags_) }
165 
176 #define SOL_BUFFER_INIT_CONST(data_, size_) SOL_BUFFER_C_CAST { .data = data_, .capacity = size_, .used = size_, .flags = SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }
177 
186 #define SOL_BUFFER_INIT_DATA(data_, size_) SOL_BUFFER_C_CAST { .data = data_, .capacity = size_, .used = size_, .flags = SOL_BUFFER_FLAGS_DEFAULT }
187 
203 #define SOL_BUFFER_DECLARE_STATIC(name_, size_) \
204  uint8_t name_ ## storage[(size_)] = { 0 }; \
205  struct sol_buffer name_ = SOL_BUFFER_INIT_FLAGS(name_ ## storage, (size_), SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED)
206 
214 static inline void
216 {
217  assert(buf);
218  buf->data = NULL;
219  buf->capacity = 0;
220  buf->used = 0;
222 }
223 
232 static inline void
233 sol_buffer_init_flags(struct sol_buffer *buf, void *data, size_t data_size, enum sol_buffer_flags flags)
234 {
235  assert(buf);
236  assert((flags & SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED) ? !!data : 1);
237  buf->data = data;
238  buf->capacity = data_size;
239  buf->used = 0;
240  buf->flags = flags;
241 }
242 
250 void sol_buffer_fini(struct sol_buffer *buf);
251 
260 static inline void *
261 sol_buffer_at(const struct sol_buffer *buf, size_t pos)
262 {
263  if (!buf)
264  return NULL;
265  if (pos > buf->used)
266  return NULL;
267  return (char *)buf->data + pos;
268 }
269 
277 static inline void *
278 sol_buffer_at_end(const struct sol_buffer *buf)
279 {
280  if (!buf)
281  return NULL;
282  return (char *)buf->data + buf->used;
283 }
284 
297 int sol_buffer_resize(struct sol_buffer *buf, size_t new_size);
298 
316 int sol_buffer_expand(struct sol_buffer *buf, size_t bytes);
317 
333 int sol_buffer_ensure(struct sol_buffer *buf, size_t min_size);
334 
350 int sol_buffer_set_slice(struct sol_buffer *buf, const struct sol_str_slice slice);
351 
359 static inline struct sol_str_slice
361 {
362  if (!buf)
363  return SOL_STR_SLICE_STR(NULL, 0);
364  return SOL_STR_SLICE_STR((char *)buf->data, buf->used);
365 }
366 
378 static inline int
379 sol_buffer_set_buffer(struct sol_buffer *dst, const struct sol_buffer *src)
380 {
381  if (!dst || !src)
382  return -EINVAL;
383 
384  return sol_buffer_set_slice(dst, sol_buffer_get_slice(src));
385 }
386 
395 static inline struct sol_str_slice
396 sol_buffer_get_slice_at(const struct sol_buffer *buf, size_t pos)
397 {
398  if (!buf || buf->used < pos)
399  return SOL_STR_SLICE_STR(NULL, 0);
400  return SOL_STR_SLICE_STR((char *)sol_buffer_at(buf, pos), buf->used - pos);
401 }
402 
416 int sol_buffer_insert_char(struct sol_buffer *buf, size_t pos, const char c);
417 
427 int sol_buffer_append_char(struct sol_buffer *buf, const char c);
428 
437 int sol_buffer_append_slice(struct sol_buffer *buf, const struct sol_str_slice slice);
438 
449 int sol_buffer_append_bytes(struct sol_buffer *buf, const uint8_t *bytes, size_t size);
450 
460 int sol_buffer_append_buffer(struct sol_buffer *dst, const struct sol_buffer *src);
461 
484 int sol_buffer_set_slice_at(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice);
485 
498 static inline int
499 sol_buffer_set_buffer_at(struct sol_buffer *dst, size_t pos, const struct sol_buffer *src)
500 {
501  if (!dst || !src)
502  return -EINVAL;
503 
504  return sol_buffer_set_slice_at(dst, pos, sol_buffer_get_slice(src));
505 }
506 
519 int sol_buffer_set_char_at(struct sol_buffer *buf, size_t pos, char c);
520 
534 int sol_buffer_insert_bytes(struct sol_buffer *buf, size_t pos, const uint8_t *bytes, size_t size);
535 
547 int sol_buffer_insert_slice(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice);
548 
560 static inline int
561 sol_buffer_insert_buffer(struct sol_buffer *dst, size_t pos, const struct sol_buffer *src)
562 {
563  if (!dst || !src)
564  return -EINVAL;
565 
566  return sol_buffer_insert_slice(dst, pos, sol_buffer_get_slice(src));
567 }
568 
569 // TODO: move this to some other file? where
574 extern const char SOL_BASE64_MAP[66];
575 
596 int sol_buffer_insert_as_base64(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]);
597 
616 int sol_buffer_append_as_base64(struct sol_buffer *buf, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]);
617 
638 int sol_buffer_insert_from_base64(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]);
639 
658 int sol_buffer_append_from_base64(struct sol_buffer *buf, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]);
659 
679 int sol_buffer_insert_as_base16(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, bool uppercase);
680 
698 int sol_buffer_append_as_base16(struct sol_buffer *buf, const struct sol_str_slice slice, bool uppercase);
699 
722 int sol_buffer_insert_from_base16(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, enum sol_decode_case decode_case);
723 
743 int sol_buffer_append_from_base16(struct sol_buffer *buf, const struct sol_str_slice slice, enum sol_decode_case decode_case);
744 
756 int sol_buffer_append_vprintf(struct sol_buffer *buf, const char *fmt, va_list args) SOL_ATTR_PRINTF(2, 0);
757 
767 static inline int sol_buffer_append_printf(struct sol_buffer *buf, const char *fmt, ...) SOL_ATTR_PRINTF(2, 3);
768 static inline int
769 sol_buffer_append_printf(struct sol_buffer *buf, const char *fmt, ...)
770 {
771  va_list args;
772  int r;
773 
774  va_start(args, fmt);
775  r = sol_buffer_append_vprintf(buf, fmt, args);
776  va_end(args);
777  return r;
778 }
779 
795 int sol_buffer_insert_vprintf(struct sol_buffer *buf, size_t pos, const char *fmt, va_list args) SOL_ATTR_PRINTF(3, 0);
796 
807 static inline int sol_buffer_insert_printf(struct sol_buffer *buf, size_t pos, const char *fmt, ...) SOL_ATTR_PRINTF(3, 4);
808 static inline int
809 sol_buffer_insert_printf(struct sol_buffer *buf, size_t pos, const char *fmt, ...)
810 {
811  va_list args;
812  int r;
813 
814  va_start(args, fmt);
815  r = sol_buffer_insert_vprintf(buf, pos, fmt, args);
816  va_end(args);
817  return r;
818 }
819 
831 static inline int
833 {
834  size_t new_size;
835 
836  if (!buf)
837  return -EINVAL;
838 
840  new_size = buf->used;
841  else if (buf->used == SIZE_MAX)
842  return -EOVERFLOW;
843  else
844  new_size = buf->used + 1;
845 
846  if (new_size == buf->capacity)
847  return 0;
848 
849  return sol_buffer_resize(buf, new_size);
850 }
851 
869 void *sol_buffer_steal(struct sol_buffer *buf, size_t *size);
870 
889 void *sol_buffer_steal_or_copy(struct sol_buffer *buf, size_t *size);
890 
904 struct sol_buffer *sol_buffer_copy(const struct sol_buffer *buf);
905 
913 static inline void
915 {
916  buf->used = 0;
917 }
918 
924 static inline struct sol_buffer *
926 {
927  struct sol_buffer *buf = (struct sol_buffer *)calloc(1, sizeof(struct sol_buffer));
928 
929  if (!buf) return NULL;
930 
931  sol_buffer_init(buf);
932 
933  return buf;
934 }
935 
943 static inline void
945 {
946  sol_buffer_fini(buf);
947  free(buf);
948 }
949 
959 int sol_buffer_ensure_nul_byte(struct sol_buffer *buf);
960 
961 
977 int sol_buffer_remove_data(struct sol_buffer *buf, size_t offset, size_t size);
978 
979 
988 struct sol_blob *sol_buffer_to_blob(struct sol_buffer *buf);
989 
994 #ifdef __cplusplus
995 }
996 #endif
int sol_buffer_append_buffer(struct sol_buffer *dst, const struct sol_buffer *src)
Appends the contents of the buffer from in the end of buf, reallocating if necessary.
size_t capacity
Buffer capacity in bytes.
Definition: sol-buffer.h:132
#define SOL_STATIC_ARRAY_SIZE(n)
Convenience macro to declare the size of a static array that will handle differences between C and C+...
Definition: sol-macros.h:208
Securely clear buffer data before finishing.
Definition: sol-buffer.h:99
static int sol_buffer_set_buffer(struct sol_buffer *dst, const struct sol_buffer *src)
Copy src into dst, ensuring that will fit.
Definition: sol-buffer.h:379
int sol_buffer_insert_as_base64(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
Insert the 'slice' into 'buf' at position 'pos' encoded as base64 using the given map...
Default flags: buffer may be resized and memory will be free'd at the end.
Definition: sol-buffer.h:72
static struct sol_buffer * sol_buffer_new(void)
Creates a new buffer.
Definition: sol-buffer.h:925
#define SOL_ATTR_PRINTF(fmt, arg)
Specifies that a function takes printf style arguments which should be type-checked against a format ...
Definition: sol-macros.h:189
static int sol_buffer_insert_buffer(struct sol_buffer *dst, size_t pos, const struct sol_buffer *src)
Insert the dst into src at position pos, reallocating if necessary.
Definition: sol-buffer.h:561
int sol_buffer_insert_from_base16(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, enum sol_decode_case decode_case)
Insert the 'slice' into 'buf' at position 'pos' decoded from base16 (hexadecimal).
No free buffers won't call free(buf->data) at sol_buffer_fini().
Definition: sol-buffer.h:82
Buffers where the buf->data is not owned by sol_buffer, that is, it can't be resized and free() should...
Definition: sol-buffer.h:88
static struct sol_str_slice sol_buffer_get_slice_at(const struct sol_buffer *buf, size_t pos)
Creates a string slice from the buffer's data starting at position pos.
Definition: sol-buffer.h:396
void sol_buffer_fini(struct sol_buffer *buf)
Finalizes the buffer.
static void * sol_buffer_at_end(const struct sol_buffer *buf)
Returns a pointer to the end of the used portion of the buffer.
Definition: sol-buffer.h:278
int sol_buffer_append_vprintf(struct sol_buffer *buf, const char *fmt, va_list args) SOL_ATTR_PRINTF(2
Append the formatted string in the end of the buffer (including trailing '\0').
int sol_buffer_insert_slice(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice)
Insert the slice into buf at position pos, reallocating if necessary.
These routines are used for Soletta types' manipulation.
int static int sol_buffer_append_printf(struct sol_buffer *buf, const char *fmt,...) SOL_ATTR_PRINTF(2
Append the formatted string in the end of the buffer (including trailing '\0').
Definition: sol-buffer.h:769
static void sol_buffer_free(struct sol_buffer *buf)
Delete the buffer.
Definition: sol-buffer.h:944
int sol_buffer_append_bytes(struct sol_buffer *buf, const uint8_t *bytes, size_t size)
Appends the bytes array to the end of buf, reallocating if necessary.
int sol_buffer_set_char_at(struct sol_buffer *buf, size_t pos, char c)
Set character c into buf at position pos, reallocating if necessary.
int sol_buffer_append_as_base64(struct sol_buffer *buf, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
Append the 'slice' at the end of 'buf' encoded as base64 using the given map.
Fixed capacity buffers won't be resized, sol_buffer_resize() will fail with -EPERM.
Definition: sol-buffer.h:77
Definition: sol-buffer.h:145
int sol_buffer_set_slice(struct sol_buffer *buf, const struct sol_str_slice slice)
Copy slice into buf, ensuring that will fit.
int sol_buffer_append_char(struct sol_buffer *buf, const char c)
Appends character c into the end of buf, reallocating if necessary.
String slice type.
Definition: sol-str-slice.h:84
static void sol_buffer_reset(struct sol_buffer *buf)
Reset the buffer content.
Definition: sol-buffer.h:914
static void sol_buffer_init(struct sol_buffer *buf)
Initializes a sol_buffer structure.
Definition: sol-buffer.h:215
size_t used
Used size in bytes.
Definition: sol-buffer.h:133
int sol_buffer_append_from_base64(struct sol_buffer *buf, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
Append the 'slice' at the end of 'buf' decoded from base64 using the given map.
int sol_buffer_resize(struct sol_buffer *buf, size_t new_size)
Resize the buffer to the given size.
void * sol_buffer_steal_or_copy(struct sol_buffer *buf, size_t *size)
'Steals' buf internal buffer and resets it.
void * data
Buffer data.
Definition: sol-buffer.h:131
struct sol_buffer * sol_buffer_copy(const struct sol_buffer *buf)
Allocate a new sol_buffer and a new data block and copy the contents of the provided sol_buffer...
int sol_buffer_append_slice(struct sol_buffer *buf, const struct sol_str_slice slice)
Appends slice into the end of buf, reallocating if necessary.
const char SOL_BASE64_MAP[66]
The default base 64 map to use.
int sol_buffer_insert_from_base64(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
Insert the 'slice' into 'buf' at position 'pos' decoded from base64 using the given map...
static int sol_buffer_set_buffer_at(struct sol_buffer *dst, size_t pos, const struct sol_buffer *src)
Copy src into dst at position pos, ensuring that will fit.
Definition: sol-buffer.h:499
Data type describing the default blob implementation.
Definition: sol-types.h:468
int sol_buffer_ensure_nul_byte(struct sol_buffer *buf)
Ensures that buffer has a terminating NULL byte.
int sol_buffer_insert_bytes(struct sol_buffer *buf, size_t pos, const uint8_t *bytes, size_t size)
Insert the bytes array into buf at position pos, reallocating if necessary.
struct sol_blob * sol_buffer_to_blob(struct sol_buffer *buf)
Convert a buffer to a struct sol_blob.
static void sol_buffer_init_flags(struct sol_buffer *buf, void *data, size_t data_size, enum sol_buffer_flags flags)
Initializes a sol_buffer structure with the given data and flags.
Definition: sol-buffer.h:233
#define SOL_STR_SLICE_STR(_s, _len)
Helper macro to make easier to declare a string slice from a string.
Definition: sol-str-slice.h:67
enum sol_buffer_flags flags
Buffer flags.
Definition: sol-buffer.h:134
int sol_buffer_insert_char(struct sol_buffer *buf, size_t pos, const char c)
Insert character c into buf at position pos, reallocating if necessary.
static struct sol_str_slice sol_buffer_get_slice(const struct sol_buffer *buf)
Creates a string slice from the buffer's valid data.
Definition: sol-buffer.h:360
static void * sol_buffer_at(const struct sol_buffer *buf, size_t pos)
Returns a pointer to the data at position pos in the buffer buf.
Definition: sol-buffer.h:261
These are routines that Soletta provides for its string slice implementation.
int sol_buffer_set_slice_at(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice)
Set the string slice slice into buf at position pos, reallocating if necessary.
sol_buffer_flags
Flags used to set sol_buffer capabilities.
Definition: sol-buffer.h:67
struct sol_buffer sol_buffer
A sol_buffer is a dynamic array, that can be resized if needed.
sol_decode_case
Case of a string to be decoded.
Definition: sol-buffer.h:142
Definition: sol-buffer.h:143
static int sol_buffer_trim(struct sol_buffer *buf)
Frees memory that is not in being used by the buffer.
Definition: sol-buffer.h:832
void * sol_buffer_steal(struct sol_buffer *buf, size_t *size)
'Steals' sol_buffer internal buffer and resets sol_buffer.
int sol_buffer_expand(struct sol_buffer *buf, size_t bytes)
Increment the buffer capacity to fit the bytes.
int sol_buffer_insert_vprintf(struct sol_buffer *buf, size_t pos, const char *fmt, va_list args) SOL_ATTR_PRINTF(3
Insert the formatted string in the given position in the buffer.
Definition: sol-buffer.h:144
int sol_buffer_remove_data(struct sol_buffer *buf, size_t offset, size_t size)
Removes part of data inside the buffer rearranging the memory properly.
int static int sol_buffer_insert_printf(struct sol_buffer *buf, size_t pos, const char *fmt,...) SOL_ATTR_PRINTF(3
Insert the formatted string in the given position in the buffer.
Definition: sol-buffer.h:809
A sol_buffer is a dynamic array, that can be resized if needed.
Definition: sol-buffer.h:130
int sol_buffer_ensure(struct sol_buffer *buf, size_t min_size)
Ensures that buf has at least min_size.
int sol_buffer_append_from_base16(struct sol_buffer *buf, const struct sol_str_slice slice, enum sol_decode_case decode_case)
Append the 'slice' at the end of 'buf' decoded from base16 (hexadecimal).
int sol_buffer_insert_as_base16(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, bool uppercase)
Insert the 'slice' into 'buf' at position 'pos' encoded as base16 (hexadecimal).
Do not reserve space for the NUL byte.
Definition: sol-buffer.h:92
int sol_buffer_append_as_base16(struct sol_buffer *buf, const struct sol_str_slice slice, bool uppercase)
Append the 'slice' at the end of 'buf' encoded as base16 (hexadecimal).