summaryrefslogtreecommitdiff
path: root/support/dktools/dk4dbitw.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4dbitw.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk4dbitw.ctr')
-rw-r--r--support/dktools/dk4dbitw.ctr366
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;
+}
+