diff --git a/README.md b/README.md index c5fa5ee..ffa250f 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,13 @@ LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.txt) or commercial license opti Contains source and library (shared object) code built from: - [litehelpers / Android-sqlite-evcore-native-driver-free](https://github.com/litehelpers/Android-sqlite-evcore-native-driver-free) - GPL v3 or commercial license options - [SQLite (sqlite.org)](https://sqlite.org/) - public domain - -Also included in Android JAR build: - [brodybits / sqlite3-regexp-cached](https://github.com/brodybits/sqlite3-regexp-cached) (based on by Alexey Tourbin, public domain) - [brodybits / sqlite3-base64](https://github.com/brodybits/sqlite3-base64) (Unlicense, public domain) - [brodybits / libb64-encode](https://github.com/brodybits/libb64-encode) (based on by Chris Venter, public domain) This project provides the following dependencies needed to build Cordova SQLite evcore plugin versions: - `sqlite3.h`, `sqlite3.c` - SQLite `3.15.2` amalgamation needed to build iOS and Windows versions +- [libb64-encode](https://github.com/brodybits/libb64-encode), [sqlite3-base64](https://github.com/brodybits/sqlite3-base64), and [sqlite3-regexp-cached](https://github.com/brodybits/sqlite3-regexp-cached) source for iOS/macOS/Windows platform versions - `evcore-native-driver.jar` - Android-sqlite-evcore-native-driver-free NDK JAR built with SQLite `3.15.2` amalgamation, with the following option flags: - `-DSQLITE_TEMP_STORE=2` - `-DSQLITE_THREADSAFE=2` diff --git a/libb64-encode/LICENSE b/libb64-encode/LICENSE new file mode 100644 index 0000000..a6b5606 --- /dev/null +++ b/libb64-encode/LICENSE @@ -0,0 +1,29 @@ +Copyright-Only Dedication (based on United States law) +or Public Domain Certification + +The person or persons who have associated work with this document (the +"Dedicator" or "Certifier") hereby either (a) certifies that, to the best of +his knowledge, the work of authorship identified is in the public domain of the +country from which the work is published, or (b) hereby dedicates whatever +copyright the dedicators holds in the work of authorship identified below (the +"Work") to the public domain. A certifier, moreover, dedicates any copyright +interest he may have in the associated work, and for these purposes, is +described as a "dedicator" below. + +A certifier has taken reasonable steps to verify the copyright status of this +work. Certifier recognizes that his good faith efforts may not shield him from +liability if in fact the work certified is not in the public domain. + +Dedicator makes this dedication for the benefit of the public at large and to +the detriment of the Dedicator's heirs and successors. Dedicator intends this +dedication to be an overt act of relinquishment in perpetuity of all present +and future rights under copyright law, whether vested or contingent, in the +Work. Dedicator understands that such relinquishment of all rights includes +the relinquishment of all rights to enforce (by lawsuit or otherwise) those +copyrights in the Work. + +Dedicator recognizes that, once placed in the public domain, the Work may be +freely reproduced, distributed, transmitted, used, modified, built upon, or +otherwise exploited by anyone for any purpose, commercial or non-commercial, +and in any way, including by methods that have not yet been invented or +conceived. \ No newline at end of file diff --git a/libb64-encode/README.md b/libb64-encode/README.md new file mode 100644 index 0000000..2c9757a --- /dev/null +++ b/libb64-encode/README.md @@ -0,0 +1,27 @@ +libb64: Base64 Encoding C Routine +================================= + +From project: (latest CVS source from ) + +LICENSE: +-------- + +Public domain + +Authors: +-------- + +- Chris Venter ([@gorb314](https://github.com/gorb314)) +- Christopher J. Brody ([@brodybits](https://github.com/brodybits)) + +Major changes: +-------------- + +- Use macro instead of function to encode each value +- Line breaks disabled by default +- Include fixed for iOS build + +Other versions: +--------------- + +- diff --git a/libb64-encode/cencode.c b/libb64-encode/cencode.c new file mode 100644 index 0000000..4ad917f --- /dev/null +++ b/libb64-encode/cencode.c @@ -0,0 +1,116 @@ +/* +cencoder.c - c source to a base64 encoding algorithm implementation + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ + +#include "cencode.h" + +#ifdef B64_ENCODE_LINE_BREAKS +const int CHARS_PER_LINE = 72; +#endif + +static const char * ENCODING_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +#define ENCODE_VALUE(value) (((value) < 0 || (value) > 63) ? '=' : (ENCODING_CHARS[(int)(value)])) + +void base64_init_encodestate(base64_encodestate* state_in) +{ + state_in->step = step_A; + state_in->result = 0; + state_in->stepcount = 0; +} + +char base64_encode_value(char value_in) +{ + return ENCODE_VALUE(value_in); +} + +int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) +{ + const char* plainchar = plaintext_in; + const char* const plaintextend = plaintext_in + length_in; + char* codechar = code_out; + char result; + char fragment; + + result = state_in->result; + + switch (state_in->step) + { + while (1) + { + case step_A: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_A; + return codechar - code_out; + } + fragment = *plainchar++; + result = (fragment & 0x0fc) >> 2; + *codechar++ = ENCODE_VALUE(result); + result = (fragment & 0x003) << 4; + case step_B: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_B; + return codechar - code_out; + } + fragment = *plainchar++; + result |= (fragment & 0x0f0) >> 4; + *codechar++ = ENCODE_VALUE(result); + result = (fragment & 0x00f) << 2; + case step_C: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_C; + return codechar - code_out; + } + fragment = *plainchar++; + result |= (fragment & 0x0c0) >> 6; + *codechar++ = ENCODE_VALUE(result); + result = (fragment & 0x03f) >> 0; + *codechar++ = ENCODE_VALUE(result); + + ++(state_in->stepcount); +#ifdef B64_ENCODE_LINE_BREAKS + if (state_in->stepcount == CHARS_PER_LINE/4) + { + *codechar++ = '\n'; + state_in->stepcount = 0; + } +#endif + } + } + /* control should not reach here */ + return codechar - code_out; +} + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in) +{ + char* codechar = code_out; + + switch (state_in->step) + { + case step_B: + *codechar++ = ENCODE_VALUE(state_in->result); + *codechar++ = '='; + *codechar++ = '='; + break; + case step_C: + *codechar++ = ENCODE_VALUE(state_in->result); + *codechar++ = '='; + break; + case step_A: + break; + } +#ifdef B64_ENCODE_LINE_BREAKS + *codechar++ = '\n'; +#endif + + return codechar - code_out; +} diff --git a/libb64-encode/cencode.h b/libb64-encode/cencode.h new file mode 100644 index 0000000..0443f8e --- /dev/null +++ b/libb64-encode/cencode.h @@ -0,0 +1,64 @@ +/* + +cencode.h - c header for a base64 encoding algorithm + + + +This is part of the libb64 project, and has been placed in the public domain. + +For details, see http://sourceforge.net/projects/libb64 + +*/ + + + +#ifndef BASE64_CENCODE_H + +#define BASE64_CENCODE_H + + + +typedef enum + +{ + + step_A, step_B, step_C + +} base64_encodestep; + + + +typedef struct + +{ + + base64_encodestep step; + + char result; + + int stepcount; + +} base64_encodestate; + + + +void base64_init_encodestate(base64_encodestate* state_in); + + + +char base64_encode_value(char value_in); + + + +int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); + + + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in); + + + +#endif /* BASE64_CENCODE_H */ + + + diff --git a/package.json b/package.json index e8728bf..09c5d49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordova-sqlite-evcore-free-dependencies", - "version": "0.8.0", + "version": "0.8.1", "description": "Cordova sqlite evcore free dependencies", "main": "404.js", "scripts": { diff --git a/sqlite3-base64/README.md b/sqlite3-base64/README.md new file mode 100644 index 0000000..87aab6a --- /dev/null +++ b/sqlite3-base64/README.md @@ -0,0 +1,27 @@ +# sqlite3-base64 + +Add BASE64 encoding function to sqlite3. + +**LICENSE:** UNLICENSE (public domain) ref: + +## External dependencies + +- `cencode.h`, `cencode.c` from (public domain) +- `sqlite3.h` + +**NOTE:** `cencode.h` must be in the build path. + +## Sample usage + +After opening sqlite3 database: + +```c +sqlite3_base64_init(db); +``` + +Then the following SQL: +```sql +SELECT BASE64(X'010203') +``` + +returns the following value: `AQID` diff --git a/sqlite3-base64/sqlite3_base64.c b/sqlite3-base64/sqlite3_base64.c new file mode 100644 index 0000000..a03cfb5 --- /dev/null +++ b/sqlite3-base64/sqlite3_base64.c @@ -0,0 +1,39 @@ +#include "sqlite3_base64.h" + +#include "cencode.h" + +#include +#include + +static +void sqlite3_base64(sqlite3_context * context, int argc, sqlite3_value ** argv) { + if (argc < 1) { + sqlite3_result_null(context); + } else { + // THANKS FOR GUIDANCE: + // http://www.sqlite.org/cgi/src/artifact/43916c1d8e6da5d1 + // (src/func.c:hexFunc) + sqlite3_value * first = argv[0]; + + const uint8_t * blob = sqlite3_value_blob(first); + + const int blen = sqlite3_value_bytes(first); + + char * b64 = sqlite3_malloc(blen*2); + + base64_encodestate es; + base64_init_encodestate(&es); + + { + const int len1 = base64_encode_block(blob, blen, b64, &es); + const int len = len1 + base64_encode_blockend(b64 + len1, &es); + + sqlite3_result_text(context, b64, len, sqlite3_free); + } + } +} + +int sqlite3_base64_init(sqlite3 * db) +{ + return sqlite3_create_function_v2(db, "BASE64", 1, SQLITE_ANY | SQLITE_DETERMINISTIC, NULL, sqlite3_base64, NULL, NULL, NULL); +} diff --git a/sqlite3-base64/sqlite3_base64.h b/sqlite3-base64/sqlite3_base64.h new file mode 100644 index 0000000..2f2810f --- /dev/null +++ b/sqlite3-base64/sqlite3_base64.h @@ -0,0 +1,11 @@ +#include "sqlite3.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int sqlite3_base64_init(sqlite3 * db); + +#ifdef __cplusplus +} +#endif diff --git a/sqlite3-regexp-cached/LICENSE b/sqlite3-regexp-cached/LICENSE new file mode 100644 index 0000000..9eb7f03 --- /dev/null +++ b/sqlite3-regexp-cached/LICENSE @@ -0,0 +1,9 @@ +Adapted by Christopher J. Brody . + +Based on sqlite3-pcre: +Written by Alexey Tourbin . + +The author has dedicated the code to the public domain. Anyone is free +to copy, modify, publish, use, compile, sell, or distribute the original +code, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. diff --git a/sqlite3-regexp-cached/README.md b/sqlite3-regexp-cached/README.md new file mode 100644 index 0000000..e96ef63 --- /dev/null +++ b/sqlite3-regexp-cached/README.md @@ -0,0 +1,26 @@ +# sqlite3-regexp-cached + +Provide REGEXP function for SQLite3 with regex caching, using BSD REGEX functions. + +Default cache size: 16 + +`SQLITE3_REGEXP_CACHE_SIZE` may be defined to change the regex cache size. + +Based on: + +Sample usage (opening database): +```c +sqlite3 * db; +int rc; +const char * err; + +rc = sqlite3_open_v2("my.db", &db, SQLITE_OPEN_CREATE, NULL); + +if (rc == 0) { + rc = sqlite3_regexp_init(db, &err); +} +``` + +**LICENSE:** public domain + +Other GitHub version of sqlite3-pcre: diff --git a/sqlite3-regexp-cached/sqlite3_regexp.c b/sqlite3-regexp-cached/sqlite3_regexp.c new file mode 100644 index 0000000..03c0d42 --- /dev/null +++ b/sqlite3-regexp-cached/sqlite3_regexp.c @@ -0,0 +1,170 @@ +/* + * Adapted by Christopher J. Brody . + * + * Based on sqlite3-pcre: + * Written by Alexey Tourbin . + * + * The author has dedicated the code to the public domain. Anyone is free + * to copy, modify, publish, use, compile, sell, or distribute the original + * code, either in source code form or as a compiled binary, for any purpose, + * commercial or non-commercial, and by any means. + */ + +#include "sqlite3_regexp.h" + +#include +#include + +/* NOTE: + * It should be possible to use a different regex implementation by changing + * the include, cached_regex_t, and static regexp_compile, regexp_free, and + * regexp_exec functions below. + */ +#include + +typedef regex_t cached_regex_t; + +#ifdef SQLITE3_REGEXP_EXT +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#endif + +typedef struct { + char *s; + cached_regex_t r; +} cache_entry; + +/* May be defined to add per-context or global locking if necessary */ +#define CACHE_LOCK(ctx) ; +#define CACHE_UNLOCK(ctx) ; + +#ifdef SQLITE3_REGEXP_CACHE_SIZE +const static int cache_size = SQLITE3_REGEXP_CACHE_SIZE; +#else +const static int cache_size = 16; +#endif + +const static int regex_compile_flags = REG_EXTENDED; + +static inline +int regexp_compile(cached_regex_t * pr, const char * re) { + return regcomp(pr, re, regex_compile_flags); +} + +static inline +void regexp_free(cached_regex_t * pr) { + regfree(pr); +} + +static inline +int regexp_exec(cached_regex_t * pr, const char * str) { + return regexec(pr, str, 0, 0, 0); +} + +static +void sqlite3_regexp(sqlite3_context *ctx, int argc, sqlite3_value **argv) +{ + const char *re, *str; + + cached_regex_t * pr; + + if (argc != 2) { + // quick failure: + sqlite3_result_int(ctx, 0); + return; + } + + re = (const char *) sqlite3_value_text(argv[0]); + if (!re) { + sqlite3_result_error(ctx, "no regexp", -1); + return; + } + + str = (const char *) sqlite3_value_text(argv[1]); + if (!str) { + sqlite3_result_error(ctx, "no string", -1); + return; + } + + /* simple LRU cache */ + { + int i; + int found = 0; + cache_entry *cache = sqlite3_user_data(ctx); + + if (!cache) { + // quick failure (should not happen): + sqlite3_result_int(ctx, 0); + return; + } + + for (i = 0; i < cache_size && cache[i].s; i++) + if (strcmp(re, cache[i].s) == 0) { + found = 1; + break; + } + if (found) { + if (i > 0) { + cache_entry c = cache[i]; + memmove(cache + 1, cache, i * sizeof(cache_entry)); + cache[0] = c; + } + } + else { + cache_entry c; + + CACHE_LOCK(ctx); + + if (regexp_compile(&c.r, re) != 0) { + char *e2 = sqlite3_mprintf("%s: invalid", re); + sqlite3_result_error(ctx, e2, -1); + sqlite3_free(e2); + return; + } + + c.s = strdup(re); + if (!c.s) { + sqlite3_result_error(ctx, "strdup: ENOMEM", -1); + regexp_free(&c.r); + return; + } + i = cache_size - 1; + if (cache[i].s) { + free(cache[i].s); + regexp_free(&cache[i].r); + } + + CACHE_UNLOCK(ctx); + + memmove(cache + 1, cache, i * sizeof(cache_entry)); + cache[0] = c; + } + pr = &cache[0].r; + } + + { + int rc = regexp_exec(pr, str); + sqlite3_result_int(ctx, rc == 0); + return; + } +} + +int sqlite3_regexp_init(sqlite3 * db, const char ** err) +{ + cache_entry *cache = calloc(cache_size, sizeof(cache_entry)); + + if (!cache) { + *err = "calloc: ENOMEM"; + return 1; + } + + return sqlite3_create_function_v2(db, "REGEXP", 2, SQLITE_ANY | SQLITE_DETERMINISTIC, cache, sqlite3_regexp, NULL, NULL, NULL); +} + +#ifdef SQLITE3_REGEXP_EXT +int sqlite3_extension_init(sqlite3 *db, char **err, const sqlite3_api_routines *api) +{ + SQLITE_EXTENSION_INIT2(api) + return sqlite3_regexp_init(db, err); +} +#endif diff --git a/sqlite3-regexp-cached/sqlite3_regexp.h b/sqlite3-regexp-cached/sqlite3_regexp.h new file mode 100644 index 0000000..2b4e85c --- /dev/null +++ b/sqlite3-regexp-cached/sqlite3_regexp.h @@ -0,0 +1,11 @@ +#include "sqlite3.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int sqlite3_regexp_init(sqlite3 * db, const char ** err); + +#ifdef __cplusplus +} +#endif