diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4dbitw.ctr |
Initial commit
Diffstat (limited to 'support/dktools/dk4dbitw.ctr')
-rw-r--r-- | support/dktools/dk4dbitw.ctr | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/support/dktools/dk4dbitw.ctr b/support/dktools/dk4dbitw.ctr new file mode 100644 index 0000000000..5da31311ed --- /dev/null +++ b/support/dktools/dk4dbitw.ctr @@ -0,0 +1,366 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + + + +%% header + +/** @file dk4dbitw.h Text (wchar_t) in database. +*/ + +#ifndef DK4DBI_H_INCLUDED +#include <dk4dbi.h> +#endif + +#if DK4_HAVE_WCHAR_H +#ifndef WCHAR_H_INCLUDED +#include <wchar.h> +#define WCHAR_H_INCLUDED 1 +#endif +#endif + +/** Function used when traversing a simple database. + @param obj Object to modify during traversal. + @param k Current key. + @param v Current value. +*/ +typedef +int +dk4dbi_wc_traverse_fct_t( + void *obj, + const wchar_t *k, + const wchar_t *v +); + +#ifdef __cplusplus +extern "C" { +#endif + +/** Set text entry. + @param db Database to modify. + @param k Key text. + @param v Value text. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if db, k or vis NULL, + - DK4_E_SYNTAX<br> + if the database was opened read-only or k or v + is too long. + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in size calculation, + - DK4_E_NOT_SUPPORTED<br> + if db indicates an unsupported backend, + - DK4_E_NOT_FOUND<br> + if no record to delete was found, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + with mem.elsize and mem.nelem + set if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if modification of the database failed. +*/ +int +dk4dbi_wc_set( + dk4_dbi_t *db, + const wchar_t *k, + const wchar_t *v, + dk4_er_t *erp +); + +/** Retrieve text entry. + @param db Database to query. + @param k Key text. + @param vbuf Result buffer address. + @param vsz Pointer to size variable (in: size, out: used), + number of wchar_t. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if db, k or vbufis NULL or vsz is 0, + or the length of k exceeds the key size limit, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in size calculation, + - DK4_E_NOT_SUPPORTED<br> + if db indicates an unsupported backend, + - DK4_E_NOT_FOUND<br> + if no record was found for the key, + - DK4_E_BUFFER_TOO_SMALL<br> + if the destination buffer is too small. +*/ +int +dk4dbi_wc_get( + dk4_dbi_t *db, + const wchar_t *k, + wchar_t *vbuf, + size_t vsz, + dk4_er_t *erp +); + +/** Delete text entry. + @param db Database to modify. + @param k Key text. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if db or k is NULL, + - DK4_E_SYNTAX<br> + if the database is opened read-only or the length of + k exceeds the key size limit, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in size calculation, + - DK4_E_NOT_SUPPORTED<br> + if db indicates an unsupported backend, + - DK4_E_WRITE_FAILED<br> + if modification of the database failed, + - DK4_E_NOT_FOUND<br> + if no record for the specified key is in the database. +*/ +int +dk4dbi_wc_del( + dk4_dbi_t *db, + const wchar_t *k, + dk4_er_t *erp +); + +/** Traverse database, apply function to all text entries. + @param db Database to traverse. + @param obj Object to modify during traversal. + @param fct Function to apply to all text entries. + @return 1 on success, 0 on error (database traversed), + -1 on error (traversal aborted). +*/ +int +dk4dbi_wc_traverse( + dk4_dbi_t *db, + void *obj, + dk4dbi_wc_traverse_fct_t *fct +); + +#ifdef __cplusplus +} +#endif + +%% module + +#include "dk4conf.h" + +#include "dk4strw.h" +#include "dk4dbitw.h" +#include "dk4maasz.h" + + + +$!trace-include + + + +/** Object for database traversal. +*/ +typedef struct { + void *obj; /**< Object for string traversal. */ + dk4dbi_wc_traverse_fct_t *fct; /**< String traversal function. */ +} dk4dbi_wc_traversal_object_t; + + + +int +dk4dbi_wc_del( + dk4_dbi_t *db, + const wchar_t *k, + dk4_er_t *erp +) +{ + dk4_er_t er; + size_t ks = 0; + int back = 0; + if ((NULL != db) && (NULL != k)) { + dk4error_init(&er); + ks = dk4ma_size_t_mul( + sizeof(wchar_t), + dk4ma_size_t_add(1, dk4strw_len(k), &er), + &er + ); + if (DK4_E_NONE == er.ec) { + back = dk4dbi_delete(db, k, ks, erp); + } else { + dk4error_copy(erp, &er); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +int +dk4dbi_wc_set( + dk4_dbi_t *db, + const wchar_t *k, + const wchar_t *v, + dk4_er_t *erp +) +{ + dk4_er_t er; + size_t ks = 0; + size_t vs = 0; + int back = 0; + + if ((NULL != db) && (NULL != k)) { + if (NULL != v) { + dk4error_init(&er); + ks = dk4ma_size_t_mul( + sizeof(wchar_t), + dk4ma_size_t_add(1, dk4strw_len(k), &er), + &er + ); + vs = dk4ma_size_t_mul( + sizeof(wchar_t), + dk4ma_size_t_add(1, dk4strw_len(v), &er), + &er + ); + if (DK4_E_NONE == er.ec) { + back = dk4dbi_set(db, k, ks, v, vs, erp); + } else { + dk4error_copy(erp, &er); + } + } else { + back = dk4dbi_wc_del(db, k, erp); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +int +dk4dbi_wc_get( + dk4_dbi_t *db, + const wchar_t *k, + wchar_t *vbuf, + size_t vsz, + dk4_er_t *erp +) +{ + dk4_er_t er; + size_t ks = 0; + size_t ressz = 0; + int back = 0; + if ((NULL != vbuf) && (0 < vsz)) { *vbuf = L'\0'; } + if ((NULL != db) && (NULL != k) && (NULL != vbuf) && (0 < vsz)) { + dk4error_init(&er); + ressz = dk4ma_size_t_mul(sizeof(wchar_t), vsz, &er); + ks = dk4ma_size_t_mul( + sizeof(wchar_t), + dk4ma_size_t_add(1, dk4strw_len(k), &er), + &er + ); + if (DK4_E_NONE == er.ec) { + if (0 != dk4dbi_get(db, k, ks, vbuf, &ressz, erp)) { + if (0 == (ressz % sizeof(wchar_t))) { + ressz = ressz / sizeof(wchar_t); + if (0 < ressz) { + if (L'\0' == vbuf[ressz - 1]) { + back = 1; + } else { + if (ressz < vsz) { + vbuf[ressz] = L'\0'; + back = 1; + } else { + *vbuf = L'\0'; + dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); + } + } + } else { + *vbuf = L'\0'; + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } + } else { + *vbuf = L'\0'; + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } + } + } else { + dk4error_copy(erp, &er); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +/** Function to traverse a simple database. + The function must check the kb, ks, vb and vs arguments + for validity, they are passed as found by the backend + functions (this means pointers may be NULL, sizes may be 0). + @param Object modified during traversal, may be NULL. + @param kb Key data. + @param ks Key size. + @param vb Value data. + @param vs Value size. + @return 1 on success, 0 on error (can continue), -1 on error (abort). +*/ +static +int +dk4dbi_wc_internal_traverse( + void *obj, + const void *kb, + size_t ks, + const void *vb, + size_t vs +) +{ + dk4dbi_wc_traversal_object_t *myobj; /* Passed from dk4dbi_traverse() */ + const wchar_t *pk; /* Key pointer */ + const wchar_t *pv; /* Value pointer */ + int back = 0; + + if ((NULL != obj) && (NULL != kb) && (NULL != vb)) { + if ((0 == (ks % sizeof(wchar_t))) && (0 == (vs % sizeof(wchar_t)))) { + ks = ks / sizeof(wchar_t); + vs = vs / sizeof(wchar_t); + if ((0 < ks) && (0 < vs)) { + pk = (const wchar_t *)kb; + pv = (const wchar_t *)vb; + if (('\0' == pk[ks - 1]) && ('\0' == pv[vs - 1])) { + myobj = (dk4dbi_wc_traversal_object_t *)obj; + back = (*(myobj->fct))(myobj->obj, pk, pv); + } + } + } + } + return back; +} + + +int +dk4dbi_wc_traverse( + dk4_dbi_t *db, + void *obj, + dk4dbi_wc_traverse_fct_t *fct +) +{ + dk4dbi_wc_traversal_object_t myobj; /* Passed to dk4dbi_traverse */ + int back = -1; + + if ((NULL != db) && (NULL != fct)) { + myobj.obj = obj; + myobj.fct = fct; + back = dk4dbi_traverse(db, &myobj, dk4dbi_wc_internal_traverse); + } + return back; +} + |