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