/*******************************************************************************
* This file is part of the Incubed project.
* Sources: https://github.com/blockchainsllc/in3
*
* Copyright (C) 2018-2020 slock.it GmbH, Blockchains LLC
*
*
* COMMERCIAL LICENSE USAGE
*
* Licensees holding a valid commercial license may use this file in accordance
* with the commercial license agreement provided with the Software or, alternatively,
* in accordance with the terms contained in a written agreement between you and
* slock.it GmbH/Blockchains LLC. For licensing terms and conditions or further
* information please contact slock.it at in3@slock.it.
*
* Alternatively, this file may be used under the AGPL license as follows:
*
* AGPL LICENSE USAGE
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
* [Permissions of this strong copyleft license are conditioned on making available
* complete source code of licensed works and modifications, which include larger
* works using a licensed work, under the same license. Copyright and license notices
* must be preserved. Contributors provide an express grant of patent rights.]
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see .
*******************************************************************************/
// @PUBLIC_HEADER
/** @file
* simple string buffer used to dynamicly add content.
* */
#ifndef __STR_BUILDER_H__
#define __STR_BUILDER_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "bytes.h"
#include "data.h"
#include
#include
#include
/** shortcut macro for adding a uint to the stringbuilder using sizeof(i) to automaticly determine the size*/
#define sb_add_hexuint(sb, i) sb_add_hexuint_l(sb, i, sizeof(i))
#ifdef __ZEPHYR__
typedef unsigned long long uintmax_t;
#endif
/**
* string build struct, which is able to hold and modify a growing string.
*/
typedef struct sb {
char* data; /**< the current string (null terminated)*/
size_t allocted; /**< number of bytes currently allocated */
size_t len; /**< the current length of the string */
} sb_t;
/**
* creates a stringbuilder which is allocating any new memory, but uses an existing string and is used directly on the stack.
* Since it will not grow the memory you need to pass a char* which allocated enough memory.
*/
NONULL static inline sb_t sb_stack(char* p) { return (sb_t){.allocted = 0xffffff, .len = 0, .data = p}; }
sb_t* sb_new(const char* chars); /**< creates a new stringbuilder and copies the inital characters into it.*/
NONULL sb_t* sb_init(sb_t* sb); /**< initializes a stringbuilder by allocating memory. */
NONULL void sb_free(sb_t* sb); /**< frees all resources of the stringbuilder */
NONULL sb_t* sb_add_char(sb_t* sb, char c); /**< add a single character */
NONULL sb_t* sb_add_chars(sb_t* sb, const char* chars); /**< adds a string */
NONULL sb_t* sb_add_range(sb_t* sb, const char* chars, int start, int len); /**< add a string range */
NONULL sb_t* sb_add_key_value(sb_t* sb, const char* key, const char* value, int value_len, bool as_string); /**< adds a value with an optional key. if as_string is true the value will be quoted. */
NONULL_FOR((1, 3))
sb_t* sb_add_bytes(sb_t* sb, const char* prefix, const bytes_t* bytes, int len, bool as_array); /**< add bytes as 0x-prefixed hexcoded string (including an optional prefix), if len>1 is passed bytes maybe an array ( if as_array==true) */
NONULL sb_t* sb_add_hexuint_l(sb_t* sb, uintmax_t uint, size_t l); /**< add a integer value as hexcoded, 0x-prefixed string*/
NONULL sb_t* sb_add_escaped_chars(sb_t* sb, const char* chars); /**< add chars but escapes all quotes */
NONULL sb_t* sb_add_int(sb_t* sb, int64_t val); /**< adds a numeric value to the stringbuilder */
NONULL char* format_json(const char* json); /**< format a json string and returns a new string, which needs to be freed */
NONULL_FOR((1))
sb_t* sb_add_rawbytes(sb_t* sb, char* prefix, bytes_t b, int fix_size);
sb_t* sb_print(sb_t* sb, const char* fmt, ...);
sb_t* sb_vprint(sb_t* sb, const char* fmt, va_list args);
sb_t* sb_add_json(sb_t* sb, const char* prefix, d_token_t* token);
sb_t* sb_printx(sb_t* sb, const char* fmt, ...);
#ifdef __cplusplus
}
#endif
#endif