int sqlite3_register_mm_cipher(sqlite3 *db, const unsigned char *key) { UErrorCode status = U_ZERO_ERROR; int sqlite_err; mm_cipher_context_t *ctx; // XXX: if we failed to load ICU functions, just skip initializing. if (!ucnv_openCCSID) return SQLITE_OK; ctx = sqlite3_malloc(sizeof(mm_cipher_context_t)); if (!ctx) return SQLITE_NOMEM; sqlite_err = SQLITE_ERROR; // open converter using CCSID instead of converter name to hide "BOCU-1" string. ctx->cnv = ucnv_openCCSID(1214, UCNV_IBM, &status); if (!ctx->cnv) goto error; memcpy(ctx->key, key, 16); ctx->ref_count = 3; sqlite_err = sqlite3_create_function_v2(db, "mmenc", 1, SQLITE_ANY, ctx, mmenc_func, NULL, NULL, mm_func_destroy); if (sqlite_err != SQLITE_OK) goto error; sqlite_err = sqlite3_create_function_v2(db, "mmdec", 1, SQLITE_ANY, ctx, mmdec_func, NULL, NULL, mm_func_destroy); if (sqlite_err != SQLITE_OK) goto error; sqlite_err = sqlite3_create_function_v2(db, "mm_cipher_key", 1, SQLITE_ANY, ctx, mm_cipher_key_func, NULL, NULL, mm_func_destroy); if (sqlite_err != SQLITE_OK) goto error; return SQLITE_OK; error: if (ctx) sqlite3_free(ctx); return sqlite_err; }
UErrorCode convsample_40() { printf("\n\n==============================================\n" "Sample 40: C: convert data02.bin from cp37 to UTF16 [data40.utf16]\n"); FILE *f; FILE *out; int32_t count; char inBuf[BUFFERSIZE]; const char *source; const char *sourceLimit; UChar *uBuf; UChar *target; UChar *targetLimit; int32_t uBufSize = 0; UConverter *conv = NULL; UErrorCode status = U_ZERO_ERROR; uint32_t inbytes=0, total=0; f = fopen("data02.bin", "rb"); if(!f) { fprintf(stderr, "Couldn't open file 'data02.bin' (cp37 data file).\n"); return U_FILE_ACCESS_ERROR; } out = fopen("data40.utf16", "wb"); if(!out) { fprintf(stderr, "Couldn't create file 'data40.utf16'.\n"); fclose(f); return U_FILE_ACCESS_ERROR; } // **************************** START SAMPLE ******************* conv = ucnv_openCCSID(37, UCNV_IBM, &status); assert(U_SUCCESS(status)); uBufSize = (BUFFERSIZE/ucnv_getMinCharSize(conv)); printf("input bytes %d / min chars %d = %d UChars\n", BUFFERSIZE, ucnv_getMinCharSize(conv), uBufSize); uBuf = (UChar*)malloc(uBufSize * sizeof(UChar)); assert(uBuf!=NULL); // grab another buffer's worth while((!feof(f)) && ((count=fread(inBuf, 1, BUFFERSIZE , f)) > 0) ) { inbytes += count; // Convert bytes to unicode source = inBuf; sourceLimit = inBuf + count; do { target = uBuf; targetLimit = uBuf + uBufSize; ucnv_toUnicode( conv, &target, targetLimit, &source, sourceLimit, NULL, feof(f)?TRUE:FALSE, /* pass 'flush' when eof */ /* is true (when no more data will come) */ &status); if(status == U_BUFFER_OVERFLOW_ERROR) { // simply ran out of space - we'll reset the target ptr the next // time through the loop. status = U_ZERO_ERROR; } else { // Check other errors here. assert(U_SUCCESS(status)); // Break out of the loop (by force) } // Process the Unicode // Todo: handle UTF-16/surrogates assert(fwrite(uBuf, sizeof(uBuf[0]), (target-uBuf), out) == (size_t)(target-uBuf)); total += (target-uBuf); } while (source < sourceLimit); // while simply out of space } printf("%d bytes in, %d UChars out.\n", inbytes, total); // ***************************** END SAMPLE ******************** ucnv_close(conv); fclose(f); fclose(out); printf("\n"); return U_ZERO_ERROR; }