Created
January 1, 2017 06:22
-
-
Save youz/2e34413d8b934401f907a0f131b98983 to your computer and use it in GitHub Desktop.
garray
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sqlite3ext.h> | |
SQLITE_EXTENSION_INIT1 | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <assert.h> | |
static int g_arr_size; | |
static int* g_arr; | |
static void gaSizeOfIntFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { | |
sqlite3_result_int64(context, sizeof(int)); | |
} | |
static void gaInitFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { | |
assert(argc == 1); | |
if (sqlite3_value_type(argv[0]) != SQLITE_INTEGER) { | |
sqlite3_result_error(context, "len must be an integer ", -1); | |
return; | |
} | |
int64_t len = sqlite3_value_int64(argv[0]); | |
if (len <= 0 || len > 0x1000000) { | |
sqlite3_result_error(context, "len must be in range [1 .. 2^24]", -1); | |
return; | |
} | |
free(g_arr); | |
g_arr = calloc((size_t)len, sizeof(int)); | |
if (!g_arr) { | |
sqlite3_result_error_nomem(context); | |
g_arr_size = 0; | |
} else { | |
sqlite3_result_int64(context, len); | |
g_arr_size = len; | |
} | |
} | |
static void gaRefFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { | |
assert(argc == 1); | |
if (g_arr_size == 0) { | |
sqlite3_result_error(context, "garray is not initialized", -1); | |
return; | |
} | |
if (sqlite3_value_type(argv[0]) != SQLITE_INTEGER) { | |
sqlite3_result_error(context, "index must be an integer", -1); | |
return; | |
} | |
int64_t idx = sqlite3_value_int64(argv[0]); | |
if (idx < 0 || idx >= g_arr_size) { | |
sqlite3_result_error(context, "range error", -1); | |
} else { | |
sqlite3_result_int64(context, g_arr[idx]); | |
} | |
} | |
static void gaSetFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { | |
assert(argc == 2); | |
if (g_arr_size == 0) { | |
sqlite3_result_error(context, "garray is not initialized", -1); | |
return; | |
} | |
if (sqlite3_value_type(argv[0]) != SQLITE_INTEGER) { | |
sqlite3_result_error(context, "idx must be an integer", -1); | |
return; | |
} | |
if (sqlite3_value_type(argv[1]) != SQLITE_INTEGER) { | |
sqlite3_result_error(context, "value must be an integer", -1); | |
} | |
int64_t idx = sqlite3_value_int64(argv[0]); | |
int64_t set_value = sqlite3_value_int64(argv[1]); | |
if (idx < 0 || idx >= g_arr_size) { | |
sqlite3_result_error(context, "range error", -1); | |
} else { | |
g_arr[idx] = (int)set_value; | |
sqlite3_result_int64(context, g_arr[idx]); | |
} | |
} | |
static void gaReleaseFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { | |
free(g_arr); | |
g_arr = NULL; | |
g_arr_size = 0; | |
sqlite3_result_int64(context, 0); | |
} | |
#ifdef _WIN32 | |
__declspec(dllexport) | |
#endif | |
int sqlite3_extension_init( | |
sqlite3 *db, | |
char **pzErrMsg, | |
const sqlite3_api_routines *pApi | |
){ | |
int rc = SQLITE_OK; | |
SQLITE_EXTENSION_INIT2(pApi); | |
g_arr = NULL; | |
g_arr_size = 0; | |
sqlite3_create_function_v2(db, "gainit", 1, SQLITE_UTF8, 0, gaInitFunc, 0, 0, NULL); | |
sqlite3_create_function_v2(db, "garef", 1, SQLITE_UTF8, 0, gaRefFunc, 0, 0, NULL); | |
sqlite3_create_function_v2(db, "gaset", 2, SQLITE_UTF8, 0, gaSetFunc, 0, 0, NULL); | |
sqlite3_create_function_v2(db, "garelease", 0, SQLITE_UTF8, 0, gaReleaseFunc, 0, 0, NULL); | |
sqlite3_create_function_v2(db, "gasizeofint", 0, SQLITE_UTF8, 0, gaSizeOfIntFunc, 0, 0, NULL); | |
return rc; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment