C serialization library: Function reference

See also: README

Translators

Fields

Serialization

Logging

Strings

Types

Internal

Translators

ser_tra_t * ser_new_tra(const char * id, const size_t size, ser_tra_t * att)

Makes a new translator called id for a structure size bytes large. If att is non-NULL the new translator will be attached to the end of that list of translators.

Returns a pointer to the new translator or NULL on error.

void ser_del_tra(ser_tra_t * tra)

Deletes the translator tra and all translators linked after it.

ser_tra_t * ser_new_dyn_array(const char * id, const char * type,
                              const int ref, const size_t size, ser_tra_t * att)

Makes a new translator called id that will be a dynamic (variable-size, i.e. a pointer) array of type. If att is non-NULL the new translator will be attached to the end of that list of translators.

Note: other translators referencing id needs an array count field to function properly.

Returns a pointer to the new translator or NULL on error.

ser_tra_t * ser_new_nullterm_array(const char * id, const char * type,
                                   const int ref, ser_tra_t * att)

Makes a new translator called id that will be a null-terminated array of type. If att is non-NULL the new translator will be attached to the end of that list of translators.

Returns a pointer to the new translator or NULL on error.

char * ser_meta_tra(ser_tra_t * tra)

Serializes translators. This function sets up translators for ser_tra_t and ser_field_t; i.e. it describes the structure of the translators themselves. If tra is provided the translators in this list will be serialized, otherwise the meta translators will be serialized.

Returns the serialized translator(s).

void ser_tra_list(ser_tra_t * tra)

Prints (to stderr) the fields in tra and all linked translators.

ser_tra_t * ser_find_tra(ser_tra_t * tra, const char * id)

Given the linked list of translators tra, finds the one called id.

Fields

ser_field_t * ser_new_field(ser_tra_t * tra, const char * type, const int ref,
                            const char * tag, const size_t offset)

Adds field tag to the translator tra. The field will be serialized as type. If ref is non-zero it will be made a reference. offset is the number of bytes between the start of the structure and the start of the member field; it is recommended to find this using offsetof().

The field will not be created if a field with the same tag exists in the translator or if the translator is defined as an array, i.e. it was created with ser_new_dyn_array() or ser_new_null_array() (see ser_tra_t.atype).

Returns a pointer to the new field, or NULL on error.

void ser_del_field(ser_tra_t * tra, ser_field_t * field)

Deletes field from tra and all fields linked after it.

ser_field_t * ser_find_field(ser_tra_t * tra, const char * id, const char * tag)

Given the translator list tra, looks up field tag in translator id.

Returns a pointer to the field or NULL if it could not be found. Both translator id and field tag must match; if there is another translator with the same field tag it will not be detected.

Serialization

char * ser_ialize(ser_tra_t * tra, char * type, void * first,
                  void (*log_func)(char *), uint16_t options)

Serializes first as type, using tra as translator list (a translator for type must exist in tra). Extra options can be given as a bitmask in options; see SER_OPT_* for details.

If log_func is provided it will be called with error messages if serialization fails. If it is NULL output will be muted. See ser_def_log(). Implement your own to redirect output to a custom logging console, etc.

Returns a string (which must be freed after use) describing the structure in human-readable format. Returns NULL on error.

void * ser_parse(ser_tra_t * first_tra, const char * expected_type,
                 char * s, void (*log_func)(char*))

Parses (inflates) s according to the translator list first_tra. expected_type should specify the type to expect for index #1; if it differs the process will fail.

If log_func is provided it will be called with error messages if inflation fails. If it is NULL output will be muted. See ser_def_log().

Returns a pointer to element #1 (correspondingly passed as first to ser_ialize()) or NULL on failure.

Logging

void ser_def_log(char * msg)

Default error logger. Implement your own and pass it to ser_ialize() and ser_parse() to redirect errors to your custom logging console, message boxes, etc.

void ser_null_log(char * msg)

Discards messages. This is where "muted" output ends up.

Strings

char * ser_preformat(char * s)

Creates a copy of s suitable for ser_parse. Semicolons, commas, braces outside quotes will be padded with spaces.

Returns the padded string or NULL on error.

char * ser_escape_str(char * s)

Creates a copy of s with quotes, backslashes and non-printable characters preceded by backslashes. Newline characters (ASCII 10) will be represented as \n, quotes as \", backslashes as \\ and non-printable characters as \xnn, where nn are hexadecimal digits.

Returns the escaped string or NULL on error.

char * ser_unescape_str(char * s)

Creates a copy of s with escaped characters converted back to their real values; reverse of ser_escape_str.

Returns the restored string or NULL on error.

char ser_hex2char(char * s)

Converts two hexadecimal digits to a number. s should point to a string with two characters 0-F (case insensitive); these will be converted to a value in the 0-255 range.

