1 /*
2 * Copyright 2021 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26 /**
27 * \file ac_msgpack.c
28 *
29 * This file provides functions to create msgpack formatted data.
30 * for msgpack specification refer to
31 * github.com/msgpack/msgpack/blob/master/spec.md
32 */
33
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdbool.h>
38 #include <string.h>
39 #include "util/u_math.h"
40 #include "ac_msgpack.h"
41
42 #define MSGPACK_MEM_START_SIZE 0x1000
43 #define MSGPACK_MEM_INC_SIZE 0x1000
44
45 #define MSGPACK_FIXMAP_OP 0x80
46 #define MSGPACK_MAP16_OP 0xde
47 #define MSGPACK_MAP32_OP 0xdf
48
49 #define MSGPACK_FIXARRAY_OP 0x90
50 #define MSGPACK_ARRAY16_OP 0xdc
51 #define MSGPACK_ARRAY32_OP 0xdd
52
53 #define MSGPACK_FIXSTR_OP 0xa0
54 #define MSGPACK_STR8_OP 0xd9
55 #define MSGPACK_STR16_OP 0xda
56 #define MSGPACK_STR32_OP 0xdb
57
58 #define MSGPACK_UINT8_OP 0xcc
59 #define MSGPACK_UINT16_OP 0xcd
60 #define MSGPACK_UINT32_OP 0xce
61 #define MSGPACK_UINT64_OP 0xcf
62
63 #define MSGPACK_NIL_OP 0xc0
64
65 #define MSGPACK_INT8_OP 0xd0
66 #define MSGPACK_INT16_OP 0xd1
67 #define MSGPACK_INT32_OP 0xd2
68 #define MSGPACK_INT64_OP 0xd3
69
70
ac_msgpack_init(struct ac_msgpack * msgpack)71 void ac_msgpack_init(struct ac_msgpack *msgpack)
72 {
73 msgpack->mem = malloc(MSGPACK_MEM_START_SIZE);
74 msgpack->mem_size = MSGPACK_MEM_START_SIZE;
75 msgpack->offset = 0;
76 }
77
ac_msgpack_destroy(struct ac_msgpack * msgpack)78 void ac_msgpack_destroy(struct ac_msgpack *msgpack)
79 {
80 free(msgpack->mem);
81 }
82
ac_msgpack_resize_if_required(struct ac_msgpack * msgpack,uint32_t data_size)83 int ac_msgpack_resize_if_required(struct ac_msgpack *msgpack,
84 uint32_t data_size)
85 {
86 if ((msgpack->offset + data_size) > msgpack->mem_size) {
87 uint32_t new_mem_size;
88
89 new_mem_size = msgpack->mem_size +
90 MAX2(MSGPACK_MEM_INC_SIZE, data_size);
91 msgpack->mem = realloc(msgpack->mem, new_mem_size);
92 if (msgpack->mem == NULL)
93 return false;
94
95 msgpack->mem_size = new_mem_size;
96 }
97
98 return true;
99 }
100
ac_msgpack_add_fixmap_op(struct ac_msgpack * msgpack,uint32_t n)101 void ac_msgpack_add_fixmap_op(struct ac_msgpack *msgpack, uint32_t n)
102 {
103 if (n <= 0xf ) {
104 if (!ac_msgpack_resize_if_required(msgpack, 1))
105 return;
106 msgpack->mem[msgpack->offset] = MSGPACK_FIXMAP_OP | n;
107 msgpack->offset = msgpack->offset + 1;
108 } else if (n <= 0xffff) {
109 if (!ac_msgpack_resize_if_required(msgpack, 3))
110 return;
111 msgpack->mem[msgpack->offset] = MSGPACK_MAP16_OP;
112 *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
113 msgpack->offset = msgpack->offset + 3;
114 } else {
115 if (!ac_msgpack_resize_if_required(msgpack, 5))
116 return;
117 msgpack->mem[msgpack->offset] = MSGPACK_MAP32_OP;
118 *((unsigned int*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
119 msgpack->offset = msgpack->offset + 5;
120 }
121 }
122
ac_msgpack_add_fixarray_op(struct ac_msgpack * msgpack,uint32_t n)123 void ac_msgpack_add_fixarray_op(struct ac_msgpack *msgpack, uint32_t n)
124 {
125 if (n <= 0xf ) {
126 if (!ac_msgpack_resize_if_required(msgpack, 1))
127 return;
128 msgpack->mem[msgpack->offset] = MSGPACK_FIXARRAY_OP | n;
129 msgpack->offset = msgpack->offset + 1;
130 } else if (n <= 0xffff) {
131 if (!ac_msgpack_resize_if_required(msgpack, 3))
132 return;
133 msgpack->mem[msgpack->offset] = MSGPACK_ARRAY16_OP;
134 *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
135 msgpack->offset = msgpack->offset + 3;
136 } else {
137 if (!ac_msgpack_resize_if_required(msgpack, 5))
138 return;
139 msgpack->mem[msgpack->offset] = MSGPACK_ARRAY32_OP;
140 *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
141 msgpack->offset = msgpack->offset + 5;
142 }
143 }
144
ac_msgpack_add_fixstr(struct ac_msgpack * msgpack,char * str)145 void ac_msgpack_add_fixstr(struct ac_msgpack *msgpack, char *str)
146 {
147 uint32_t n;
148
149 n = strlen(str);
150
151 if (n <= 0x1f) {
152 if (!ac_msgpack_resize_if_required(msgpack, 1 + n))
153 return;
154 msgpack->mem[msgpack->offset] = MSGPACK_FIXSTR_OP | n;
155 msgpack->offset = msgpack->offset + 1;
156 } else if (n <= 0xff) {
157 if (!ac_msgpack_resize_if_required(msgpack, 2 + n))
158 return;
159 msgpack->mem[msgpack->offset] = MSGPACK_STR8_OP;
160 msgpack->mem[msgpack->offset + 1] = n;
161 msgpack->offset = msgpack->offset + 2;
162 } else if (n <= 0xffff) {
163 if (!ac_msgpack_resize_if_required(msgpack, 3 + n))
164 return;
165 msgpack->mem[msgpack->offset] = MSGPACK_STR16_OP;
166 *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
167 msgpack->offset = msgpack->offset + 3;
168 } else {
169 if (!ac_msgpack_resize_if_required(msgpack, 5 + n))
170 return;
171 msgpack->mem[msgpack->offset] = MSGPACK_STR32_OP;
172 *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
173 msgpack->offset = msgpack->offset + 5;
174 }
175
176 memcpy (&msgpack->mem[msgpack->offset], str, n);
177 msgpack->offset = msgpack->offset + n;
178 }
179
ac_msgpack_add_uint(struct ac_msgpack * msgpack,uint64_t val)180 void ac_msgpack_add_uint(struct ac_msgpack *msgpack, uint64_t val)
181 {
182 if (val <= 0x7f) {
183 if (!ac_msgpack_resize_if_required(msgpack, 1))
184 return;
185 msgpack->mem[msgpack->offset] = val;
186 msgpack->offset = msgpack->offset + 1;
187 } else if (val <= 0xff) {
188 if (!ac_msgpack_resize_if_required(msgpack, 2))
189 return;
190 msgpack->mem[msgpack->offset] = MSGPACK_UINT8_OP;
191 msgpack->mem[msgpack->offset + 1] = val;
192 msgpack->offset = msgpack->offset + 2;
193 } else if (val <= 0xffff) {
194 if (!ac_msgpack_resize_if_required(msgpack, 3))
195 return;
196 msgpack->mem[msgpack->offset] = MSGPACK_UINT16_OP;
197 *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(val);
198 msgpack->offset = msgpack->offset + 3;
199 } else if (val <= 0xffffffff) {
200 if (!ac_msgpack_resize_if_required(msgpack, 5))
201 return;
202 msgpack->mem[msgpack->offset] = MSGPACK_UINT32_OP;
203 *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
204 msgpack->offset = msgpack->offset + 5;
205 } else {
206 if (!ac_msgpack_resize_if_required(msgpack, 9))
207 return;
208 msgpack->mem[msgpack->offset] = MSGPACK_UINT64_OP;
209 *((uint64_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap64(val);
210 msgpack->offset = msgpack->offset + 9;
211 }
212 }
213
ac_msgpack_add_int(struct ac_msgpack * msgpack,int64_t val)214 void ac_msgpack_add_int(struct ac_msgpack *msgpack, int64_t val)
215 {
216 if ((val >= -0x7f) && (val <= 0x7f)) {
217 if ((val >= -31) && (val < 0)) {
218 if (!ac_msgpack_resize_if_required(msgpack, 1))
219 return;
220 msgpack->mem[msgpack->offset] = val | MSGPACK_NIL_OP;
221 msgpack->offset = msgpack->offset + 1;
222 } else if ((val >= 0) && (val <= 127)) {
223 if (!ac_msgpack_resize_if_required(msgpack, 1))
224 return;
225 msgpack->mem[msgpack->offset] = val;
226 msgpack->offset = msgpack->offset + 1;
227 } else {
228 if (!ac_msgpack_resize_if_required(msgpack, 2))
229 return;
230 msgpack->mem[msgpack->offset] = MSGPACK_INT8_OP;
231 msgpack->mem[msgpack->offset + 1] = val;
232 msgpack->offset = msgpack->offset + 2;
233 }
234 } else if ((val >= -0x7fff) && (val <= 0x7fff)) {
235 if (!ac_msgpack_resize_if_required(msgpack, 3))
236 return;
237 msgpack->mem[msgpack->offset] = MSGPACK_INT16_OP;
238 *((int16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
239 msgpack->offset = msgpack->offset + 3;
240 } else if ((val >= -0x7fffffff) && (val <= 0x7fffffff)) {
241 if (!ac_msgpack_resize_if_required(msgpack, 5))
242 return;
243 msgpack->mem[msgpack->offset] = MSGPACK_INT32_OP;
244 *((int32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
245 msgpack->offset = msgpack->offset + 5;
246 } else {
247 if (!ac_msgpack_resize_if_required(msgpack, 9))
248 return;
249 msgpack->mem[msgpack->offset] = MSGPACK_INT64_OP;
250 *((int64_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap64(val);
251 msgpack->offset = msgpack->offset + 9;
252 }
253 }
254