1 /*
2 * Copyright 2021 Advanced Micro Devices, Inc.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 /**
8 * \file ac_msgpack.c
9 *
10 * This file provides functions to create msgpack formatted data.
11 * for msgpack specification refer to
12 * github.com/msgpack/msgpack/blob/master/spec.md
13 */
14
15 #include <stdint.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdbool.h>
19 #include <string.h>
20 #include "util/u_math.h"
21 #include "ac_msgpack.h"
22
23 #define MSGPACK_MEM_START_SIZE 0x1000
24 #define MSGPACK_MEM_INC_SIZE 0x1000
25
26 #define MSGPACK_FIXMAP_OP 0x80
27 #define MSGPACK_MAP16_OP 0xde
28 #define MSGPACK_MAP32_OP 0xdf
29
30 #define MSGPACK_FIXARRAY_OP 0x90
31 #define MSGPACK_ARRAY16_OP 0xdc
32 #define MSGPACK_ARRAY32_OP 0xdd
33
34 #define MSGPACK_FIXSTR_OP 0xa0
35 #define MSGPACK_STR8_OP 0xd9
36 #define MSGPACK_STR16_OP 0xda
37 #define MSGPACK_STR32_OP 0xdb
38
39 #define MSGPACK_UINT8_OP 0xcc
40 #define MSGPACK_UINT16_OP 0xcd
41 #define MSGPACK_UINT32_OP 0xce
42 #define MSGPACK_UINT64_OP 0xcf
43
44 #define MSGPACK_NIL_OP 0xc0
45
46 #define MSGPACK_INT8_OP 0xd0
47 #define MSGPACK_INT16_OP 0xd1
48 #define MSGPACK_INT32_OP 0xd2
49 #define MSGPACK_INT64_OP 0xd3
50
51
ac_msgpack_init(struct ac_msgpack * msgpack)52 void ac_msgpack_init(struct ac_msgpack *msgpack)
53 {
54 msgpack->mem = malloc(MSGPACK_MEM_START_SIZE);
55 msgpack->mem_size = MSGPACK_MEM_START_SIZE;
56 msgpack->offset = 0;
57 }
58
ac_msgpack_destroy(struct ac_msgpack * msgpack)59 void ac_msgpack_destroy(struct ac_msgpack *msgpack)
60 {
61 free(msgpack->mem);
62 }
63
ac_msgpack_resize_if_required(struct ac_msgpack * msgpack,uint32_t data_size)64 int ac_msgpack_resize_if_required(struct ac_msgpack *msgpack,
65 uint32_t data_size)
66 {
67 if ((msgpack->offset + data_size) > msgpack->mem_size) {
68 uint32_t new_mem_size;
69
70 new_mem_size = msgpack->mem_size +
71 MAX2(MSGPACK_MEM_INC_SIZE, data_size);
72 msgpack->mem = realloc(msgpack->mem, new_mem_size);
73 if (msgpack->mem == NULL)
74 return false;
75
76 msgpack->mem_size = new_mem_size;
77 }
78
79 return true;
80 }
81
ac_msgpack_add_fixmap_op(struct ac_msgpack * msgpack,uint32_t n)82 void ac_msgpack_add_fixmap_op(struct ac_msgpack *msgpack, uint32_t n)
83 {
84 if (n <= 0xf ) {
85 if (!ac_msgpack_resize_if_required(msgpack, 1))
86 return;
87 msgpack->mem[msgpack->offset] = MSGPACK_FIXMAP_OP | n;
88 msgpack->offset = msgpack->offset + 1;
89 } else if (n <= 0xffff) {
90 if (!ac_msgpack_resize_if_required(msgpack, 3))
91 return;
92 msgpack->mem[msgpack->offset] = MSGPACK_MAP16_OP;
93 *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
94 msgpack->offset = msgpack->offset + 3;
95 } else {
96 if (!ac_msgpack_resize_if_required(msgpack, 5))
97 return;
98 msgpack->mem[msgpack->offset] = MSGPACK_MAP32_OP;
99 *((unsigned int*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
100 msgpack->offset = msgpack->offset + 5;
101 }
102 }
103
ac_msgpack_add_fixarray_op(struct ac_msgpack * msgpack,uint32_t n)104 void ac_msgpack_add_fixarray_op(struct ac_msgpack *msgpack, uint32_t n)
105 {
106 if (n <= 0xf ) {
107 if (!ac_msgpack_resize_if_required(msgpack, 1))
108 return;
109 msgpack->mem[msgpack->offset] = MSGPACK_FIXARRAY_OP | n;
110 msgpack->offset = msgpack->offset + 1;
111 } else if (n <= 0xffff) {
112 if (!ac_msgpack_resize_if_required(msgpack, 3))
113 return;
114 msgpack->mem[msgpack->offset] = MSGPACK_ARRAY16_OP;
115 *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
116 msgpack->offset = msgpack->offset + 3;
117 } else {
118 if (!ac_msgpack_resize_if_required(msgpack, 5))
119 return;
120 msgpack->mem[msgpack->offset] = MSGPACK_ARRAY32_OP;
121 *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
122 msgpack->offset = msgpack->offset + 5;
123 }
124 }
125
ac_msgpack_add_fixstr(struct ac_msgpack * msgpack,const char * str)126 void ac_msgpack_add_fixstr(struct ac_msgpack *msgpack, const char *str)
127 {
128 uint32_t n;
129
130 n = strlen(str);
131
132 if (n <= 0x1f) {
133 if (!ac_msgpack_resize_if_required(msgpack, 1 + n))
134 return;
135 msgpack->mem[msgpack->offset] = MSGPACK_FIXSTR_OP | n;
136 msgpack->offset = msgpack->offset + 1;
137 } else if (n <= 0xff) {
138 if (!ac_msgpack_resize_if_required(msgpack, 2 + n))
139 return;
140 msgpack->mem[msgpack->offset] = MSGPACK_STR8_OP;
141 msgpack->mem[msgpack->offset + 1] = n;
142 msgpack->offset = msgpack->offset + 2;
143 } else if (n <= 0xffff) {
144 if (!ac_msgpack_resize_if_required(msgpack, 3 + n))
145 return;
146 msgpack->mem[msgpack->offset] = MSGPACK_STR16_OP;
147 *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
148 msgpack->offset = msgpack->offset + 3;
149 } else {
150 if (!ac_msgpack_resize_if_required(msgpack, 5 + n))
151 return;
152 msgpack->mem[msgpack->offset] = MSGPACK_STR32_OP;
153 *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
154 msgpack->offset = msgpack->offset + 5;
155 }
156
157 memcpy (&msgpack->mem[msgpack->offset], str, n);
158 msgpack->offset = msgpack->offset + n;
159 }
160
ac_msgpack_add_uint(struct ac_msgpack * msgpack,uint64_t val)161 void ac_msgpack_add_uint(struct ac_msgpack *msgpack, uint64_t val)
162 {
163 if (val <= 0x7f) {
164 if (!ac_msgpack_resize_if_required(msgpack, 1))
165 return;
166 msgpack->mem[msgpack->offset] = val;
167 msgpack->offset = msgpack->offset + 1;
168 } else if (val <= 0xff) {
169 if (!ac_msgpack_resize_if_required(msgpack, 2))
170 return;
171 msgpack->mem[msgpack->offset] = MSGPACK_UINT8_OP;
172 msgpack->mem[msgpack->offset + 1] = val;
173 msgpack->offset = msgpack->offset + 2;
174 } else if (val <= 0xffff) {
175 if (!ac_msgpack_resize_if_required(msgpack, 3))
176 return;
177 msgpack->mem[msgpack->offset] = MSGPACK_UINT16_OP;
178 *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(val);
179 msgpack->offset = msgpack->offset + 3;
180 } else if (val <= 0xffffffff) {
181 if (!ac_msgpack_resize_if_required(msgpack, 5))
182 return;
183 msgpack->mem[msgpack->offset] = MSGPACK_UINT32_OP;
184 *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
185 msgpack->offset = msgpack->offset + 5;
186 } else {
187 if (!ac_msgpack_resize_if_required(msgpack, 9))
188 return;
189 msgpack->mem[msgpack->offset] = MSGPACK_UINT64_OP;
190 *((uint64_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap64(val);
191 msgpack->offset = msgpack->offset + 9;
192 }
193 }
194
ac_msgpack_add_int(struct ac_msgpack * msgpack,int64_t val)195 void ac_msgpack_add_int(struct ac_msgpack *msgpack, int64_t val)
196 {
197 if ((val >= -0x7f) && (val <= 0x7f)) {
198 if ((val >= -31) && (val < 0)) {
199 if (!ac_msgpack_resize_if_required(msgpack, 1))
200 return;
201 msgpack->mem[msgpack->offset] = val | MSGPACK_NIL_OP;
202 msgpack->offset = msgpack->offset + 1;
203 } else if ((val >= 0) && (val <= 127)) {
204 if (!ac_msgpack_resize_if_required(msgpack, 1))
205 return;
206 msgpack->mem[msgpack->offset] = val;
207 msgpack->offset = msgpack->offset + 1;
208 } else {
209 if (!ac_msgpack_resize_if_required(msgpack, 2))
210 return;
211 msgpack->mem[msgpack->offset] = MSGPACK_INT8_OP;
212 msgpack->mem[msgpack->offset + 1] = val;
213 msgpack->offset = msgpack->offset + 2;
214 }
215 } else if ((val >= -0x7fff) && (val <= 0x7fff)) {
216 if (!ac_msgpack_resize_if_required(msgpack, 3))
217 return;
218 msgpack->mem[msgpack->offset] = MSGPACK_INT16_OP;
219 *((int16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
220 msgpack->offset = msgpack->offset + 3;
221 } else if ((val >= -0x7fffffff) && (val <= 0x7fffffff)) {
222 if (!ac_msgpack_resize_if_required(msgpack, 5))
223 return;
224 msgpack->mem[msgpack->offset] = MSGPACK_INT32_OP;
225 *((int32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
226 msgpack->offset = msgpack->offset + 5;
227 } else {
228 if (!ac_msgpack_resize_if_required(msgpack, 9))
229 return;
230 msgpack->mem[msgpack->offset] = MSGPACK_INT64_OP;
231 *((int64_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap64(val);
232 msgpack->offset = msgpack->offset + 9;
233 }
234 }
235