Returns the converted value.

Types

bool ser_is_signed(const char * type)

Checks if type is a signed numeric type.

size_t ser_field_size(ser_job_t * job, const char * type, const int ref)

Returns the size (in bytes) of type. If ref is nonzero it will instead return the size of a pointer to such an array (which really will be sizeof(void*)).

bool ser_is_primitive(const char * s)

Returns if s is a type that can be serialized natively (without a user-provided translator).

bool ser_valid_type(ser_tra_t * tra, char * s)

Returns if s is a valid type (primitive or present as a translator in translator list tra).

Internal

size_t ser_nullterm_len(void * thing, char * type)

Returns the length of a null-terminated array of type starting at thing. Elements will be counted up to (and including) the first that is zero.

void ser_list_holders(ser_job_t * job)

Lists the holders in job; what they point to, size, type, element count, redirections, etc.

void ser_ptr_overlap(ser_job_t * job)

Scans job for holders whose pointers overlap. If a holder is found whose destination would fit within a another structure, it will be marked as a redirected structure. This information will be used by ser_ialize().

Returns non-zero on success, zero on failure.

bool ser_job_realloc_result(ser_job_t * job, const int len)

Reallocates jobs output buffer to len characters. One extra byte will be reserved for the terminator; this does not need to be included in len.

Returns true on success, false on failure.

bool ser_job_cat(ser_job_t * job, char * s)

Concatenates s to jobs result buffer. Note that the buffer might be moved and old pointers to it invalidated.

Returns true on success, false on failure (bad pointers, memory could not be allocated, etc).

size_t ser_assign_holder(ser_job_t * job, void * thing, size_t size)

Finds the index of thing in jobs list of pointer holders, or adds it if it isn't found. If the list is too small to hold the addition it will be resized aggressively.

Returns the index assigned or 0 on error.

size_t ser_find_holder(ser_job_t * job, void * thing, size_t size)

Returns the index of the holder in job pointing to thing, or 0 if it could not be found.

See also: ser_assign_holder

bool ser_write_primitive(ser_job_t * job, const size_t holder,
                         const char * type, void * field_ptr)

Serializes a primitive value and adds it to jobs output buffer. holder is the index of the value; type is self-explanatory and field_ptr is the start of the memory to be translated.

Returns true on success, false on failure.

bool ser_dump(ser_job_t * job, char * type, void * thing)

Converts thing to human-readable text, according to the translator for type present in job. The result will be appended to the output buffer in job.

Returns true if thing could be translated properly, false if something went wrong.

bool ser_write_struct(ser_job_t * job, ser_tra_t * tra,
                      size_t ptr_index, void * thing, const int anon)

Adds to jobs output buffer a textual representation of the structure located at thing serialized using tra.

ptr_index should be the index of the holder pointing to thing or zero if thing does not have any memory allocation of its own (e.g. it is an anonymous sub-structure).

Returns true if everything went o-kay, false if something broke.

bool ser_set_holder_elements(ser_job_t * job, size_t holder_index, size_t elements)

Sets the number of elements for holder holder_index in job to elements.

Returns true on success, false on error (in which case holder_index was probably outside the allocated range).

bool ser_element_count(ser_job_t * job, ser_tra_t * tra,
                       ser_field_t * field, void * thing, void * start)

Looks for a holder in job that points to start and a field in tra that is the array count field of field (same name, prepended by an at sign). If both are found the holder element count will be set to the array count field value. thing is the structure referencing start; i.e. thing has one or more pointers to start that are also registered in the translator.

Returns true if the field was found and the holder count set, false if it could not be found or an error occured.

bool ser_write_array(ser_job_t * job, ser_tra_t * tra, ser_field_t * field,
                     void * array_start, size_t elements)

Writes elements fields, starting at array_start, to jobs output buffer. tra should be the type of container structure and field the type of output.

Returns true if the array could be written, false on error.

void ser_set_custom_handler(ser_tra_t * tra,
                            int (*func_ptr)(ser_job_t *, ser_tra_t *, void *))

Sets the custom output handler for tra to func_ptr. There can only be one such function per translator; if multiple calls are needed (for OO-like functionality) a wrapper function is needed.

long ser_numeric_cast(void * ptr, char * type)

Attempts to convert the data at ptr into a type number. No type or overflow checking is performed.

Returns the number (0 on error).

ser_field_t * ser_find_array_count(ser_tra_t * tra, char * array_tag)

Returns a pointer to any field in tra that is an array count for array_tag; i.e. one that is array_tag prepended with a .

bool ser_follow_ptrs(ser_job_t * job, size_t holder_index,
                     ser_tra_t * thing_tra, void * thing)

Searches thing for reference fields and adds their destination to jobs list of holders. If holder_index is non-zero the type specified for that holder will be used as translator, otherwise thing_tra must be provided.

