posting old shit
This commit is contained in:
parent
e3adc39578
commit
2f42a4a426
238
kore_json_construct.c
Normal file
238
kore_json_construct.c
Normal file
@ -0,0 +1,238 @@
|
||||
#include <PublicDomain.txt>
|
||||
|
||||
// Simple function I wrote to make my life easier while playing with Kore C web server
|
||||
//
|
||||
// Should be easily portable to not use any json libraries at all if you really wanna to
|
||||
//
|
||||
// I know that it uses ?: GCC extension but in this file it can be expanded to standard C ternary operator with simple
|
||||
// sed expression, everything for your closed-source "can't add useful features to my compiler" needs :)
|
||||
//
|
||||
// Usage:
|
||||
// N-th variadic argument starts new context with one of the json types
|
||||
// N+1 sets the name of object if current context is not an array, can be NULL
|
||||
// N+2 sets the object value
|
||||
// N+M marks the end with JSON_END flag if the context was object or array
|
||||
//
|
||||
// Example:
|
||||
// root = json_construct( NULL,
|
||||
// JSON_TYPE_OBJECT, NULL,
|
||||
// JSON_TYPE_STRING, "version", "2.1",
|
||||
// JSON_TYPE_OBJECT, "software",
|
||||
// JSON_TYPE_STRING, "name", "apserv",
|
||||
// JSON_TYPE_STRING, "version", "0.0.1",
|
||||
// JSON_TYPE_STRING, "repository", "https://git.mentality.rip/FWGS/apserv",
|
||||
// JSON_TYPE_STRING, "homepage", "https://git.mentality.rip/FWGS/apserv",
|
||||
// JSON_END,
|
||||
// JSON_TYPE_ARRAY, "protocols",
|
||||
// JSON_TYPE_STRING, "activitypub",
|
||||
// JSON_END,
|
||||
// JSON_TYPE_OBJECT, "services",
|
||||
// JSON_TYPE_ARRAY, "inbound", JSON_END,
|
||||
// JSON_TYPE_ARRAY, "outbound", JSON_END,
|
||||
// JSON_END,
|
||||
// JSON_TYPE_LITERAL, "openRegistrations", APSERV_OPEN_REGISTRATIONS ? JSON_TRUE : JSON_FALSE,
|
||||
// JSON_TYPE_OBJECT, "usage",
|
||||
// JSON_TYPE_OBJECT, "users",
|
||||
// JSON_TYPE_U64, "total", 0,
|
||||
// JSON_TYPE_U64, "activeHalfyear", 0,
|
||||
// JSON_TYPE_U64, "activeMonth", 0,
|
||||
// JSON_END,
|
||||
// JSON_END,
|
||||
// JSON_TYPE_OBJECT, "metadata",
|
||||
// JSON_END,
|
||||
// JSON_END);
|
||||
//
|
||||
// This generates an object below:
|
||||
// {
|
||||
// "version": "2.1",
|
||||
// "software": {
|
||||
// "name": "apserv",
|
||||
// "version": "0.0.1",
|
||||
// "repository": "https://git.mentality.rip/FWGS/apserv",
|
||||
// "homepage": "https://git.mentality.rip/FWGS/apserv"
|
||||
// },
|
||||
// "protocols": [
|
||||
// "activitypub"
|
||||
// ],
|
||||
// "services": {
|
||||
// "inbound": [],
|
||||
// "outbound": []
|
||||
// },
|
||||
// "openRegistrations": false,
|
||||
// "usage": {
|
||||
// "users": {
|
||||
// "total": 0,
|
||||
// "activeHalfyear": 0,
|
||||
// "activeMonth": 0
|
||||
// }
|
||||
// },
|
||||
// "metadata": {}
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <kore/kore.h>
|
||||
|
||||
#define JSON_END 0
|
||||
#define JSON_TYPE_OBJECT KORE_JSON_TYPE_OBJECT
|
||||
#define JSON_TYPE_ARRAY KORE_JSON_TYPE_ARRAY
|
||||
#define JSON_TYPE_STRING KORE_JSON_TYPE_STRING
|
||||
#define JSON_TYPE_NUMBER KORE_JSON_TYPE_NUMBER
|
||||
#define JSON_TYPE_LITERAL KORE_JSON_TYPE_LITERAL
|
||||
#define JSON_TYPE_I32 (1U<<31)
|
||||
#define JSON_TYPE_U32 (1U<<30)
|
||||
#define JSON_TYPE_I64 KORE_JSON_TYPE_INTEGER
|
||||
#define JSON_TYPE_U64 KORE_JSON_TYPE_INTEGER_U64
|
||||
|
||||
#define JSON_FALSE KORE_JSON_FALSE
|
||||
#define JSON_TRUE KORE_JSON_TRUE
|
||||
#define JSON_NULL KORE_JSON_NULL
|
||||
|
||||
struct kore_json_item *json_construct( struct kore_json_item *parent, int type, ... );
|
||||
|
||||
#define JSON_CONSTRUCT_DEBUG
|
||||
|
||||
#ifdef JSON_CONSTRUCT_DEBUG
|
||||
#define CONSTRUCT_DEBUG(...) kore_log( LOG_DEBUG, __VA_ARGS__ )
|
||||
#else
|
||||
#define CONSTRUCT_DEBUG(...)
|
||||
#endif
|
||||
|
||||
static struct kore_json_item *json_construct_onev( struct kore_json_item *parent, bool skipname, int type, va_list ap )
|
||||
{
|
||||
struct kore_json_item *ret = NULL;
|
||||
const char *name, *parent_name;
|
||||
|
||||
if( type == JSON_END )
|
||||
{
|
||||
fatal( "%s: this shouldn't happen", __func__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( parent )
|
||||
{
|
||||
if( parent->name )
|
||||
parent_name = parent->name;
|
||||
else parent_name = "(noname)";
|
||||
}
|
||||
else parent_name = "(noparent)";
|
||||
|
||||
if( !skipname )
|
||||
name = va_arg( ap, const char * );
|
||||
else name = NULL;
|
||||
|
||||
if( type == JSON_TYPE_OBJECT || type == JSON_TYPE_ARRAY )
|
||||
{
|
||||
const char *strtype = type == JSON_TYPE_OBJECT ? "object" : "array";
|
||||
struct kore_json_item *f;
|
||||
|
||||
f = kore_json_create_item( parent, name, type );
|
||||
if( !ret ) ret = f;
|
||||
|
||||
CONSTRUCT_DEBUG( "(%s) creating %s \"%s\"", parent_name, strtype, name ?: "" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
int nexttype = va_arg( ap, int );
|
||||
if( nexttype == JSON_END )
|
||||
{
|
||||
CONSTRUCT_DEBUG( "(%s) closing %s \"%s\"", parent_name, strtype, name ?: "" );
|
||||
return ret;
|
||||
}
|
||||
|
||||
json_construct_onev( f, type == JSON_TYPE_ARRAY, nexttype, ap );
|
||||
}
|
||||
}
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case JSON_TYPE_STRING:
|
||||
{
|
||||
const char *szValue = va_arg( ap, const char * );
|
||||
|
||||
CONSTRUCT_DEBUG( "(%s) creating string object \"%s\": \"%s\"", parent_name, name ?: "", szValue );
|
||||
|
||||
ret = kore_json_create_string( parent, name, szValue );
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_NUMBER:
|
||||
{
|
||||
double flValue = va_arg( ap, double );
|
||||
|
||||
CONSTRUCT_DEBUG( "(%s) creating number parameter \"%s\": %f", parent_name, name ?: "", flValue );
|
||||
|
||||
ret = kore_json_create_number( parent, name, flValue );
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_LITERAL:
|
||||
{
|
||||
int32_t iValue = va_arg( ap, int );
|
||||
const char *szValue;
|
||||
|
||||
switch( iValue )
|
||||
{
|
||||
case JSON_FALSE: szValue = "false"; break;
|
||||
case JSON_TRUE: szValue = "true"; break;
|
||||
case JSON_NULL: szValue = "null"; break;
|
||||
default: fatal("illegal value %d for literal type", iValue );
|
||||
}
|
||||
|
||||
CONSTRUCT_DEBUG( "(%s) creating literal parameter \"%s\": %s", parent_name, name ?: "", szValue );
|
||||
|
||||
ret = kore_json_create_literal( parent, name, iValue );
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_I32:
|
||||
{
|
||||
int32_t iValue = va_arg( ap, int32_t );
|
||||
|
||||
CONSTRUCT_DEBUG( "(%s) creating int32 parameter \"%s\": %d", parent_name, name ?: "", iValue );
|
||||
|
||||
ret = kore_json_create_integer( parent, name, iValue );
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_U32:
|
||||
{
|
||||
uint32_t uValue = va_arg( ap, uint32_t );
|
||||
|
||||
CONSTRUCT_DEBUG( "(%s) creating uint32 parameter \"%s\": %u", parent_name, name ?: "", uValue );
|
||||
|
||||
ret = kore_json_create_integer( parent, name, uValue );
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_I64:
|
||||
{
|
||||
int64_t lValue = va_arg( ap, int64_t );
|
||||
|
||||
CONSTRUCT_DEBUG( "(%s) creating int64 parameter \"%s\": " PRId64, parent_name, name ?: "", lValue );
|
||||
|
||||
ret = kore_json_create_integer( parent, name, lValue );
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_U64:
|
||||
{
|
||||
uint64_t ulValue = va_arg( ap, uint64_t );
|
||||
|
||||
CONSTRUCT_DEBUG( "(%s) creating uint64 parameter \"%s\": " PRIu64, parent_name, name ?: "", ulValue );
|
||||
|
||||
ret = kore_json_create_integer_u64( parent, name, ulValue );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct kore_json_item *json_construct( struct kore_json_item *parent, int type, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start( ap, type );
|
||||
parent = json_construct_onev( parent, type == JSON_TYPE_ARRAY, type, ap );
|
||||
va_end( ap );
|
||||
|
||||
return parent;
|
||||
}
|
Loading…
Reference in New Issue
Block a user