Fri, 12 Dec 2025 10:42:53 +0100
update ucx
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2025 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "json.h" CxJsonValue* dbuObjectToJson(DBUClass *type, void *obj, const CxAllocator *a) { return dbuObjectToJson2(type, obj, a, false, false); } CxJsonValue* dbuObjectToJson2(DBUClass *type, void *obj, const CxAllocator *a, bool setNull, bool forceString) { if(obj == NULL) { return cxJsonCreateLiteral(a, CX_JSON_NULL); } if(!a) { a = cxDefaultAllocator; } CxJsonValue *value = cxJsonCreateObj(a); if(!value) { return NULL; } // add all primitive values CxMapIterator i = cxMapIteratorValues(type->fields); for(int n=0;n<2;n++) { cx_foreach(DBUField *, field, i) { CxJsonValue *child = NULL; if(field->toBool) { bool b = field->toBool(field, obj); child = cxJsonCreateLiteral(a, b ? CX_JSON_TRUE : CX_JSON_FALSE); } else if(field->toInt64) { int64_t i = field->toInt64(field, obj); child = cxJsonCreateInteger(a, i); } else if(field->toUInt64) { uint64_t u = field->toUInt64(field, obj); child = cxJsonCreateInteger(a, (int64_t)u); } else if(field->toDouble) { double d = field->toDouble(field, obj); child = cxJsonCreateNumber(a, d); } else if(field->toString) { cxmutstr s = field->toString(field, obj, a); if(s.ptr) { // we don't want to copy the string again, therefore // we can't use cxJsonCreateString child = cxMalloc(a, sizeof(CxJsonValue)); if(!child) { cxFree(a, s.ptr); return NULL; } child->allocator = a; child->type = CX_JSON_STRING; child->string = s; } } else if(field->toBinary) { // TODO } else if(field->toObject) { DBUObject child_obj = field->toObject(field, obj); if(child_obj == NULL) { child = CX_JSON_NULL; } else if(field->objType) { child = dbuObjectToJson2(field->objType, child_obj, a, setNull, forceString); } } else if(field->toList) { DBUAbstractList *list = field->toList(field, obj); child = cxJsonCreateArr(a); if(child) { if(list->iterator) { CxIterator iter = list->iterator(list); cx_foreach(void *, elm, iter) { DBUField *f = list->elementField(list, elm); if(f->toObject) { DBUObject child_obj = f->toObject(field, elm); if(f->objType) { CxJsonValue *array_elm = dbuObjectToJson2(f->objType, child_obj, a, setNull, forceString); cxJsonArrAddValues(child, &array_elm, 1); } } } } } } else { continue; // non-serializable field } if(!child) { cxJsonValueFree(value); return NULL; } if(cxJsonObjPut(value, field->name, child)) { cxJsonValueFree(child); cxJsonValueFree(value); return NULL; } } i = cxMapIteratorValues(type->obj_fields); } return value; }