Returns true on success, false on utter, catastrophic failure.

bool ser_write_value(ser_job_t * job, const char * type,
                     const int ref, void * field_ptr)

Appends to jobs output buffer a textual representation of field_ptr as a type. If the field is a reference, it will also register in jobs "holder" list what type of translation to use for the destination structure in the future.

Returns true if the value could be written properly, false on error.

bool ser_job_realloc_holders(ser_job_t * job, const int n)

Resizes the holder list of job to n elements. If the list is expanded, new entries will be cleared.

Returns true on success, false on failure.

void ser_clear_holder(ser_holder_t * holder)

Clears holder. This will not free any pointers associated with it, only reset them to neutral values.

bool ser_read_primitive(ser_job_t * job, const long id, const char * type)

Reads a primitive type from jobs parse buffer. The result will be stored in holder id after allocating sufficient memory to stort the type.

Returns true on success, false on failure.

void * ser_resolve_subst_ptr(ser_job_t * job, const size_t hi,
                             const char * tag, const size_t ai,
                             char ** type, bool * ref)

Returns a pointer to the start of field tag (array offset ai) in the structure held by holder index hi in job. Returns NULL if it cannot be found.

If type is provided the pointer at that location will be pointed to a string with the type of the destination. This is in use somewhere else in the program and should not be freed.

If ref is provided it will be set to true if the resolved address points to a reference field or false if it is a normal value or the beginning of a struct (possibly anonymous).

bool ser_check_subst_ptrs(ser_job_t * job)

Checks that all substitution pointers in job resolve to valid locations (the holder, field and array index (if >0) must exist).

ser_subst_ptr_t * ser_add_subst_ptr(ser_job_t * job, const size_t d_hi,
                                    const char * d_tag, const size_t d_ai)

Creates a new substitution pointer structure in job. When dereferenced, the subst pointer will resolve to holder[@d_hi@].@d_tag@[@d_ai@]. Any pointer that wants to use this location should point themselves at the structure returned.

bool ser_restore_pointers(ser_job_t * job)

Goes through every structure held by job and resolves reference indices to real pointers.

For example, any reference to #2 will be replaced by the address in holder[2]->start.

Returns true on success, false on failure.

bool ser_restore_ptr(ser_job_t * job, ser_holder_t * holder,
                     ser_tra_t * tra, ser_field_t * field)

Resolves the destination holder for a substitution pointer structure located at field in holder. tra should be the translator for holder. If tra or field is an array all elements will be processed.

Returns true on success, false on failure.

void * ser_replace_ptr(ser_job_t * job,
                       const size_t holder_index,
                       const char * tag)

Returns a pointer to field tag in the structure held by holder holder_index in job; NULL if no such field could be found (it's missing in the id translator) or any other error occurs.

bool ser_read_struct(ser_job_t * job, const long id, ser_tra_t * thing_tra)

Reads a structure from jobs input buffer and assigns it to holder id. The structure will be parsed according to thing_tra.

Returns true on success, false on error.

bool ser_read_struct_internal(ser_job_t * job, ser_holder_t * holder,
                              ser_tra_t * thing_tra, void * ptr)

Assumes jobs input parsing is at the start of a structure (after the opening brace). Reads the structure into ptr according to thing_tra. If holder is non-NULL, it will be used to reallocate ptr (if needed; this is only used for dynamic arrays - do not pass it when reading static arrays or embedded structs).

Returns true on success, false on error.

bool ser_expect(ser_job_t * job, ser_tok_t expected)

Reads a token from jobs input buffer. Returns true if it is of type expected, otherwise false. If it is of another type a message will be sent to jobs log_func. The output will be discarded (this is mostly useful for detecting braces and terminators).

bool ser_read_value(ser_job_t * job, const char * type, ser_tok_t r,
                    void * where, char * token, long int value)

Reads token into where. r is the type of token provided and must match the field. If the field is a numeric value will be used instead of token.

Returns true on success, false on failure.

ser_tok_t ser_ntok(ser_job_t * job, char ** dest, long int * value)

Extracts a new token from jobs parse buffer. Returns the type of token, ser_tok_any if it can't determine what it is. dest will be repointed to the string representation of the token. value will be set to the numerical value, if it can be determined.

On error, ser_tok_err is returned and a message will be printed using the log_func of job. In these cases, it is usually not necessary to print any other error messages.

ser_field_t * ser_field_by_offset(ser_tra_t * tra, const size_t offset)

Returns the field in tra with offset offset, or NULL if none is found.

void * ser_blank_struct(ser_tra_t * tra)

Allocates and blanks memory for a structure of type tra.

char * ser_token_code(const ser_tok_t token)

Returns a pointer to a string describing token.