|
Csilk 0.2.1
A lightweight, high-performance C HTTP web framework
|
#include <stdbool.h>#include <stddef.h>#include <stdint.h>#include "cJSON.h"

Go to the source code of this file.
Data Structures | |
| struct | csilk_field_desc_t |
| Descriptor for a single field in a reflected struct. More... | |
| struct | csilk_reflect_entry_t |
| Registration entry for a reflected type. More... | |
Macros | |
| #define | CSILK_USER_TYPE_MAP |
| User-extensible type-name mapping. | |
| #define | csilk_type_name(x) |
| Map a C expression's type to its reflected string name. | |
| #define | csilk_marshal(ptr) csilk_json_marshal(csilk_type_name(*(ptr)), ptr) |
| Convenience macro to serialise a reflected struct to a JSON string. | |
| #define | csilk_unmarshal(json, ptr) csilk_json_unmarshal(csilk_type_name(*(ptr)), json, ptr) |
| Convenience macro to deserialise a JSON string into a reflected struct. | |
| #define | CSILK_META_EXPAND(struct_type, field, type_enum, size, arr_len, is_ptr, nested_name) {#field, type_enum, offsetof(struct_type, field), size, arr_len, is_ptr, nested_name}, |
| Internal helper: expand a single field into a csilk_field_desc_t initialiser. | |
| #define | CSILK_REGISTER_REFLECT(struct_type, map_macro) |
| Automatically register a struct for reflection at program startup. | |
Typedefs | |
| typedef void(* | csilk_reflect_foreach_cb) (const char *name, const csilk_reflect_entry_t *entry, void *user_data) |
| Callback type for csilk_reflect_foreach. | |
Enumerations | |
| enum | csilk_field_type_t { CSILK_TYPE_INT8 , CSILK_TYPE_UINT8 , CSILK_TYPE_INT16 , CSILK_TYPE_UINT16 , CSILK_TYPE_INT32 , CSILK_TYPE_UINT32 , CSILK_TYPE_INT64 , CSILK_TYPE_UINT64 , CSILK_TYPE_FLOAT , CSILK_TYPE_DOUBLE , CSILK_TYPE_BOOL , CSILK_TYPE_STRING , CSILK_TYPE_STRUCT } |
| Supported C data types for struct field reflection. More... | |
Functions | |
| void | csilk_reflect_init (void) |
| Initialise the reflection subsystem. | |
| void | csilk_reflect_register (const char *name, const csilk_field_desc_t *fields, size_t count) |
| Manually register a struct type for reflection. | |
| const csilk_reflect_entry_t * | csilk_reflect_find (const char *name) |
| Look up a registered type by name. | |
| void | csilk_reflect_foreach (csilk_reflect_foreach_cb cb, void *user_data) |
| Iterate over all registered reflection types. | |
| char * | csilk_json_marshal (const char *type_name, const void *ptr) |
| Serialise a reflected struct to a JSON string. | |
| int | csilk_json_unmarshal (const char *type_name, const char *json_str, void *ptr) |
| Deserialise a JSON string into a reflected struct. | |
| struct csilk_field_desc_s |
Descriptor for a single field in a reflected struct.
Forward declaration for the field descriptor struct.
Each field in a registered struct produces one of these descriptors, typically via the CSILK_META_EXPAND macro. The array of descriptors is NULL-terminated (sentinel entry with all-zero fields).
During marshalling, the engine walks the field descriptor array, reads offset bytes from the struct base, and converts the value according to type. During unmarshalling, JSON values are type-checked and written to the same offset. Nested structs (CSILK_TYPE_STRUCT) are resolved lazily by name at marshal/unmarshal time, allowing forward references.
| Data Fields | ||
|---|---|---|
| size_t | array_length |
Number of elements for fixed-size C arrays (0 = scalar fields or pointer fields). |
| bool | is_pointer |
True if the field is a pointer type (char* or struct pointer). Affects how the field is read/written. |
| const char * | json_key |
JSON key name for this field (used during marshal/unmarshal; e.g., "user_name"). |
| const char * | nested_type_name |
For CSILK_TYPE_STRUCT fields, the registered type name of the nested struct (resolved lazily at marshalling time to support forward declarations). NULL for non-struct fields. |
| size_t | offset |
Byte offset of this field from the struct base address (computed via offsetof). |
| size_t | size |
Size in bytes of one element (sizeof(field_type)). For arrays this is the element size, not the total. |
| csilk_field_type_t | type |
Data type enumerator (see csilk_field_type_t). |
| struct csilk_reflect_entry_t |
Registration entry for a reflected type.
Stored in an internal hash map. Populated via csilk_reflect_register or automatically via the CSILK_REGISTER_REFLECT macro.
| #define csilk_marshal | ( | ptr | ) | csilk_json_marshal(csilk_type_name(*(ptr)), ptr) |
Convenience macro to serialise a reflected struct to a JSON string.
Automatically deduces the type name via csilk_type_name(*(ptr)).
| ptr | Pointer to a registered struct instance. |
| #define CSILK_META_EXPAND | ( | struct_type, | |
| field, | |||
| type_enum, | |||
| size, | |||
| arr_len, | |||
| is_ptr, | |||
| nested_name | |||
| ) | {#field, type_enum, offsetof(struct_type, field), size, arr_len, is_ptr, nested_name}, |
Internal helper: expand a single field into a csilk_field_desc_t initialiser.
Used by the map macro passed to CSILK_REGISTER_REFLECT. Each invocation produces one array element.
| struct_type | The owning struct type name. |
| field | The field name. |
| type_enum | csilk_field_type_t enum value for this field. |
| size | sizeof() the field's type. |
| arr_len | Array element count (0 for scalar/pointer). |
| is_ptr | Non-zero if the field is a pointer type. |
| nested_name | Registered type name for CSILK_TYPE_STRUCT fields (ignored for other types). |
| #define CSILK_REGISTER_REFLECT | ( | struct_type, | |
| map_macro | |||
| ) |
Automatically register a struct for reflection at program startup.
Generates a static array of csilk_field_desc_t from the map_macro and registers it via a GCC constructor function (runs before main()). This means no explicit initialisation call is needed — types are available as soon as the program starts.
| struct_type | The struct type name (used as the registration key in the reflection hash map and for generating internal symbol names). |
| map_macro | A macro that applies CSILK_META_EXPAND to each field. Must produce exactly one CSILK_META_EXPAND(struct_type, field, type_enum, size, arr_len, is_ptr, nested_name) call per field. |
| #define csilk_type_name | ( | x | ) |
Map a C expression's type to its reflected string name.
Uses C11 _Generic dispatch. Extend with CSILK_USER_TYPE_MAP for user-defined types.
| x | Expression whose static type determines the returned name. |
| #define csilk_unmarshal | ( | json, | |
| ptr | |||
| ) | csilk_json_unmarshal(csilk_type_name(*(ptr)), json, ptr) |
Convenience macro to deserialise a JSON string into a reflected struct.
Automatically deduces the type name via csilk_type_name(*(ptr)).
| json | NUL-terminated JSON string. |
| ptr | Pointer to a registered struct instance (must be pre-allocated). |
| #define CSILK_USER_TYPE_MAP |
User-extensible type-name mapping.
Define CSILK_USER_TYPE_MAP before including csilk_reflect.h to add custom type-to-string mappings via _Generic. The default map handles char* and const char* as "string".
| typedef void(* csilk_reflect_foreach_cb) (const char *name, const csilk_reflect_entry_t *entry, void *user_data) |
Callback type for csilk_reflect_foreach.
Invoked once per registered type.
| name | The registered type name. |
| entry | The type descriptor entry. |
| user_data | Opaque pointer forwarded from csilk_reflect_foreach. |
| enum csilk_field_type_t |
Supported C data types for struct field reflection.
Each enumerator corresponds to a C type that the reflection system can read/write when marshalling to or from JSON.
| char * csilk_json_marshal | ( | const char * | type_name, |
| const void * | ptr | ||
| ) |
Serialise a reflected struct to a JSON string.
Walks the field descriptors for type_name and produces a compact JSON string (no extra whitespace). String fields are properly escaped.
| type_name | Registered type name of the struct. |
| ptr | Pointer to the struct instance to serialise. |
Serialise a reflected struct to a JSON string.
| int csilk_json_unmarshal | ( | const char * | type_name, |
| const char * | json_str, | ||
| void * | ptr | ||
| ) |
Deserialise a JSON string into a reflected struct.
Parses the JSON and populates the struct fields according to the registered field descriptors. Numeric type checking and range clamping are performed where possible.
| type_name | Registered type name of the target struct. | |
| json_str | NUL-terminated JSON string to parse. | |
| [out] | ptr | Pointer to the struct instance to populate (must already be allocated and zero-initialised). |
Deserialise a JSON string into a reflected struct.
| const csilk_reflect_entry_t * csilk_reflect_find | ( | const char * | name | ) |
Look up a registered type by name.
| name | Type name string. |
name has not been registered.Look up a registered type by name.
Searches the global registry for a type matching name.
| name | Type name to find (case-sensitive). |
| void csilk_reflect_foreach | ( | csilk_reflect_foreach_cb | cb, |
| void * | user_data | ||
| ) |
Iterate over all registered reflection types.
Calls cb for each type in the registration table. Safe to call at any point — types registered via CSILK_REGISTER_REFLECT are available via GCC constructor functions that run before main().
| cb | Callback invoked for each registered type (must not be NULL). |
| user_data | Opaque pointer forwarded to every cb invocation. |
Iterate over all registered reflection types.
Collects type names into a temporary array while holding the registry lock, then releases the lock and invokes the callback for each name. This two-phase approach avoids deadlocks when the callback itself calls back into reflection APIs (e.g., csilk_reflect_find()).
| cb | Callback invoked once per registered type. |
| user_data | Opaque pointer passed through to the callback. |
| void csilk_reflect_init | ( | void | ) |
Initialise the reflection subsystem.
Sets up internal data structures (mutexes for thread-safe registration). Safe to call multiple times — subsequent calls are no-ops.
Initialise the reflection subsystem.
Creates the global registry mutex. Idempotent — safe to call multiple times. Automatically called by csilk_server_new() and other entry points.
| void csilk_reflect_register | ( | const char * | name, |
| const csilk_field_desc_t * | fields, | ||
| size_t | count | ||
| ) |
Manually register a struct type for reflection.
Types registered with this function are immediately available for marshal/unmarshal operations. The name must be unique.
| name | Type name string (must remain valid for the lifetime of the program — typically a string literal). |
| fields | NULL-terminated array of csilk_field_desc_t. |
| count | Number of valid entries in fields (excluding the NULL-sentinel terminator). |
Manually register a struct type for reflection.
Adds a type name and its field descriptors to the global registry. Once registered, the type can be serialized/deserialized to/from JSON via csilk_json_marshal() / csilk_json_unmarshal(). The CSILK_REGISTER_REFLECT() macro generates the field array and calls this function automatically.
| name | Type name string (e.g., "my_request_t"). Must remain valid for the lifetime of the registration. |
| fields | Array of csilk_field_desc_t describing each struct field. |
| count | Number of fields in the array. |