Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
JSONContext Struct Reference

#include <JSONContext.h>

Overview

A context for JSON serialization and deserialization.

Create one instance per operation. Errors encountered during parsing or type-binding accumulate in errors.

Definition at line 72 of file JSONContext.h.

Inheritance diagram for JSONContext:
Object

Properties

Arrayerrors
 Errors accumulated during the operation.
 
Object object
 The superclass.
 
- Properties inherited from Object
Classclazz
 Every instance of Object begins with a pointer to its Class.
 
unsigned int magic
 A header to allow introspection of Object types.
 

Methods

Class_JSONContext (void)
 The JSONContext archetype.
 
DatadataFromObject (JSONContext *self, const ident obj, int options)
 Serializes an Objectively object graph to JSON Data.
 
DatadataFromStruct (JSONContext *self, const JSONProperties *properties, const ident instance)
 Serializes a C struct instance to a JSON object.
 
DatadataFromStructs (JSONContext *self, const JSONProperties *properties, const ident instances, size_t count)
 Serializes an array of C struct instances to a JSON array.
 
DictionarydictionaryFromStruct (JSONContext *self, const JSONProperties *properties, const ident instance)
 Serializes a C struct instance to a Dictionary.
 
JSONContextinit (JSONContext *self)
 Initializes a JSONContext.
 
ident objectFromData (JSONContext *self, const Data *data, int options)
 Parses a JSON Data buffer into an Objectively object graph.
 
bool structFromData (JSONContext *self, const JSONProperties *properties, const Data *data, ident instance)
 Deserializes a top-level JSON object into a C struct.
 
bool structFromDictionary (JSONContext *self, const JSONProperties *properties, const Dictionary *dictionary, ident instance)
 Deserializes a Dictionary into a C struct.
 
size_t structsFromArray (JSONContext *self, const JSONProperties *properties, const Array *array, ident instances, size_t count)
 Deserializes an Array of Dictionaries into an array of C structs.
 
size_t structsFromData (JSONContext *self, const JSONProperties *properties, const Data *data, ident instances, size_t count)
 Deserializes a top-level JSON array into an array of C structs.
 
- Methods inherited from Object
Class_Object (void)
 The Object archetype.
 
Objectcopy (const Object *self)
 Creates a shallow copy of this Object.
 
void dealloc (Object *self)
 Frees all resources held by this Object.
 
Stringdescription (const Object *self)
 
int hash (const Object *self)
 
Objectinit (Object *self)
 Initializes this Object.
 
bool isEqual (const Object *self, const Object *other)
 Tests equality of the other Object.
 
bool isKindOfClass (const Object *self, const Class *clazz)
 Tests for Class hierarchy membership.
 

Protected Attributes

JSONContextInterface * interface
 The interface.
 
- Protected Attributes inherited from Object
ObjectInterface * interface
 The interface.
 

Property Details

◆ errors

Array* JSONContext::errors

Errors accumulated during the operation.

Lazily allocated; NULL until the first error is recorded.

Definition at line 89 of file JSONContext.h.

◆ interface

JSONContextInterface* JSONContext::interface
protected

The interface.

Definition at line 83 of file JSONContext.h.

◆ object

Object JSONContext::object

The superclass.

Definition at line 77 of file JSONContext.h.

Method Details

◆ _JSONContext()

Class * _JSONContext ( void  )

The JSONContext archetype.

Returns
The JSONContext Class.

Definition at line 821 of file JSONContext.c.

