android_database_CursorWindow.cpp revision 715311fa5aeb39fd0904209e1428a3656c721c3d
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef LOG_TAG 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "CursorWindow" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <jni.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <JNIHelp.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String16.h> 273bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#include <utils/Unicode.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 332807df89af680e46cb35ee0035bb10b42d3136a2Mike Lockwood#include "binder/CursorWindow.h" 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "sqlite3_exception.h" 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_util_Binder.h" 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 393bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic struct { 403bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jfieldID data; 413bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jfieldID sizeCopied; 423bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} gCharArrayBufferClassInfo; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jstring gEmptyString; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 463bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void throwExceptionWithRowCol(JNIEnv* env, jint row, jint column) { 473bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown String8 msg; 483bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown msg.appendFormat("Couldn't read row %d, col %d from CursorWindow. " 493bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown "Make sure the Cursor is initialized correctly before accessing data from it.", 503bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown row, column); 513bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jniThrowException(env, "java/lang/IllegalStateException", msg.string()); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 543bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void throwUnknownTypeException(JNIEnv * env, jint type) { 553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown String8 msg; 563bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown msg.appendFormat("UNKNOWN type %d", type); 573bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jniThrowException(env, "java/lang/IllegalStateException", msg.string()); 583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 603bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jint nativeInitializeEmpty(JNIEnv* env, jclass clazz, 613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint cursorWindowSize, jboolean localOnly) { 623bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = new CursorWindow(cursorWindowSize); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!window) { 643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!window->initBuffer(localOnly)) { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete window; 683bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("nativeInitializeEmpty: window = %p", window); 723bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return reinterpret_cast<jint>(window); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 753bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jint nativeInitializeFromBinder(JNIEnv* env, jclass clazz, jobject binderObj) { 763bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown sp<IMemory> memory = interface_cast<IMemory>(ibinderForJavaObject(env, binderObj)); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (memory == NULL) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", "Couldn't get native binder"); 793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 823bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = new CursorWindow(); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!window) { 843bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!window->setMemory(memory)) { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete window; 883bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 913bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("nativeInitializeFromBinder: numRows = %d, numColumns = %d, window = %p", 923bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->getNumRows(), window->getNumColumns(), window); 933bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return reinterpret_cast<jint>(window); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 963bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void nativeDispose(JNIEnv* env, jclass clazz, jint windowPtr) { 973bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 983bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (window) { 993bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Closing window %p", window); 1003bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown delete window; 1013bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 1023bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 1033bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 1043bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jobject nativeGetBinder(JNIEnv * env, jclass clazz, jint windowPtr) { 1053bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (window) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemory> memory = window->getMemory(); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (memory != NULL) { 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> binder = memory->asBinder(); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return javaObjectForIBinder(env, binder); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1163bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void nativeClear(JNIEnv * env, jclass clazz, jint windowPtr) { 1173bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1183bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Clearing window %p", window); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project window->clear(); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1223bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jint nativeGetNumRows(JNIEnv* env, jclass clazz, jint windowPtr) { 1233bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1243bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return window->getNumRows(); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1273bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativeSetNumColumns(JNIEnv* env, jclass clazz, jint windowPtr, 1283bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint columnNum) { 1293bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1303bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return window->setNumColumns(columnNum); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1333bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativeAllocRow(JNIEnv* env, jclass clazz, jint windowPtr) { 1343bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1353bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return window->allocRow() != NULL; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1383bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void nativeFreeLastRow(JNIEnv* env, jclass clazz, jint windowPtr) { 1393bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1403bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->freeLastRow(); 1413bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1433bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jint nativeGetType(JNIEnv* env, jclass clazz, jint windowPtr, 1443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 1453bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1463bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("returning column type affinity for %d,%d from %p", row, column, window); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1483bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 1493bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 150aa32c30b81134fc7ebd9408f4757d1dc4410f338Jeff Brown // FIXME: This is really broken but we have CTS tests that depend 151aa32c30b81134fc7ebd9408f4757d1dc4410f338Jeff Brown // on this legacy behavior. 152aa32c30b81134fc7ebd9408f4757d1dc4410f338Jeff Brown //throwExceptionWithRowCol(env, row, column); 153aa32c30b81134fc7ebd9408f4757d1dc4410f338Jeff Brown return FIELD_TYPE_NULL; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return fieldSlot->type; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jbyteArray nativeGetBlob(JNIEnv* env, jclass clazz, jint windowPtr, 1593bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 1603bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Getting blob for %d,%d from %p", row, column, window); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1633bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 1643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throwExceptionWithRowCol(env, row, column); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1693bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint8_t type = fieldSlot->type; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == FIELD_TYPE_BLOB || type == FIELD_TYPE_STRING) { 1713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t size = fieldSlot->data.buffer.size; 1723bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jbyteArray byteArray = env->NewByteArray(size); 173e6044145bccf30e2b1785eb33a26de6496167986Vasu Nori if (!byteArray) { 1743bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ExceptionClear(); 175e6044145bccf30e2b1785eb33a26de6496167986Vasu Nori throw_sqlite3_exception(env, "Native could not create new byte[]"); 176e6044145bccf30e2b1785eb33a26de6496167986Vasu Nori return NULL; 177e6044145bccf30e2b1785eb33a26de6496167986Vasu Nori } 1783bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetByteArrayRegion(byteArray, 0, size, 1793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown reinterpret_cast<jbyte*>(window->offsetToPtr(fieldSlot->data.buffer.offset))); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return byteArray; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_INTEGER) { 1823bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throw_sqlite3_exception(env, "INTEGER data in nativeGetBlob "); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_FLOAT) { 1843bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throw_sqlite3_exception(env, "FLOAT data in nativeGetBlob "); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_NULL) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do nothing 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1883bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1933bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jstring nativeGetString(JNIEnv* env, jclass clazz, jint windowPtr, 1943bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 1953bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 1963bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Getting string for %d,%d from %p", row, column, window); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1983bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 1993bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throwExceptionWithRowCol(env, row, column); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2043bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint8_t type = fieldSlot->type; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == FIELD_TYPE_STRING) { 2063bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t size = fieldSlot->data.buffer.size; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 208715311fa5aeb39fd0904209e1428a3656c721c3dJeff Brown if (size <= 1) { 209715311fa5aeb39fd0904209e1428a3656c721c3dJeff Brown return gEmptyString; 210715311fa5aeb39fd0904209e1428a3656c721c3dJeff Brown } 211715311fa5aeb39fd0904209e1428a3656c721c3dJeff Brown // Convert to UTF-16 here instead of calling NewStringUTF. NewStringUTF 212715311fa5aeb39fd0904209e1428a3656c721c3dJeff Brown // doesn't like UTF-8 strings with high codepoints. It actually expects 213715311fa5aeb39fd0904209e1428a3656c721c3dJeff Brown // Modified UTF-8 with encoded surrogate pairs. 214715311fa5aeb39fd0904209e1428a3656c721c3dJeff Brown String16 utf16(window->getFieldSlotValueString(fieldSlot), size - 1); 215715311fa5aeb39fd0904209e1428a3656c721c3dJeff Brown return env->NewString(reinterpret_cast<const jchar*>(utf16.string()), utf16.size()); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 2173bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t chars = size / sizeof(char16_t); 2183bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return chars ? env->NewString(reinterpret_cast<jchar*>( 2193bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->getFieldSlotValueString(fieldSlot)), chars) 2203bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown : gEmptyString; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_INTEGER) { 2233bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown int64_t value = window->getFieldSlotValueLong(fieldSlot); 2243bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown char buf[32]; 2253bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown snprintf(buf, sizeof(buf), "%lld", value); 2263bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return env->NewStringUTF(buf); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_FLOAT) { 2283bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown double value = window->getFieldSlotValueDouble(fieldSlot); 2293bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown char buf[32]; 2303bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown snprintf(buf, sizeof(buf), "%g", value); 2313bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return env->NewStringUTF(buf); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_NULL) { 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_BLOB) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw_sqlite3_exception(env, "Unable to convert BLOB to string"); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2383bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2433bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jcharArray allocCharArrayBuffer(JNIEnv* env, jobject bufferObj, size_t size) { 2443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jcharArray dataObj = jcharArray(env->GetObjectField(bufferObj, 2453bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown gCharArrayBufferClassInfo.data)); 2463bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj && size) { 2473bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jsize capacity = env->GetArrayLength(dataObj); 2483bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (size_t(capacity) < size) { 2493bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->DeleteLocalRef(dataObj); 2503bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown dataObj = NULL; 2513bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2523bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2533bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!dataObj) { 2543bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jsize capacity = size; 2553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (capacity < 64) { 2563bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown capacity = 64; 2573bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown dataObj = env->NewCharArray(capacity); // might throw OOM 2593bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj) { 2603bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetObjectField(bufferObj, gCharArrayBufferClassInfo.data, dataObj); 2613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2623bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2633bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return dataObj; 2643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2663bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void fillCharArrayBufferUTF(JNIEnv* env, jobject bufferObj, 2673bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown const char* str, size_t len) { 2683bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown ssize_t size = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(str), len); 2693bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (size < 0) { 2703bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size = 0; // invalid UTF8 string 2713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2723bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, size); 2733bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj) { 2743bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (size) { 2753bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jchar* data = static_cast<jchar*>(env->GetPrimitiveArrayCritical(dataObj, NULL)); 276d0ff68da6a606602235fb8749473999e3d1bde53Jeff Brown utf8_to_utf16_no_null_terminator(reinterpret_cast<const uint8_t*>(str), len, 2773bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown reinterpret_cast<char16_t*>(data)); 2783bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleasePrimitiveArrayCritical(dataObj, data, 0); 2793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2803bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, size); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2823bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2843bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#if !WINDOW_STORAGE_UTF8 2853bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void fillCharArrayBuffer(JNIEnv* env, jobject bufferObj, 2863bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown const char16_t* str, size_t len) { 2873bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, len); 2883bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj) { 2893bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (len) { 2903bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jchar* data = static_cast<jchar*>(env->GetPrimitiveArrayCritical(dataObj, NULL)); 2913bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown memcpy(data, str, len * sizeof(jchar)); 2923bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleasePrimitiveArrayCritical(dataObj, data, 0); 2933bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2943bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, len); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2973bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#endif 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2993bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void clearCharArrayBuffer(JNIEnv* env, jobject bufferObj) { 3003bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, 0); 3013bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj) { 3023bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, 0); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3043bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 30503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana 3063bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void nativeCopyStringToBuffer(JNIEnv* env, jclass clazz, jint windowPtr, 3073bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column, jobject bufferObj) { 3083bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 3093bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Copying string for %d,%d from %p", row, column, window); 3103bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3113bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 3123bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 3133bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwExceptionWithRowCol(env, row, column); 3143bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3163bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3173bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint8_t type = fieldSlot->type; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == FIELD_TYPE_STRING) { 3193bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t size = fieldSlot->data.buffer.size; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 3213bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (size > 1) { 3223bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fillCharArrayBufferUTF(env, bufferObj, 3233bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->getFieldSlotValueString(fieldSlot), size - 1); 3243bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else { 3253bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown clearCharArrayBuffer(env, bufferObj); 3263bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3283bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t chars = size / sizeof(char16_t); 3293bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (chars) { 3303bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fillCharArrayBuffer(env, bufferObj, 3313bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->getFieldSlotValueString(fieldSlot), chars); 3323bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else { 3333bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown clearCharArrayBuffer(env, bufferObj); 33403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana } 3353bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#endif 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_INTEGER) { 3373bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown int64_t value = window->getFieldSlotValueLong(fieldSlot); 3383bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown char buf[32]; 3393bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown snprintf(buf, sizeof(buf), "%lld", value); 3403bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf)); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_FLOAT) { 3423bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown double value = window->getFieldSlotValueDouble(fieldSlot); 3433bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown char buf[32]; 3443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown snprintf(buf, sizeof(buf), "%g", value); 3453bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf)); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_NULL) { 3473bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown clearCharArrayBuffer(env, bufferObj); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_BLOB) { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw_sqlite3_exception(env, "Unable to convert BLOB to string"); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3513bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jlong nativeGetLong(JNIEnv* env, jclass clazz, jint windowPtr, 3563bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 3573bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 3583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Getting long for %d,%d from %p", row, column, window); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3603bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 3613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 3623bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwExceptionWithRowCol(env, row, column); 3633bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 3643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 3653bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3663bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint8_t type = fieldSlot->type; 3673bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (type == FIELD_TYPE_INTEGER) { 3683bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return window->getFieldSlotValueLong(fieldSlot); 3693bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else if (type == FIELD_TYPE_STRING) { 3703bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t size = fieldSlot->data.buffer.size; 3713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#if WINDOW_STORAGE_UTF8 3723bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return size > 1 ? strtoll(window->getFieldSlotValueString(fieldSlot), NULL, 0) : 0L; 3733bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#else 3743bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t chars = size / sizeof(char16_t); 3753bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return chars ? strtoll(String8(window->getFieldSlotValueString(fieldSlot), chars) 3763bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown .string(), NULL, 0) : 0L; 3773bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#endif 3783bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else if (type == FIELD_TYPE_FLOAT) { 3793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return jlong(window->getFieldSlotValueDouble(fieldSlot)); 3803bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else if (type == FIELD_TYPE_NULL) { 3813bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 3823bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else if (type == FIELD_TYPE_BLOB) { 3833bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throw_sqlite3_exception(env, "Unable to convert BLOB to long"); 3843bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 3853bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else { 3863bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 3873bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 3883bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 3893bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 3903bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3913bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jdouble nativeGetDouble(JNIEnv* env, jclass clazz, jint windowPtr, 3923bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 3933bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 3943bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Getting double for %d,%d from %p", row, column, window); 3953bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3963bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 3973bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throwExceptionWithRowCol(env, row, column); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0.0; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4023bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint8_t type = fieldSlot->type; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == FIELD_TYPE_FLOAT) { 4043bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return window->getFieldSlotValueDouble(fieldSlot); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_STRING) { 4063bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t size = fieldSlot->data.buffer.size; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 4083bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return size > 1 ? strtod(window->getFieldSlotValueString(fieldSlot), NULL) : 0.0; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 4103bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t chars = size / sizeof(char16_t); 4113bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return chars ? strtod(String8(window->getFieldSlotValueString(fieldSlot), chars) 4123bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown .string(), NULL) : 0.0; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_INTEGER) { 4153bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return jdouble(window->getFieldSlotValueLong(fieldSlot)); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_NULL) { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0.0; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_BLOB) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw_sqlite3_exception(env, "Unable to convert BLOB to double"); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0.0; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4223bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0.0; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4273bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutBlob(JNIEnv* env, jclass clazz, jint windowPtr, 4283bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jbyteArray valueObj, jint row, jint column) { 4293bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 4303bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, column); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fieldSlot == NULL) { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4363bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jsize len = env->GetArrayLength(valueObj); 4373bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t offset = window->alloc(len); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!offset) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW("Failed allocating %u bytes", len); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4433bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown void* value = env->GetPrimitiveArrayCritical(valueObj, NULL); 4443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->copyIn(offset, static_cast<const uint8_t*>(value), len); 4453bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleasePrimitiveArrayCritical(valueObj, value, JNI_ABORT); 4463bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fieldSlot->type = FIELD_TYPE_BLOB; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fieldSlot->data.buffer.offset = offset; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fieldSlot->data.buffer.size = len; 4503bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is BLOB with %u bytes @ %d", row, column, len, offset); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4543bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutString(JNIEnv* env, jclass clazz, jint windowPtr, 4553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jstring valueObj, jint row, jint column) { 4563bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 4573bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, column); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fieldSlot == NULL) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 4643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t size = env->GetStringUTFLength(valueObj) + 1; 4653bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown const char* valueStr = env->GetStringUTFChars(valueObj, NULL); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 4673bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t size = env->GetStringLength(valueObj) * sizeof(jchar); 4683bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown const jchar* valueStr = env->GetStringChars(valueObj, NULL); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4703bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!valueStr) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW("value can't be transfer to UTFChars"); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4753bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t offset = window->alloc(size); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!offset) { 4773bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Failed allocating %u bytes", size); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 4793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleaseStringUTFChars(valueObj, valueStr); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 4813bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleaseStringChars(valueObj, valueStr); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4863bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->copyIn(offset, reinterpret_cast<const uint8_t*>(valueStr), size); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 4893bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleaseStringUTFChars(valueObj, valueStr); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 4913bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleaseStringChars(valueObj, valueStr); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4943bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fieldSlot->type = FIELD_TYPE_STRING; 4953bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fieldSlot->data.buffer.offset = offset; 4963bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fieldSlot->data.buffer.size = size; 4973bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is TEXT with %u bytes @ %d", row, column, size, offset); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5013bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutLong(JNIEnv* env, jclass clazz, jint windowPtr, 5023bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jlong value, jint row, jint column) { 5033bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 5043bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!window->putLong(row, column, value)) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5093bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is INTEGER 0x%016llx", row, column, value); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5133bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutDouble(JNIEnv* env, jclass clazz, jint windowPtr, 5143bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jdouble value, jint row, jint column) { 5153bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 5163bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!window->putDouble(row, column, value)) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5213bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is FLOAT %lf", row, column, value); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5253bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutNull(JNIEnv* env, jclass clazz, jint windowPtr, 5263bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 5273bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 5283bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!window->putNull(row, column)) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5333bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is NULL", row, column); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5393bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown /* name, signature, funcPtr */ 5403bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeInitializeEmpty", "(IZ)I", 5413bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeInitializeEmpty }, 5423bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeInitializeFromBinder", "(Landroid/os/IBinder;)I", 5433bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeInitializeFromBinder }, 5443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeDispose", "(I)V", 5453bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeDispose }, 5463bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetBinder", "(I)Landroid/os/IBinder;", 5473bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetBinder }, 5483bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeClear", "(I)V", 5493bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeClear }, 5503bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetNumRows", "(I)I", 5513bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetNumRows }, 5523bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeSetNumColumns", "(II)Z", 5533bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeSetNumColumns }, 5543bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeAllocRow", "(I)Z", 5553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeAllocRow }, 5563bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeFreeLastRow", "(I)V", 5573bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeFreeLastRow }, 5583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetType", "(III)I", 5593bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetType }, 5603bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetBlob", "(III)[B", 5613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetBlob }, 5623bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetString", "(III)Ljava/lang/String;", 5633bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetString }, 5643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetLong", "(III)J", 5653bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetLong }, 5663bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetDouble", "(III)D", 5673bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetDouble }, 5683bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeCopyStringToBuffer", "(IIILandroid/database/CharArrayBuffer;)V", 5693bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeCopyStringToBuffer }, 5703bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutBlob", "(I[BII)Z", 5713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutBlob }, 5723bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutString", "(ILjava/lang/String;II)Z", 5733bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutString }, 5743bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutLong", "(IJII)Z", 5753bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutLong }, 5763bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutDouble", "(IDII)Z", 5773bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutDouble }, 5783bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutNull", "(III)Z", 5793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutNull }, 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5823bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#define FIND_CLASS(var, className) \ 5833bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown var = env->FindClass(className); \ 5843bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); 5853bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 5863bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 5873bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 5883bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_FATAL_IF(! var, "Unable to find field " fieldName); 5893bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_database_CursorWindow(JNIEnv * env) 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz; 5933bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown FIND_CLASS(clazz, "android/database/CharArrayBuffer"); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5953bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown GET_FIELD_ID(gCharArrayBufferClassInfo.data, clazz, 5963bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown "data", "[C"); 5973bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown GET_FIELD_ID(gCharArrayBufferClassInfo.sizeCopied, clazz, 5983bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown "sizeCopied", "I"); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6003bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown gEmptyString = jstring(env->NewGlobalRef(env->NewStringUTF(""))); 6013bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_FATAL_IF(!gEmptyString, "Unable to create empty string"); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AndroidRuntime::registerNativeMethods(env, "android/database/CursorWindow", 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sMethods, NELEM(sMethods)); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android 608