android_database_CursorWindow.cpp revision d0ff68da6a606602235fb8749473999e3d1bde53
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 2083bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return size > 1 ? env->NewStringUTF(window->getFieldSlotValueString(fieldSlot)) 2093bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown : gEmptyString; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 2113bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t chars = size / sizeof(char16_t); 2123bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return chars ? env->NewString(reinterpret_cast<jchar*>( 2133bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->getFieldSlotValueString(fieldSlot)), chars) 2143bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown : gEmptyString; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_INTEGER) { 2173bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown int64_t value = window->getFieldSlotValueLong(fieldSlot); 2183bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown char buf[32]; 2193bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown snprintf(buf, sizeof(buf), "%lld", value); 2203bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return env->NewStringUTF(buf); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_FLOAT) { 2223bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown double value = window->getFieldSlotValueDouble(fieldSlot); 2233bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown char buf[32]; 2243bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown snprintf(buf, sizeof(buf), "%g", value); 2253bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return env->NewStringUTF(buf); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_NULL) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_BLOB) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw_sqlite3_exception(env, "Unable to convert BLOB to string"); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2323bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2373bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jcharArray allocCharArrayBuffer(JNIEnv* env, jobject bufferObj, size_t size) { 2383bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jcharArray dataObj = jcharArray(env->GetObjectField(bufferObj, 2393bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown gCharArrayBufferClassInfo.data)); 2403bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj && size) { 2413bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jsize capacity = env->GetArrayLength(dataObj); 2423bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (size_t(capacity) < size) { 2433bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->DeleteLocalRef(dataObj); 2443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown dataObj = NULL; 2453bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2463bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2473bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!dataObj) { 2483bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jsize capacity = size; 2493bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (capacity < 64) { 2503bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown capacity = 64; 2513bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2523bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown dataObj = env->NewCharArray(capacity); // might throw OOM 2533bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj) { 2543bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetObjectField(bufferObj, gCharArrayBufferClassInfo.data, dataObj); 2553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2563bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2573bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return dataObj; 2583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2603bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void fillCharArrayBufferUTF(JNIEnv* env, jobject bufferObj, 2613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown const char* str, size_t len) { 2623bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown ssize_t size = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(str), len); 2633bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (size < 0) { 2643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size = 0; // invalid UTF8 string 2653bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2663bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, size); 2673bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj) { 2683bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (size) { 2693bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jchar* data = static_cast<jchar*>(env->GetPrimitiveArrayCritical(dataObj, NULL)); 270d0ff68da6a606602235fb8749473999e3d1bde53Jeff Brown utf8_to_utf16_no_null_terminator(reinterpret_cast<const uint8_t*>(str), len, 2713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown reinterpret_cast<char16_t*>(data)); 2723bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleasePrimitiveArrayCritical(dataObj, data, 0); 2733bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2743bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, size); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2763bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2783bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#if !WINDOW_STORAGE_UTF8 2793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void fillCharArrayBuffer(JNIEnv* env, jobject bufferObj, 2803bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown const char16_t* str, size_t len) { 2813bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, len); 2823bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj) { 2833bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (len) { 2843bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jchar* data = static_cast<jchar*>(env->GetPrimitiveArrayCritical(dataObj, NULL)); 2853bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown memcpy(data, str, len * sizeof(jchar)); 2863bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleasePrimitiveArrayCritical(dataObj, data, 0); 2873bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 2883bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, len); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2913bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#endif 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2933bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void clearCharArrayBuffer(JNIEnv* env, jobject bufferObj) { 2943bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, 0); 2953bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (dataObj) { 2963bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, 0); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2983bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 29903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana 3003bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic void nativeCopyStringToBuffer(JNIEnv* env, jclass clazz, jint windowPtr, 3013bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column, jobject bufferObj) { 3023bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 3033bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Copying string for %d,%d from %p", row, column, window); 3043bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3053bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 3063bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 3073bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwExceptionWithRowCol(env, row, column); 3083bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3103bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3113bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint8_t type = fieldSlot->type; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == FIELD_TYPE_STRING) { 3133bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t size = fieldSlot->data.buffer.size; 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 3153bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (size > 1) { 3163bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fillCharArrayBufferUTF(env, bufferObj, 3173bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->getFieldSlotValueString(fieldSlot), size - 1); 3183bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else { 3193bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown clearCharArrayBuffer(env, bufferObj); 3203bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3223bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t chars = size / sizeof(char16_t); 3233bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (chars) { 3243bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fillCharArrayBuffer(env, bufferObj, 3253bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->getFieldSlotValueString(fieldSlot), chars); 3263bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else { 3273bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown clearCharArrayBuffer(env, bufferObj); 32803d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana } 3293bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#endif 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_INTEGER) { 3313bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown int64_t value = window->getFieldSlotValueLong(fieldSlot); 3323bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown char buf[32]; 3333bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown snprintf(buf, sizeof(buf), "%lld", value); 3343bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf)); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_FLOAT) { 3363bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown double value = window->getFieldSlotValueDouble(fieldSlot); 3373bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown char buf[32]; 3383bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown snprintf(buf, sizeof(buf), "%g", value); 3393bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf)); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_NULL) { 3413bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown clearCharArrayBuffer(env, bufferObj); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_BLOB) { 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw_sqlite3_exception(env, "Unable to convert BLOB to string"); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3453bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3493bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jlong nativeGetLong(JNIEnv* env, jclass clazz, jint windowPtr, 3503bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 3513bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 3523bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Getting long for %d,%d from %p", row, column, window); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3543bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 3553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 3563bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwExceptionWithRowCol(env, row, column); 3573bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 3583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 3593bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3603bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint8_t type = fieldSlot->type; 3613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (type == FIELD_TYPE_INTEGER) { 3623bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return window->getFieldSlotValueLong(fieldSlot); 3633bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else if (type == FIELD_TYPE_STRING) { 3643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t size = fieldSlot->data.buffer.size; 3653bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#if WINDOW_STORAGE_UTF8 3663bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return size > 1 ? strtoll(window->getFieldSlotValueString(fieldSlot), NULL, 0) : 0L; 3673bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#else 3683bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t chars = size / sizeof(char16_t); 3693bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return chars ? strtoll(String8(window->getFieldSlotValueString(fieldSlot), chars) 3703bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown .string(), NULL, 0) : 0L; 3713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#endif 3723bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else if (type == FIELD_TYPE_FLOAT) { 3733bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return jlong(window->getFieldSlotValueDouble(fieldSlot)); 3743bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else if (type == FIELD_TYPE_NULL) { 3753bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 3763bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else if (type == FIELD_TYPE_BLOB) { 3773bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throw_sqlite3_exception(env, "Unable to convert BLOB to long"); 3783bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 3793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } else { 3803bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 3813bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return 0; 3823bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown } 3833bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown} 3843bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3853bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jdouble nativeGetDouble(JNIEnv* env, jclass clazz, jint windowPtr, 3863bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 3873bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 3883bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Getting double for %d,%d from %p", row, column, window); 3893bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 3903bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column); 3913bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!fieldSlot) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throwExceptionWithRowCol(env, row, column); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0.0; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3963bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint8_t type = fieldSlot->type; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == FIELD_TYPE_FLOAT) { 3983bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return window->getFieldSlotValueDouble(fieldSlot); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_STRING) { 4003bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t size = fieldSlot->data.buffer.size; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 4023bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return size > 1 ? strtod(window->getFieldSlotValueString(fieldSlot), NULL) : 0.0; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 4043bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t chars = size / sizeof(char16_t); 4053bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return chars ? strtod(String8(window->getFieldSlotValueString(fieldSlot), chars) 4063bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown .string(), NULL) : 0.0; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_INTEGER) { 4093bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown return jdouble(window->getFieldSlotValueLong(fieldSlot)); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_NULL) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0.0; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == FIELD_TYPE_BLOB) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw_sqlite3_exception(env, "Unable to convert BLOB to double"); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0.0; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4163bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown throwUnknownTypeException(env, type); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0.0; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4213bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutBlob(JNIEnv* env, jclass clazz, jint windowPtr, 4223bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jbyteArray valueObj, jint row, jint column) { 4233bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 4243bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, column); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fieldSlot == NULL) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4303bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jsize len = env->GetArrayLength(valueObj); 4313bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t offset = window->alloc(len); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!offset) { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW("Failed allocating %u bytes", len); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4373bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown void* value = env->GetPrimitiveArrayCritical(valueObj, NULL); 4383bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->copyIn(offset, static_cast<const uint8_t*>(value), len); 4393bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleasePrimitiveArrayCritical(valueObj, value, JNI_ABORT); 4403bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fieldSlot->type = FIELD_TYPE_BLOB; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fieldSlot->data.buffer.offset = offset; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fieldSlot->data.buffer.size = len; 4443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is BLOB with %u bytes @ %d", row, column, len, offset); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4483bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutString(JNIEnv* env, jclass clazz, jint windowPtr, 4493bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jstring valueObj, jint row, jint column) { 4503bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 4513bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, column); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fieldSlot == NULL) { 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 4583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t size = env->GetStringUTFLength(valueObj) + 1; 4593bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown const char* valueStr = env->GetStringUTFChars(valueObj, NULL); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 4613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown size_t size = env->GetStringLength(valueObj) * sizeof(jchar); 4623bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown const jchar* valueStr = env->GetStringChars(valueObj, NULL); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!valueStr) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW("value can't be transfer to UTFChars"); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4693bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown uint32_t offset = window->alloc(size); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!offset) { 4713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("Failed allocating %u bytes", size); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 4733bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleaseStringUTFChars(valueObj, valueStr); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 4753bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleaseStringChars(valueObj, valueStr); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4803bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown window->copyIn(offset, reinterpret_cast<const uint8_t*>(valueStr), size); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8 4833bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleaseStringUTFChars(valueObj, valueStr); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 4853bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown env->ReleaseStringChars(valueObj, valueStr); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4883bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fieldSlot->type = FIELD_TYPE_STRING; 4893bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fieldSlot->data.buffer.offset = offset; 4903bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown fieldSlot->data.buffer.size = size; 4913bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is TEXT with %u bytes @ %d", row, column, size, offset); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4953bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutLong(JNIEnv* env, jclass clazz, jint windowPtr, 4963bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jlong value, jint row, jint column) { 4973bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 4983bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!window->putLong(row, column, value)) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5033bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is INTEGER 0x%016llx", row, column, value); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5073bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutDouble(JNIEnv* env, jclass clazz, jint windowPtr, 5083bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jdouble value, jint row, jint column) { 5093bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 5103bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!window->putDouble(row, column, value)) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5153bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is FLOAT %lf", row, column, value); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5193bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brownstatic jboolean nativePutNull(JNIEnv* env, jclass clazz, jint windowPtr, 5203bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown jint row, jint column) { 5213bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr); 5223bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown if (!window->putNull(row, column)) { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_WINDOW(" getFieldSlotWithCheck error "); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5273bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_WINDOW("%d,%d is NULL", row, column); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5333bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown /* name, signature, funcPtr */ 5343bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeInitializeEmpty", "(IZ)I", 5353bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeInitializeEmpty }, 5363bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeInitializeFromBinder", "(Landroid/os/IBinder;)I", 5373bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeInitializeFromBinder }, 5383bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeDispose", "(I)V", 5393bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeDispose }, 5403bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetBinder", "(I)Landroid/os/IBinder;", 5413bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetBinder }, 5423bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeClear", "(I)V", 5433bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeClear }, 5443bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetNumRows", "(I)I", 5453bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetNumRows }, 5463bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeSetNumColumns", "(II)Z", 5473bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeSetNumColumns }, 5483bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeAllocRow", "(I)Z", 5493bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeAllocRow }, 5503bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeFreeLastRow", "(I)V", 5513bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeFreeLastRow }, 5523bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetType", "(III)I", 5533bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetType }, 5543bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetBlob", "(III)[B", 5553bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetBlob }, 5563bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetString", "(III)Ljava/lang/String;", 5573bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetString }, 5583bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetLong", "(III)J", 5593bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetLong }, 5603bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeGetDouble", "(III)D", 5613bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeGetDouble }, 5623bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativeCopyStringToBuffer", "(IIILandroid/database/CharArrayBuffer;)V", 5633bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativeCopyStringToBuffer }, 5643bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutBlob", "(I[BII)Z", 5653bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutBlob }, 5663bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutString", "(ILjava/lang/String;II)Z", 5673bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutString }, 5683bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutLong", "(IJII)Z", 5693bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutLong }, 5703bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutDouble", "(IDII)Z", 5713bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutDouble }, 5723bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown { "nativePutNull", "(III)Z", 5733bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown (void*)nativePutNull }, 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5763bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#define FIND_CLASS(var, className) \ 5773bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown var = env->FindClass(className); \ 5783bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); 5793bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 5803bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 5813bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 5823bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_FATAL_IF(! var, "Unable to find field " fieldName); 5833bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_database_CursorWindow(JNIEnv * env) 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz; 5873bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown FIND_CLASS(clazz, "android/database/CharArrayBuffer"); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5893bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown GET_FIELD_ID(gCharArrayBufferClassInfo.data, clazz, 5903bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown "data", "[C"); 5913bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown GET_FIELD_ID(gCharArrayBufferClassInfo.sizeCopied, clazz, 5923bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown "sizeCopied", "I"); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5943bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown gEmptyString = jstring(env->NewGlobalRef(env->NewStringUTF(""))); 5953bc6bbc92cd2095f42039b5aadd0a14d0e5d9230Jeff Brown LOG_FATAL_IF(!gEmptyString, "Unable to create empty string"); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AndroidRuntime::registerNativeMethods(env, "android/database/CursorWindow", 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sMethods, NELEM(sMethods)); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android 602