821 {
822 static Class *clazz;
823 static Once once;
824
825 do_once(&once, {
826 clazz = _initialize(&(const ClassDef) {
827 .name = "JSONContext",
828 .superclass = _Object(),
829 .instanceSize = sizeof(JSONContext),
830 .interfaceOffset = offsetof(JSONContext, interface),
831 .interfaceSize = sizeof(JSONContextInterface),
833 .destroy = destroy,
834 });
835 });
836
837 return clazz;
838}
static void initialize(Class *clazz)
Definition Array.c:710
static void destroy(Class *clazz)
Definition Boole.c:102
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:86
long Once
The Once type.
Definition Once.h:37
#define do_once(once, block)
Executes the given block at most one time.
Definition Once.h:43
ClassDefs are passed to _initialize via an archetype to initialize a Class.
Definition Class.h:41
The runtime representation of a Class.
Definition Class.h:95
A context for JSON serialization and deserialization.
Definition JSONContext.h:72
JSONContextInterface * interface
The interface.
Definition JSONContext.h:83
Class * clazz
Every instance of Object begins with a pointer to its Class.
Definition Object.h:55
Class * _Object(void)
The Object archetype.
Definition Object.c:136

◆ dataFromObject()

Data * dataFromObject ( JSONContext self,
const ident  obj,
int  options 
)

Serializes an Objectively object graph to JSON Data.

Parameters
selfThe JSONContext.
objThe root Object to serialize.
optionsA bitwise-or of JSONWriteOptions.
Returns
The resulting JSON Data.

Definition at line 584 of file JSONContext.c.

584 {
585
586 (void) self;
587
588 if (obj) {
589 JSONWriter writer = {
590 .data = $(alloc(Data), init),
591 .options = options
592 };
593
594 writeElement(&writer, obj);
595
596 return (Data *) writer.data;
597 }
598
599 return NULL;
600}
#define obj
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:176
static void writeElement(JSONWriter *writer, const ident obj)
Writes any JSON element to writer.
static int options(RESTClient *self, const char *url, Data **data)
Definition RESTClient.c:217
Data buffers.
Definition Data.h:50
JSONContext * init(JSONContext *self)
Initializes a JSONContext.
Internal state for JSON text generation.
Definition JSONContext.c:94
Data * data
Definition JSONContext.c:95

◆ dataFromStruct()

Data * dataFromStruct ( JSONContext self,
const JSONProperties properties,
const ident  instance 
)

Serializes a C struct instance to a JSON object.

Parameters
selfThe JSONContext.
propertiesThe JSONProperties for the struct type.
instancePointer to the struct instance.
Returns
The resulting JSON Data.

Definition at line 606 of file JSONContext.c.

606 {
607
608 Dictionary *dict = $(self, dictionaryFromStruct, properties, instance);
609 Data *data = dataFromObject(self, dict, 0);
610 release(dict);
611 return data;
612}
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Definition Class.c:195
static Data * data(void)
Definition Data.c:286
Key-value stores.
Definition Dictionary.h:60
Dictionary * dictionaryFromStruct(JSONContext *self, const JSONProperties *properties, const ident instance)
Serializes a C struct instance to a Dictionary.
Data * dataFromObject(JSONContext *self, const ident obj, int options)
Serializes an Objectively object graph to JSON Data.

◆ dataFromStructs()

Data * dataFromStructs ( JSONContext self,
const JSONProperties properties,
const ident  instances,
size_t  count 
)

Serializes an array of C struct instances to a JSON array.

Parameters
selfThe JSONContext.
propertiesThe JSONProperties for the struct type.
instancesPointer to the first instance.
countThe number of instances to serialize.
Returns
The resulting JSON Data (a top-level JSON array), or NULL if count is zero.

Definition at line 618 of file JSONContext.c.

618 {
619
620 if (!count) {
621 return NULL;
622 }
623
624 Array *array = $(alloc(Array), init);
625
626 for (size_t i = 0; i < count; i++) {
627 const ident instance = instances + i * properties->size;
628 Dictionary *dict = $(self, dictionaryFromStruct, properties, instance);
629 $(array, addObject, dict);
630 release(dict);
631 }
632
633 Data *data = dataFromObject(self, array, 0);
634 release(array);
635 return data;
636}
static void addObject(Array *self, const ident obj)
Definition Array.c:181
static Array * array(void)
Definition Array.c:234
void * ident
The identity type, similar to Objective-C id.
Definition Types.h:49
Arrays.
Definition Array.h:56
size_t size
The struct size, i.e. sizeof(Struct).

