diff --git a/src/core/data.c b/src/core/data.c
index c71e3630e4f76dcf8d61fbb82370f818590b8b21..4e0fd779580f9dd734bf1211dc2769ca326a179f 100644 (file)
--- a/src/core/data.c
+++ b/src/core/data.c
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
#include "core/data.h"
+#include <inttypes.h>
+
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
}
} /* sdb_data_free_datum */
+size_t
+sdb_data_strlen(sdb_data_t *datum)
+{
+ if (! datum)
+ return 0;
+
+ switch (datum->type) {
+ case SDB_TYPE_INTEGER:
+ /* log(64) */
+ return 20;
+ case SDB_TYPE_DECIMAL:
+ /* XXX: -0xN.NNNNNNp+NNN */
+ return 42;
+ case SDB_TYPE_STRING:
+ if (! datum->data.string)
+ return 6; /* "NULL" */
+ /* in the worst case, each character needs to be escaped */
+ return 2 * strlen(datum->data.string) + 2;
+ case SDB_TYPE_DATETIME:
+ /* "YYYY-MM-DD HH:MM:SS +zzzz" */
+ return 27;
+ case SDB_TYPE_BINARY:
+ /* "\xNN" */
+ return 4 * datum->data.binary.length + 2;
+ }
+ return 0;
+} /* sdb_data_strlen */
+
+int
+sdb_data_format(sdb_data_t *datum, char *buf, size_t buflen, int quoted)
+{
+ char tmp[sdb_data_strlen(datum) + 1];
+ char *data = NULL;
+ int ret = -1;
+
+ size_t i, pos;
+
+ if ((! datum) || (! buf))
+ return -1;
+
+ switch (datum->type) {
+ case SDB_TYPE_INTEGER:
+ ret = snprintf(buf, buflen, "%"PRIi64, datum->data.integer);
+ break;
+ case SDB_TYPE_DECIMAL:
+ ret = snprintf(buf, buflen, "%a", datum->data.decimal);
+ break;
+ case SDB_TYPE_STRING:
+ if (! datum->data.string)
+ data = "NULL";
+ else {
+ pos = 0;
+ for (i = 0; i < strlen(datum->data.string); ++i) {
+ char byte = datum->data.string[i];
+
+ if ((byte == '\\') || (byte == '"')) {
+ tmp[pos] = '\\';
+ ++pos;
+ }
+ tmp[pos] = byte;
+ ++pos;
+ }
+ tmp[pos] = '\0';
+ data = tmp;
+ }
+ break;
+ case SDB_TYPE_DATETIME:
+ if (! sdb_strftime(tmp, sizeof(tmp), "%F %T %z",
+ datum->data.datetime))
+ return -1;
+ tmp[sizeof(tmp) - 1] = '\0';
+ data = tmp;
+ break;
+ case SDB_TYPE_BINARY:
+ pos = 0;
+ for (i = 0; i < datum->data.binary.length; ++i) {
+ int byte = (int)datum->data.binary.datum[i];
+ char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+ tmp[pos] = '\\';
+ tmp[pos + 1] = 'x';
+ pos += 2;
+
+ if (byte > 0xf) {
+ tmp[pos] = hex[byte >> 4];
+ ++pos;
+ }
+ tmp[pos] = hex[byte & 0xf];
+ ++pos;
+ }
+ tmp[pos] = '\0';
+ data = tmp;
+ break;
+ }
+
+ if (data) {
+ if (quoted == SDB_UNQUOTED)
+ ret = snprintf(buf, buflen, "%s", data);
+ else if (quoted == SDB_SINGLE_QUOTED)
+ ret = snprintf(buf, buflen, "'%s'", data);
+ else
+ ret = snprintf(buf, buflen, "\"%s\"", data);
+ }
+ buf[buflen - 1] = '\0';
+ return ret;
+} /* sdb_data_format */
+
/* vim: set tw=78 sw=4 ts=4 noexpandtab : */