17ec681f3Smrg/*
27ec681f3Smrg * Copyright 2021 Advanced Micro Devices, Inc.
37ec681f3Smrg * All Rights Reserved.
47ec681f3Smrg *
57ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
67ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
77ec681f3Smrg * to deal in the Software without restriction, including without limitation
87ec681f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub
97ec681f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom
107ec681f3Smrg * the Software is furnished to do so, subject to the following conditions:
117ec681f3Smrg *
127ec681f3Smrg * The above copyright notice and this permission notice (including the next
137ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
147ec681f3Smrg * Software.
157ec681f3Smrg *
167ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
177ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
197ec681f3Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
207ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
217ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
227ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
237ec681f3Smrg *
247ec681f3Smrg */
257ec681f3Smrg
267ec681f3Smrg/**
277ec681f3Smrg * \file ac_msgpack.c
287ec681f3Smrg *
297ec681f3Smrg * This file provides functions to create msgpack formatted data.
307ec681f3Smrg * for msgpack specification refer to
317ec681f3Smrg * github.com/msgpack/msgpack/blob/master/spec.md
327ec681f3Smrg */
337ec681f3Smrg
347ec681f3Smrg#include <stdint.h>
357ec681f3Smrg#include <stdio.h>
367ec681f3Smrg#include <stdlib.h>
377ec681f3Smrg#include <stdbool.h>
387ec681f3Smrg#include <string.h>
397ec681f3Smrg#include "util/u_math.h"
407ec681f3Smrg#include "ac_msgpack.h"
417ec681f3Smrg
427ec681f3Smrg#define MSGPACK_MEM_START_SIZE 0x1000
437ec681f3Smrg#define MSGPACK_MEM_INC_SIZE 0x1000
447ec681f3Smrg
457ec681f3Smrg#define MSGPACK_FIXMAP_OP 0x80
467ec681f3Smrg#define MSGPACK_MAP16_OP 0xde
477ec681f3Smrg#define MSGPACK_MAP32_OP 0xdf
487ec681f3Smrg
497ec681f3Smrg#define MSGPACK_FIXARRAY_OP 0x90
507ec681f3Smrg#define MSGPACK_ARRAY16_OP 0xdc
517ec681f3Smrg#define MSGPACK_ARRAY32_OP 0xdd
527ec681f3Smrg
537ec681f3Smrg#define MSGPACK_FIXSTR_OP 0xa0
547ec681f3Smrg#define MSGPACK_STR8_OP 0xd9
557ec681f3Smrg#define MSGPACK_STR16_OP 0xda
567ec681f3Smrg#define MSGPACK_STR32_OP 0xdb
577ec681f3Smrg
587ec681f3Smrg#define MSGPACK_UINT8_OP 0xcc
597ec681f3Smrg#define MSGPACK_UINT16_OP 0xcd
607ec681f3Smrg#define MSGPACK_UINT32_OP 0xce
617ec681f3Smrg#define MSGPACK_UINT64_OP 0xcf
627ec681f3Smrg
637ec681f3Smrg#define MSGPACK_NIL_OP 0xc0
647ec681f3Smrg
657ec681f3Smrg#define MSGPACK_INT8_OP 0xd0
667ec681f3Smrg#define MSGPACK_INT16_OP 0xd1
677ec681f3Smrg#define MSGPACK_INT32_OP 0xd2
687ec681f3Smrg#define MSGPACK_INT64_OP 0xd3
697ec681f3Smrg
707ec681f3Smrg
717ec681f3Smrgvoid ac_msgpack_init(struct ac_msgpack *msgpack)
727ec681f3Smrg{
737ec681f3Smrg   msgpack->mem = malloc(MSGPACK_MEM_START_SIZE);
747ec681f3Smrg   msgpack->mem_size = MSGPACK_MEM_START_SIZE;
757ec681f3Smrg   msgpack->offset = 0;
767ec681f3Smrg}
777ec681f3Smrg
787ec681f3Smrgvoid ac_msgpack_destroy(struct ac_msgpack *msgpack)
797ec681f3Smrg{
807ec681f3Smrg   free(msgpack->mem);
817ec681f3Smrg}
827ec681f3Smrg
837ec681f3Smrgint ac_msgpack_resize_if_required(struct ac_msgpack *msgpack,
847ec681f3Smrg                                  uint32_t data_size)
857ec681f3Smrg{
867ec681f3Smrg   if ((msgpack->offset + data_size) > msgpack->mem_size) {
877ec681f3Smrg      uint32_t new_mem_size;
887ec681f3Smrg
897ec681f3Smrg      new_mem_size = msgpack->mem_size +
907ec681f3Smrg                     MAX2(MSGPACK_MEM_INC_SIZE, data_size);
917ec681f3Smrg      msgpack->mem = realloc(msgpack->mem, new_mem_size);
927ec681f3Smrg      if (msgpack->mem == NULL)
937ec681f3Smrg         return false;
947ec681f3Smrg
957ec681f3Smrg      msgpack->mem_size = new_mem_size;
967ec681f3Smrg   }
977ec681f3Smrg
987ec681f3Smrg   return true;
997ec681f3Smrg}
1007ec681f3Smrg
1017ec681f3Smrgvoid ac_msgpack_add_fixmap_op(struct ac_msgpack *msgpack, uint32_t n)
1027ec681f3Smrg{
1037ec681f3Smrg   if (n <= 0xf ) {
1047ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 1))
1057ec681f3Smrg         return;
1067ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_FIXMAP_OP | n;
1077ec681f3Smrg      msgpack->offset = msgpack->offset + 1;
1087ec681f3Smrg   } else if (n <= 0xffff) {
1097ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 3))
1107ec681f3Smrg         return;
1117ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_MAP16_OP;
1127ec681f3Smrg      *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
1137ec681f3Smrg      msgpack->offset = msgpack->offset + 3;
1147ec681f3Smrg   } else {
1157ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 5))
1167ec681f3Smrg         return;
1177ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_MAP32_OP;
1187ec681f3Smrg      *((unsigned int*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
1197ec681f3Smrg      msgpack->offset = msgpack->offset + 5;
1207ec681f3Smrg   }
1217ec681f3Smrg}
1227ec681f3Smrg
1237ec681f3Smrgvoid ac_msgpack_add_fixarray_op(struct ac_msgpack *msgpack, uint32_t n)
1247ec681f3Smrg{
1257ec681f3Smrg   if (n <= 0xf ) {
1267ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 1))
1277ec681f3Smrg         return;
1287ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_FIXARRAY_OP | n;
1297ec681f3Smrg      msgpack->offset = msgpack->offset + 1;
1307ec681f3Smrg   } else if (n <= 0xffff) {
1317ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 3))
1327ec681f3Smrg         return;
1337ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_ARRAY16_OP;
1347ec681f3Smrg      *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
1357ec681f3Smrg      msgpack->offset = msgpack->offset + 3;
1367ec681f3Smrg   } else {
1377ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 5))
1387ec681f3Smrg         return;
1397ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_ARRAY32_OP;
1407ec681f3Smrg      *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
1417ec681f3Smrg      msgpack->offset = msgpack->offset + 5;
1427ec681f3Smrg   }
1437ec681f3Smrg}
1447ec681f3Smrg
1457ec681f3Smrgvoid ac_msgpack_add_fixstr(struct ac_msgpack *msgpack, char *str)
1467ec681f3Smrg{
1477ec681f3Smrg   uint32_t n;
1487ec681f3Smrg
1497ec681f3Smrg   n = strlen(str);
1507ec681f3Smrg
1517ec681f3Smrg   if (n <= 0x1f) {
1527ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 1 + n))
1537ec681f3Smrg         return;
1547ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_FIXSTR_OP | n;
1557ec681f3Smrg      msgpack->offset = msgpack->offset + 1;
1567ec681f3Smrg   } else if (n <= 0xff) {
1577ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 2 + n))
1587ec681f3Smrg         return;
1597ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_STR8_OP;
1607ec681f3Smrg      msgpack->mem[msgpack->offset + 1] = n;
1617ec681f3Smrg      msgpack->offset = msgpack->offset + 2;
1627ec681f3Smrg   } else if (n <= 0xffff) {
1637ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 3 + n))
1647ec681f3Smrg         return;
1657ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_STR16_OP;
1667ec681f3Smrg      *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(n);
1677ec681f3Smrg      msgpack->offset = msgpack->offset + 3;
1687ec681f3Smrg   } else {
1697ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 5 + n))
1707ec681f3Smrg         return;
1717ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_STR32_OP;
1727ec681f3Smrg      *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(n);
1737ec681f3Smrg      msgpack->offset = msgpack->offset + 5;
1747ec681f3Smrg   }
1757ec681f3Smrg
1767ec681f3Smrg   memcpy (&msgpack->mem[msgpack->offset], str, n);
1777ec681f3Smrg   msgpack->offset = msgpack->offset + n;
1787ec681f3Smrg}
1797ec681f3Smrg
1807ec681f3Smrgvoid ac_msgpack_add_uint(struct ac_msgpack *msgpack, uint64_t val)
1817ec681f3Smrg{
1827ec681f3Smrg   if (val <= 0x7f) {
1837ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 1))
1847ec681f3Smrg         return;
1857ec681f3Smrg      msgpack->mem[msgpack->offset] = val;
1867ec681f3Smrg      msgpack->offset = msgpack->offset + 1;
1877ec681f3Smrg   } else if (val <= 0xff) {
1887ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 2))
1897ec681f3Smrg         return;
1907ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_UINT8_OP;
1917ec681f3Smrg      msgpack->mem[msgpack->offset + 1] = val;
1927ec681f3Smrg      msgpack->offset = msgpack->offset + 2;
1937ec681f3Smrg   } else if (val <= 0xffff) {
1947ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 3))
1957ec681f3Smrg         return;
1967ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_UINT16_OP;
1977ec681f3Smrg      *((uint16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap16(val);
1987ec681f3Smrg      msgpack->offset = msgpack->offset + 3;
1997ec681f3Smrg   } else if (val <= 0xffffffff) {
2007ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 5))
2017ec681f3Smrg         return;
2027ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_UINT32_OP;
2037ec681f3Smrg      *((uint32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
2047ec681f3Smrg      msgpack->offset = msgpack->offset + 5;
2057ec681f3Smrg   } else {
2067ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 9))
2077ec681f3Smrg         return;
2087ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_UINT64_OP;
2097ec681f3Smrg      *((uint64_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap64(val);
2107ec681f3Smrg      msgpack->offset = msgpack->offset + 9;
2117ec681f3Smrg   }
2127ec681f3Smrg}
2137ec681f3Smrg
2147ec681f3Smrgvoid ac_msgpack_add_int(struct ac_msgpack *msgpack, int64_t val)
2157ec681f3Smrg{
2167ec681f3Smrg   if ((val >= -0x7f) && (val <= 0x7f)) {
2177ec681f3Smrg      if ((val >= -31) && (val < 0)) {
2187ec681f3Smrg         if (!ac_msgpack_resize_if_required(msgpack, 1))
2197ec681f3Smrg            return;
2207ec681f3Smrg         msgpack->mem[msgpack->offset] = val | MSGPACK_NIL_OP;
2217ec681f3Smrg         msgpack->offset = msgpack->offset + 1;
2227ec681f3Smrg      } else if ((val >= 0) && (val <= 127)) {
2237ec681f3Smrg         if (!ac_msgpack_resize_if_required(msgpack, 1))
2247ec681f3Smrg            return;
2257ec681f3Smrg         msgpack->mem[msgpack->offset] = val;
2267ec681f3Smrg         msgpack->offset = msgpack->offset + 1;
2277ec681f3Smrg      } else {
2287ec681f3Smrg         if (!ac_msgpack_resize_if_required(msgpack, 2))
2297ec681f3Smrg            return;
2307ec681f3Smrg         msgpack->mem[msgpack->offset] = MSGPACK_INT8_OP;
2317ec681f3Smrg         msgpack->mem[msgpack->offset + 1] = val;
2327ec681f3Smrg         msgpack->offset = msgpack->offset + 2;
2337ec681f3Smrg      }
2347ec681f3Smrg   } else if ((val >= -0x7fff) && (val <= 0x7fff)) {
2357ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 3))
2367ec681f3Smrg         return;
2377ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_INT16_OP;
2387ec681f3Smrg      *((int16_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
2397ec681f3Smrg      msgpack->offset = msgpack->offset + 3;
2407ec681f3Smrg   } else if ((val >= -0x7fffffff) && (val <= 0x7fffffff)) {
2417ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 5))
2427ec681f3Smrg         return;
2437ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_INT32_OP;
2447ec681f3Smrg      *((int32_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap32(val);
2457ec681f3Smrg      msgpack->offset = msgpack->offset + 5;
2467ec681f3Smrg   } else {
2477ec681f3Smrg      if (!ac_msgpack_resize_if_required(msgpack, 9))
2487ec681f3Smrg         return;
2497ec681f3Smrg      msgpack->mem[msgpack->offset] = MSGPACK_INT64_OP;
2507ec681f3Smrg      *((int64_t*)&msgpack->mem[msgpack->offset + 1]) = util_bswap64(val);
2517ec681f3Smrg      msgpack->offset = msgpack->offset + 9;
2527ec681f3Smrg   }
2537ec681f3Smrg}
254