static jbyteArray getBlob_native(JNIEnv* env, jobject object, jint row, jint column) { int32_t err; CursorWindow * window = GET_WINDOW(env, object); LOG_WINDOW("Getting blob for %d,%d from %p", row, column, window); field_slot_t field; err = window->read_field_slot(row, column, &field); if (err != 0) { throwExceptionWithRowCol(env, row, column); return NULL; } uint8_t type = field.type; if (type == FIELD_TYPE_BLOB || type == FIELD_TYPE_STRING) { jbyteArray byteArray = env->NewByteArray(field.data.buffer.size); LOG_ASSERT(byteArray, "Native could not create new byte[]"); env->SetByteArrayRegion(byteArray, 0, field.data.buffer.size, (const jbyte*)window->offsetToPtr(field.data.buffer.offset)); return byteArray; } else if (type == FIELD_TYPE_INTEGER) { throw_sqlite3_exception(env, "INTEGER data in getBlob_native "); } else if (type == FIELD_TYPE_FLOAT) { throw_sqlite3_exception(env, "FLOAT data in getBlob_native "); } else if (type == FIELD_TYPE_NULL) { // do nothing } else { throwUnknowTypeException(env, type); } return NULL; }
static jstring getString_native(JNIEnv* env, jobject object, jint row, jint column) { int32_t err; CursorWindow * window = GET_WINDOW(env, object); LOG_WINDOW("Getting string for %d,%d from %p", row, column, window); field_slot_t field; err = window->read_field_slot(row, column, &field); if (err != 0) { throwExceptionWithRowCol(env, row, column); return NULL; } uint8_t type = field.type; if (type == FIELD_TYPE_STRING) { uint32_t size = field.data.buffer.size; if (size > 0) { #if WINDOW_STORAGE_UTF8 // Pass size - 1 since the UTF8 is null terminated and we don't want a null terminator on the UTF16 string String16 utf16((char const *)window->offsetToPtr(field.data.buffer.offset), size - 1); return env->NewString((jchar const *)utf16.string(), utf16.size()); #else return env->NewString((jchar const *)window->offsetToPtr(field.data.buffer.offset), size / 2); #endif } else { return env->NewStringUTF(""); } } else if (type == FIELD_TYPE_INTEGER) { int64_t value; if (window->getLong(row, column, &value)) { char buf[32]; snprintf(buf, sizeof(buf), "%lld", value); return env->NewStringUTF(buf); } return NULL; } else if (type == FIELD_TYPE_FLOAT) { double value; if (window->getDouble(row, column, &value)) { char buf[32]; //selete the print way by code to impove the precision if (((value > 0.0001) && (value < 1000000)) || ((value < -0.0001) && (value > -1000000))) snprintf(buf, sizeof(buf), "%lf", value); else snprintf(buf, sizeof(buf), "%e", value); return env->NewStringUTF(buf); } return NULL; } else if (type == FIELD_TYPE_NULL) { return NULL; } else if (type == FIELD_TYPE_BLOB) { throw_sqlite3_exception(env, "Unable to convert BLOB to string"); return NULL; } else { throwUnknowTypeException(env, type); return NULL; } }
static jdouble getDouble_native(JNIEnv* env, jobject object, jint row, jint column) { int32_t err; CursorWindow * window = GET_WINDOW(env, object); LOG_WINDOW("Getting double for %d,%d from %p", row, column, window); field_slot_t field; err = window->read_field_slot(row, column, &field); if (err != 0) { throwExceptionWithRowCol(env, row, column); return 0.0; } uint8_t type = field.type; if (type == FIELD_TYPE_FLOAT) { double value; if (window->getDouble(row, column, &value)) { return value; } return 0.0; } else if (type == FIELD_TYPE_STRING) { uint32_t size = field.data.buffer.size; if (size > 0) { #if WINDOW_STORAGE_UTF8 return strtod((char const *)window->offsetToPtr(field.data.buffer.offset), NULL); #else String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2); char const * str = ascii.string(); return strtod(str, NULL); #endif } else { return 0.0; } } else if (type == FIELD_TYPE_INTEGER) { int64_t value; if (window->getLong(row, column, &value)) { return (double) value; } return 0.0; } else if (type == FIELD_TYPE_NULL) { return 0.0; } else if (type == FIELD_TYPE_BLOB) { throw_sqlite3_exception(env, "Unable to convert BLOB to double"); return 0.0; } else { throwUnknowTypeException(env, type); return 0.0; } }
static jdouble getDouble_native(JNIEnv* env, jobject object, jint row, jint column) { int32_t err; CursorWindow * window = GET_WINDOW(env, object); LOG_WINDOW("Getting double for %d,%d from %p", row, column, window); field_slot_t field; err = window->read_field_slot(row, column, &field); if (err != 0) { throwExceptionWithRowCol(env, row, column); return 0.0; } uint8_t type = field.type; if (type == FIELD_TYPE_FLOAT) { double value; if (window->getDouble(row, column, &value)) { return value; } return 0.0; } else if (type == FIELD_TYPE_STRING) { uint32_t size = field.data.buffer.size; if (size > 0) { double result; jstring data = env->NewString((const jchar*)window->offsetToPtr(field.data.buffer.offset), (jsize)size); const char* utf8data = env->GetStringUTFChars(data, NULL); result = strtod(utf8data, NULL); if(utf8data) env->ReleaseStringUTFChars(data, utf8data); if(data) env->DeleteLocalRef(data); return result; } else { return 0.0; } } else if (type == FIELD_TYPE_INTEGER) { int64_t value; if (window->getLong(row, column, &value)) { return (double) value; } return 0.0; } else if (type == FIELD_TYPE_NULL) { return 0.0; } else if (type == FIELD_TYPE_BLOB) { throw_sqlite3_exception(env, "Unable to convert BLOB to double"); return 0.0; } else { throwUnknowTypeException(env, type); return 0.0; } }