static jbyteArray nativeGetBlob(JNIEnv* env, jclass clazz, jlong windowPtr, jint row, jint column) { CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); LOG_WINDOW("Getting blob for %d,%d from %p", row, column, window); CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column); if (!fieldSlot) { throwExceptionWithRowCol(env, row, column); return NULL; } int32_t type = window->getFieldSlotType(fieldSlot); if (type == CursorWindow::FIELD_TYPE_BLOB || type == CursorWindow::FIELD_TYPE_STRING) { size_t size; const void* value = window->getFieldSlotValueBlob(fieldSlot, &size); jbyteArray byteArray = env->NewByteArray(size); if (!byteArray) { env->ExceptionClear(); throw_sqlite3_exception(env, "Native could not create new byte[]"); return NULL; } env->SetByteArrayRegion(byteArray, 0, size, static_cast<const jbyte*>(value)); return byteArray; } else if (type == CursorWindow::FIELD_TYPE_INTEGER) { throw_sqlite3_exception(env, "INTEGER data in nativeGetBlob "); } else if (type == CursorWindow::FIELD_TYPE_FLOAT) { throw_sqlite3_exception(env, "FLOAT data in nativeGetBlob "); } else if (type == CursorWindow::FIELD_TYPE_NULL) { // do nothing } else { throwUnknownTypeException(env, type); } return NULL; }
static jdouble nativeGetDouble(JNIEnv* env, jclass clazz, jlong windowPtr, jint row, jint column) { CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); LOG_WINDOW("Getting double for %d,%d from %p", row, column, window); CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column); if (!fieldSlot) { throwExceptionWithRowCol(env, row, column); return 0.0; } int32_t type = window->getFieldSlotType(fieldSlot); if (type == CursorWindow::FIELD_TYPE_FLOAT) { return window->getFieldSlotValueDouble(fieldSlot); } else if (type == CursorWindow::FIELD_TYPE_STRING) { size_t sizeIncludingNull; const char* value = window->getFieldSlotValueString(fieldSlot, &sizeIncludingNull); return sizeIncludingNull > 1 ? strtod(value, NULL) : 0.0; } else if (type == CursorWindow::FIELD_TYPE_INTEGER) { return jdouble(window->getFieldSlotValueLong(fieldSlot)); } else if (type == CursorWindow::FIELD_TYPE_NULL) { return 0.0; } else if (type == CursorWindow::FIELD_TYPE_BLOB) { throw_sqlite3_exception(env, "Unable to convert BLOB to double"); return 0.0; } else { throwUnknownTypeException(env, type); return 0.0; } }
static jint nativeGetType(JNIEnv* env, jclass clazz, jlong windowPtr, jint row, jint column) { CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); LOG_WINDOW("returning column type affinity for %d,%d from %p", row, column, window); CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column); if (!fieldSlot) { return CursorWindow::FIELD_TYPE_NULL; } return window->getFieldSlotType(fieldSlot); }
static jint nativeGetType(JNIEnv* env, jclass clazz, jlong windowPtr, jint row, jint column) { CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); LOG_WINDOW("returning column type affinity for %d,%d from %p", row, column, window); CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column); if (!fieldSlot) { // FIXME: This is really broken but we have CTS tests that depend // on this legacy behavior. //throwExceptionWithRowCol(env, row, column); return CursorWindow::FIELD_TYPE_NULL; } return window->getFieldSlotType(fieldSlot); }
static jstring nativeGetString(JNIEnv* env, jclass clazz, jlong windowPtr, jint row, jint column) { CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); LOG_WINDOW("Getting string for %d,%d from %p", row, column, window); CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column); if (!fieldSlot) { throwExceptionWithRowCol(env, row, column); return NULL; } int32_t type = window->getFieldSlotType(fieldSlot); if (type == CursorWindow::FIELD_TYPE_STRING) { size_t sizeIncludingNull; const char* value = window->getFieldSlotValueString(fieldSlot, &sizeIncludingNull); if (sizeIncludingNull <= 1) { return gEmptyString; } // Convert to UTF-16 here instead of calling NewStringUTF. NewStringUTF // doesn't like UTF-8 strings with high codepoints. It actually expects // Modified UTF-8 with encoded surrogate pairs. String16 utf16(value, sizeIncludingNull - 1); return env->NewString(reinterpret_cast<const jchar*>(utf16.string()), utf16.size()); } else if (type == CursorWindow::FIELD_TYPE_INTEGER) { int64_t value = window->getFieldSlotValueLong(fieldSlot); char buf[32]; snprintf(buf, sizeof(buf), "%" PRId64, value); return env->NewStringUTF(buf); } else if (type == CursorWindow::FIELD_TYPE_FLOAT) { double value = window->getFieldSlotValueDouble(fieldSlot); char buf[32]; snprintf(buf, sizeof(buf), "%g", value); return env->NewStringUTF(buf); } else if (type == CursorWindow::FIELD_TYPE_NULL) { return NULL; } else if (type == CursorWindow::FIELD_TYPE_BLOB) { throw_sqlite3_exception(env, "Unable to convert BLOB to string"); return NULL; } else { throwUnknownTypeException(env, type); return NULL; } }
static jstring nativeGetString(JNIEnv* env, jclass clazz, jlong windowPtr, jint row, jint column) { CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); //LOG_WINDOW("Getting string for %d,%d from %p", row, column, window); CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column); if (!fieldSlot) { throwExceptionWithRowCol(env, row, column); return NULL; } int32_t type = window->getFieldSlotType(fieldSlot); if (type == CursorWindow::FIELD_TYPE_STRING) { size_t sizeIncludingNull; const char* value = window->getFieldSlotValueString(fieldSlot, &sizeIncludingNull); if (sizeIncludingNull <= 1) { return NULL; } jchar chars[sizeIncludingNull - 1]; jint size = utf8ToJavaCharArray(value, chars, sizeIncludingNull - 1); return env->NewString(chars, size); } else if (type == CursorWindow::FIELD_TYPE_INTEGER) { int64_t value = window->getFieldSlotValueLong(fieldSlot); char buf[32]; snprintf(buf, sizeof(buf), "%" PRId64, value); return env->NewStringUTF(buf); } else if (type == CursorWindow::FIELD_TYPE_FLOAT) { double value = window->getFieldSlotValueDouble(fieldSlot); char buf[32]; snprintf(buf, sizeof(buf), "%g", value); return env->NewStringUTF(buf); } else if (type == CursorWindow::FIELD_TYPE_NULL) { return NULL; } else if (type == CursorWindow::FIELD_TYPE_BLOB) { throw_sqlite3_exception(env, "Unable to convert BLOB to string"); return NULL; } else { throwUnknownTypeException(env, type); return NULL; } }
static void nativeCopyStringToBuffer(JNIEnv* env, jclass clazz, jlong windowPtr, jint row, jint column, jobject bufferObj) { CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); LOG_WINDOW("Copying string for %d,%d from %p", row, column, window); CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column); if (!fieldSlot) { throwExceptionWithRowCol(env, row, column); return; } int32_t type = window->getFieldSlotType(fieldSlot); if (type == CursorWindow::FIELD_TYPE_STRING) { size_t sizeIncludingNull; const char* value = window->getFieldSlotValueString(fieldSlot, &sizeIncludingNull); if (sizeIncludingNull > 1) { fillCharArrayBufferUTF(env, bufferObj, value, sizeIncludingNull - 1); } else { clearCharArrayBuffer(env, bufferObj); } } else if (type == CursorWindow::FIELD_TYPE_INTEGER) { int64_t value = window->getFieldSlotValueLong(fieldSlot); char buf[32]; snprintf(buf, sizeof(buf), "%" PRId64, value); fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf)); } else if (type == CursorWindow::FIELD_TYPE_FLOAT) { double value = window->getFieldSlotValueDouble(fieldSlot); char buf[32]; snprintf(buf, sizeof(buf), "%g", value); fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf)); } else if (type == CursorWindow::FIELD_TYPE_NULL) { clearCharArrayBuffer(env, bufferObj); } else if (type == CursorWindow::FIELD_TYPE_BLOB) { throw_sqlite3_exception(env, "Unable to convert BLOB to string"); } else { throwUnknownTypeException(env, type); } }