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