◆ dictionaryFromStruct()

Dictionary * dictionaryFromStruct ( JSONContext self,
const JSONProperties properties,
const ident  instance 
)

Serializes a C struct instance to a Dictionary.

Parameters
selfThe JSONContext.
propertiesThe JSONProperties for the struct type.
instancePointer to the struct instance.
Returns
A new Dictionary, or NULL on error.

Definition at line 641 of file JSONContext.c.

641 {
642
643 if (!properties || !instance) {
644 return NULL;
645 }
646
647 Dictionary *dict = $(alloc(Dictionary), init);
648
649 for (const JSONProperty *p = properties->properties; p->key; p++) {
650 if (!p->serializer) {
651 continue;
652 }
653
654 const ident field = instance + p->offset;
655 ident val = p->serializer(properties, p, field, p->data, self);
656
657 if (val) {
658 String *key = $$(String, stringWithCharacters, p->key);
659 $(dict, setObjectForKey, val, key);
660 release(key);
661 release(val);
662 }
663 }
664
665 return (Dictionary *) dict;
666}
static void setObjectForKey(Dictionary *self, const ident obj, const ident key)
Definition Dictionary.c:634
static String * stringWithCharacters(const char *chars)
Definition String.c:349
const JSONProperty * properties
The NULL-terminated JSONProperty array.
Describes the JSON binding strategy for a single field of a C struct.
UTF-8 strings.
Definition String.h:69

◆ init()

JSONContext * init ( JSONContext self)

Initializes a JSONContext.

Parameters
selfThe JSONContext.
Returns
The initialized JSONContext.

Definition at line 671 of file JSONContext.c.

671 {
672 return (JSONContext *) super(Object, self, init);
673}
#define super(type, obj, method,...)
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46

◆ objectFromData()

ident objectFromData ( JSONContext self,
const Data data,
int  options 
)

Parses a JSON Data buffer into an Objectively object graph.

Parameters
selfThe JSONContext.
dataThe JSON Data to parse.
optionsReserved; pass 0.
Returns
The root Object (Dictionary or Array), or NULL on parse error.

Definition at line 679 of file JSONContext.c.

679 {
680
681 if (data && data->length) {
682 JSONReader reader = {
683 .data = data,
684 .options = options
685 };
686
687 ident obj = readElement(&reader);
688
689 if (reader.error) {
690 addError(self, 1, NULL, "JSON parse error");
691 release(obj);
692 return NULL;
693 }
694
695 return obj;
696 }
697
698 return NULL;
699}
static ident readElement(JSONReader *reader)
Reads any JSON element from reader.
static void addError(JSONContext *self, int code, const char *key, const char *description)
Records an error on the context.
Definition JSONContext.c:65
size_t length
The length of bytes.
Definition Data.h:76
Internal state for JSON text parsing.
const Data * data

◆ structFromData()

bool structFromData ( JSONContext self,
const JSONProperties properties,
const Data data,
ident  instance 
)

Deserializes a top-level JSON object into a C struct.

Parameters
selfThe JSONContext.
propertiesThe JSONProperties for the struct type.
dataThe JSON Data containing a top-level object.
instancePointer to the caller-allocated struct to populate.
Returns
true if parsing succeeded and all recognized fields were bound without type errors.

Definition at line 757 of file JSONContext.c.

757 {
758
759 ident obj = $(self, objectFromData, data, 0);
760 if (!obj || !$((Object *) obj, isKindOfClass, _Dictionary())) {
761 release(obj);
762 return false;
763 }
764
765 const bool ok = structFromDictionary(self, properties, (Dictionary *) obj, instance);
766
767 release(obj);
768 return ok;
769}
Class * _Dictionary(void)
Definition Dictionary.c:762
bool structFromDictionary(JSONContext *self, const JSONProperties *properties, const Dictionary *dictionary, ident instance)
Deserializes a Dictionary into a C struct.
ident objectFromData(JSONContext *self, const Data *data, int options)
Parses a JSON Data buffer into an Objectively object graph.
bool isKindOfClass(const Object *self, const Class *clazz)
Tests for Class hierarchy membership.
Definition Object.c:101

