1 /*
2 * Copyright (c) 2018 Foundries.io
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_INCLUDE_BUF_UTIL_H_
8 #define ZEPHYR_INCLUDE_BUF_UTIL_H_
9
10 #include <zephyr/types.h>
11 #include <errno.h>
12 #include <string.h>
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 /* append */
buf_append(uint8_t * dst,uint16_t * dst_len,uint16_t dst_size,const uint8_t * src,uint16_t src_len)19 static inline int buf_append(uint8_t *dst, uint16_t *dst_len, uint16_t dst_size,
20 const uint8_t *src, uint16_t src_len)
21 {
22 if (!dst || !src) {
23 return -EINVAL;
24 }
25
26 if (*dst_len + src_len > dst_size) {
27 return -ENOMEM;
28 }
29
30 memcpy(dst + *dst_len, src, src_len);
31 *dst_len += src_len;
32 return 0;
33 }
34
35 /* insert */
buf_insert(uint8_t * dst,uint16_t * dst_len,uint16_t dst_size,uint16_t offset,uint8_t * src,uint16_t src_len)36 static inline int buf_insert(uint8_t *dst, uint16_t *dst_len, uint16_t dst_size,
37 uint16_t offset, uint8_t *src, uint16_t src_len)
38 {
39 if (!dst || !src) {
40 return -EINVAL;
41 }
42
43 if (*dst_len + src_len > dst_size) {
44 return -ENOMEM;
45 }
46
47 /* shift everything in fbuf after offset by len */
48 memmove(dst + offset + src_len, dst + offset, *dst_len - offset);
49
50 /* copy src into fbuf at offset */
51 memcpy(dst + offset, src, src_len);
52 *dst_len += src_len;
53 return 0;
54 }
55
56 /* read */
buf_read(uint8_t * dst,uint16_t len,uint8_t * src,uint16_t src_len,uint16_t * offset)57 static inline int buf_read(uint8_t *dst, uint16_t len, uint8_t *src, uint16_t src_len,
58 uint16_t *offset)
59 {
60 if (!src) {
61 return -EINVAL;
62 }
63
64 if (*offset + len > src_len) {
65 return -ENODATA;
66 }
67
68 if (dst) {
69 /* copy data at offset into dst */
70 memcpy(dst, src + *offset, len);
71 }
72
73 *offset += len;
74 return 0;
75 }
76
buf_skip(uint16_t len,uint8_t * src,uint16_t src_len,uint16_t * offset)77 static inline int buf_skip(uint16_t len, uint8_t *src, uint16_t src_len, uint16_t *offset)
78 {
79 return buf_read(NULL, len, src, src_len, offset);
80 }
81
buf_read_u8(uint8_t * value,uint8_t * src,uint16_t src_len,uint16_t * offset)82 static inline int buf_read_u8(uint8_t *value, uint8_t *src, uint16_t src_len,
83 uint16_t *offset)
84 {
85 return buf_read(value, sizeof(uint8_t), src, src_len, offset);
86 }
87
buf_read_u16(uint16_t * value,uint8_t * src,uint16_t src_len,uint16_t * offset)88 static inline int buf_read_u16(uint16_t *value, uint8_t *src, uint16_t src_len,
89 uint16_t *offset)
90 {
91 return buf_read((uint8_t *)value, sizeof(uint16_t), src, src_len, offset);
92 }
93
buf_read_be16(uint16_t * value,uint8_t * src,uint16_t src_len,uint16_t * offset)94 static inline int buf_read_be16(uint16_t *value, uint8_t *src, uint16_t src_len,
95 uint16_t *offset)
96 {
97 int ret;
98 uint8_t v16[2];
99
100 ret = buf_read(v16, sizeof(uint16_t), src, src_len, offset);
101 *value = v16[0] << 8 | v16[1];
102
103 return ret;
104 }
105
buf_read_u32(uint32_t * value,uint8_t * src,uint16_t src_len,uint16_t * offset)106 static inline int buf_read_u32(uint32_t *value, uint8_t *src, uint16_t src_len,
107 uint16_t *offset)
108 {
109 return buf_read((uint8_t *)value, sizeof(uint32_t), src, src_len, offset);
110 }
111
buf_read_be32(uint32_t * value,uint8_t * src,uint16_t src_len,uint16_t * offset)112 static inline int buf_read_be32(uint32_t *value, uint8_t *src, uint16_t src_len,
113 uint16_t *offset)
114 {
115 int ret;
116 uint8_t v32[4];
117
118 ret = buf_read(v32, sizeof(uint32_t), src, src_len, offset);
119 *value = v32[0] << 24 | v32[1] << 16 | v32[2] << 8 | v32[3];
120
121 return ret;
122 }
123
124 #ifdef __cplusplus
125 }
126 #endif
127
128 #endif /* ZEPHYR_INCLUDE_BUF_UTIL_H_ */
129