From 1355c16cd40405bdf817ef05bdcaf20b060dd0ce Mon Sep 17 00:00:00 2001 From: prpr Date: Sat, 24 Sep 2022 01:14:14 +0100 Subject: [PATCH] Add utf8conv function to decode/strip prefixes from database strings --- xconv.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/xconv.c b/xconv.c index b71e8da..70ae1eb 100644 --- a/xconv.c +++ b/xconv.c @@ -2,7 +2,6 @@ * xconv.c -- An SQLite3 C extension that uses libxconv to convert from * ISO 6937 to UTF-8. */ -#include #include #include #include @@ -22,28 +21,79 @@ sqlite_xconv(sqlite3_context *c, int argc, sqlite3_value **argv) return; } - dlen = strlen(src) + 20; + dlen = strlen(src) * 2 + 14; if (!(dst = (char *)malloc(dlen))) { sqlite3_result_error(c, "malloc() failed", -1); return; } - + if (!xconv(src, dst, dlen)) { free(dst); dst = strdup(src); } + + sqlite3_result_text(c, dst, -1, free); +} + +void +sqlite_utf8conv(sqlite3_context *c, int argc, sqlite3_value **argv) +{ + char *src, *dst; + + if (argc != 1 || !(src = (char *)sqlite3_value_text(argv[0]))) + { + sqlite3_result_error(c, "utf8conv requires 1 parameter", -1); + return; + } + + if (src[0] == 0x10) + { + if (src[1] == 'i' && src[2] == '7') + { + size_t dlen; + + src += 3; + dlen = strlen(src) * 2 + 14; + if (!(dst = (char *)malloc(dlen))) + { + sqlite3_result_error(c, "malloc() failed", -1); + return; + } + + if (!xconv(src, dst, dlen)) + { + free(dst); + dst = strdup(src); + } + } + else + dst = strdup(""); + } + else + { + if (*src < 0x20) + src += *src == 0x1F ? 2 : 1; + + dst = strdup(src); + } + sqlite3_result_text(c, dst, -1, free); } int sqlite3_xconv_init(sqlite3 *db, char **err, const sqlite3_api_routines *api) { - SQLITE_EXTENSION_INIT2(api); + int rc1, rc2; - return sqlite3_create_function(db, "xconv", 1, + SQLITE_EXTENSION_INIT2(api); + rc1 = sqlite3_create_function(db, "xconv", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, NULL, sqlite_xconv, NULL, NULL); + rc2 = sqlite3_create_function(db, "utf8conv", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC, NULL, + sqlite_utf8conv, NULL, NULL); + return rc1 != SQLITE_OK && rc2 != SQLITE_OK ? rc1 : SQLITE_OK; }