◆ structFromDictionary()

bool structFromDictionary ( JSONContext self,
const JSONProperties properties,
const Dictionary dictionary,
ident  instance 
)

Deserializes a Dictionary into a C struct.

Parameters
selfThe JSONContext.
propertiesThe JSONProperties for the struct type.
dictionaryThe source Dictionary.
instancePointer to the caller-allocated struct to populate.
Returns
true if all recognized fields were bound without type errors.

Definition at line 704 of file JSONContext.c.

704 {
705
706 if (!properties || !dictionary || !instance) {
707 return false;
708 }
709
710 bool ok = true;
711
712 for (const JSONProperty *p = properties->properties; p->key; p++) {
713 if (!p->deserializer) {
714 continue;
715 }
716
717 String *key = $$(String, stringWithCharacters, p->key);
718 const Object *val = $(dictionary, objectForKey, key);
719 release(key);
720
721 if (!val) {
722 continue;
723 }
724
725 if (!p->deserializer(properties, p, val, instance + p->offset, self)) {
726 addError(self, 2, p->key, "type mismatch");
727 ok = false;
728 }
729 }
730
731 return ok;
732}
static Dictionary * dictionary(void)
Definition Dictionary.c:242
static ident objectForKey(const Dictionary *self, const ident key)
Definition Dictionary.c:439

◆ structsFromArray()

size_t structsFromArray ( JSONContext self,
const JSONProperties properties,
const Array array,
ident  instances,
size_t  count 
)

Deserializes an Array of Dictionaries into an array of C structs.

Parameters
selfThe JSONContext.
propertiesThe JSONProperties for the element type.
arrayThe source Array of Dictionary objects.
instancesPointer to a caller-allocated buffer of at least count structs.
countThe capacity of the instances buffer.
Returns
The number of structs actually written.

Definition at line 737 of file JSONContext.c.

737 {
738
739 if (!properties || !array || !instances || !count) {
740 return 0;
741 }
742
743 const size_t n = min(array->count, count);
744
745 for (size_t i = 0; i < n; i++) {
747 $(self, structFromDictionary, properties, dictionary, instances + i * properties->size);
748 }
749
750 return n;
751}
static ident objectAtIndex(const Array *self, size_t index)
Definition Array.c:578
#define cast(type, obj)
Safely cast obj to type.
Definition Class.h:182
#define min(a, b)
Definition Types.h:159
size_t count
The count of elements.
Definition Array.h:72

◆ structsFromData()

size_t structsFromData ( JSONContext self,
const JSONProperties properties,
const Data data,
ident  instances,
size_t  count 
)

Deserializes a top-level JSON array into an array of C structs.

Parameters
selfThe JSONContext.
propertiesThe JSONProperties for the element type.
dataThe JSON Data containing a top-level array.
instancesPointer to a caller-allocated buffer of at least count structs.
countThe capacity of the instances buffer.
Returns
The number of structs actually written.

Definition at line 775 of file JSONContext.c.

775 {
776
777 ident obj = objectFromData(self, data, 0);
778 if (!obj || !$((Object *) obj, isKindOfClass, _Array())) {
779 release(obj);
780 return 0;
781 }
782
783 const size_t n = structsFromArray(self, properties, (Array *) obj, instances, count);
784
785 release(obj);
786 return n;
787}
Class * _Array(void)
Definition Array.c:760
size_t structsFromArray(JSONContext *self, const JSONProperties *properties, const Array *array, ident instances, size_t count)
Deserializes an Array of Dictionaries into an array of C structs.

The documentation for this struct was generated from the following files: