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>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "CursorWindow.h"
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "sqlite3_exception.h"
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_util_Binder.h"
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gWindowField;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gBufferField;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gSizeCopiedField;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define GET_WINDOW(env, object) ((CursorWindow *)env->GetIntField(object, gWindowField))
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define SET_WINDOW(env, object, window) (env->SetIntField(object, gWindowField, (int)window))
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define SET_BUFFER(env, object, buf) (env->SetObjectField(object, gBufferField, buf))
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define SET_SIZE_COPIED(env, object, size) (env->SetIntField(object, gSizeCopiedField, size))
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectCursorWindow * get_window_from_object(JNIEnv * env, jobject javaWindow)
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return GET_WINDOW(env, javaWindow);
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void native_init_empty(JNIEnv * env, jobject object, jboolean localOnly)
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t * data;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t size;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    window = new CursorWindow(MAX_WINDOW_SIZE);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!window) {
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/RuntimeException", "No memory for native window object");
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!window->initBuffer(localOnly)) {
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException", "Couldn't init cursor window");
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete window;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("native_init_empty: window = %p", window);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SET_WINDOW(env, object, window);
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void native_init_memory(JNIEnv * env, jobject object, jobject memObj)
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<IMemory> memory = interface_cast<IMemory>(ibinderForJavaObject(env, memObj));
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (memory == NULL) {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException", "Couldn't get native binder");
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = new CursorWindow();
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!window) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/RuntimeException", "No memory for native window object");
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!window->setMemory(memory)) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/RuntimeException", "No memory in memObj");
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete window;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("native_init_memory: numRows = %d, numColumns = %d, window = %p", window->getNumRows(), window->getNumColumns(), window);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SET_WINDOW(env, object, window);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject native_getBinder(JNIEnv * env, jobject object)
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (window) {
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<IMemory> memory = window->getMemory();
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (memory != NULL) {
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<IBinder> binder = memory->asBinder();
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return javaObjectForIBinder(env, binder);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void native_clear(JNIEnv * env, jobject object)
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("Clearing window %p", window);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (window == NULL) {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException", "clear() called after close()");
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    window->clear();
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void native_close(JNIEnv * env, jobject object)
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (window) {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("Closing window %p", window);
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete window;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SET_WINDOW(env, object, 0);
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void throwExceptionWithRowCol(JNIEnv * env, jint row, jint column)
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[100];
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buf, sizeof(buf), "get field slot from row %d col %d failed", row, column);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jniThrowException(env, "java/lang/IllegalStateException", buf);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void throwUnknowTypeException(JNIEnv * env, jint type)
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[80];
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buf, sizeof(buf), "UNKNOWN type %d", type);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jniThrowException(env, "java/lang/IllegalStateException", buf);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong getLong_native(JNIEnv * env, jobject object, jint row, jint column)
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t err;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("Getting long for %d,%d from %p", row, column, window);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_slot_t field;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = window->read_field_slot(row, column, &field);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0) {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwExceptionWithRowCol(env, row, column);
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t type = field.type;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (type == FIELD_TYPE_INTEGER) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int64_t value;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (window->getLong(row, column, &value)) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return value;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_STRING) {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t size = field.data.buffer.size;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (size > 0) {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return strtoll((char const *)window->offsetToPtr(field.data.buffer.offset), NULL, 0);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char const * str = ascii.string();
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return strtoll(str, NULL, 0);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_FLOAT) {
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double value;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (window->getDouble(row, column, &value)) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return value;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_NULL) {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_BLOB) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw_sqlite3_exception(env, "Unable to convert BLOB to long");
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwUnknowTypeException(env, type);
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jbyteArray getBlob_native(JNIEnv* env, jobject object, jint row, jint column)
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t err;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("Getting blob for %d,%d from %p", row, column, window);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_slot_t field;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = window->read_field_slot(row, column, &field);
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwExceptionWithRowCol(env, row, column);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t type = field.type;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (type == FIELD_TYPE_BLOB || type == FIELD_TYPE_STRING) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jbyteArray byteArray = env->NewByteArray(field.data.buffer.size);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_ASSERT(byteArray, "Native could not create new byte[]");
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetByteArrayRegion(byteArray, 0, field.data.buffer.size,
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (const jbyte*)window->offsetToPtr(field.data.buffer.offset));
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return byteArray;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_INTEGER) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw_sqlite3_exception(env, "INTEGER data in getBlob_native ");
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_FLOAT) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw_sqlite3_exception(env, "FLOAT data in getBlob_native ");
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_NULL) {
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // do nothing
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwUnknowTypeException(env, type);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean isBlob_native(JNIEnv* env, jobject object, jint row, jint column)
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t err;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
23203d9490758c9318cee6d14d3cc5007556dce92d0Fred QuintanaLOG_WINDOW("Checking if column is a blob or null for %d,%d from %p", row, column, window);
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_slot_t field;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = window->read_field_slot(row, column, &field);
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwExceptionWithRowCol(env, row, column);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return field.type == FIELD_TYPE_BLOB || field.type == FIELD_TYPE_NULL;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanastatic jboolean isString_native(JNIEnv* env, jobject object, jint row, jint column)
24503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana{
24603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    int32_t err;
24703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    CursorWindow * window = GET_WINDOW(env, object);
24803d9490758c9318cee6d14d3cc5007556dce92d0Fred QuintanaLOG_WINDOW("Checking if column is a string or null for %d,%d from %p", row, column, window);
24903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
25003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    field_slot_t field;
25103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    err = window->read_field_slot(row, column, &field);
25203d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    if (err != 0) {
25303d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        throwExceptionWithRowCol(env, row, column);
25403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        return NULL;
25503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    }
25603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
25703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    return field.type == FIELD_TYPE_STRING || field.type == FIELD_TYPE_NULL;
25803d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana}
25903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
26003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanastatic jboolean isInteger_native(JNIEnv* env, jobject object, jint row, jint column)
26103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana{
26203d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    int32_t err;
26303d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    CursorWindow * window = GET_WINDOW(env, object);
26403d9490758c9318cee6d14d3cc5007556dce92d0Fred QuintanaLOG_WINDOW("Checking if column is an integer for %d,%d from %p", row, column, window);
26503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
26603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    field_slot_t field;
26703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    err = window->read_field_slot(row, column, &field);
26803d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    if (err != 0) {
26903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        throwExceptionWithRowCol(env, row, column);
27003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        return NULL;
27103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    }
27203d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
27303d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    return field.type == FIELD_TYPE_INTEGER;
27403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana}
27503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
27603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanastatic jboolean isFloat_native(JNIEnv* env, jobject object, jint row, jint column)
27703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana{
27803d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    int32_t err;
27903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    CursorWindow * window = GET_WINDOW(env, object);
28003d9490758c9318cee6d14d3cc5007556dce92d0Fred QuintanaLOG_WINDOW("Checking if column is a float for %d,%d from %p", row, column, window);
28103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
28203d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    field_slot_t field;
28303d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    err = window->read_field_slot(row, column, &field);
28403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    if (err != 0) {
28503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        throwExceptionWithRowCol(env, row, column);
28603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        return NULL;
28703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    }
28803d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
28903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    return field.type == FIELD_TYPE_FLOAT;
29003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana}
29103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring getString_native(JNIEnv* env, jobject object, jint row, jint column)
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t err;
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("Getting string for %d,%d from %p", row, column, window);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_slot_t field;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = window->read_field_slot(row, column, &field);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0) {
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwExceptionWithRowCol(env, row, column);
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t type = field.type;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (type == FIELD_TYPE_STRING) {
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t size = field.data.buffer.size;
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (size > 0) {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Pass size - 1 since the UTF8 is null terminated and we don't want a null terminator on the UTF16 string
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 utf16((char const *)window->offsetToPtr(field.data.buffer.offset), size - 1);
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return env->NewString((jchar const *)utf16.string(), utf16.size());
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return env->NewString((jchar const *)window->offsetToPtr(field.data.buffer.offset), size / 2);
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return env->NewStringUTF("");
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_INTEGER) {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int64_t value;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (window->getLong(row, column, &value)) {
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char buf[32];
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            snprintf(buf, sizeof(buf), "%lld", value);
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return env->NewStringUTF(buf);
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_FLOAT) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double value;
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (window->getDouble(row, column, &value)) {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char buf[32];
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            snprintf(buf, sizeof(buf), "%g", value);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return env->NewStringUTF(buf);
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_NULL) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_BLOB) {
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw_sqlite3_exception(env, "Unable to convert BLOB to string");
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwUnknowTypeException(env, type);
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use this only to convert characters that are known to be within the
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0-127 range for direct conversion to UTF-16
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint charToJchar(const char* src, jchar* dst, jint bufferSize)
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t len = strlen(src);
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bufferSize < len) {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len = bufferSize;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < len; i++) {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *dst++ = (*src++ & 0x7F);
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return len;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jcharArray copyStringToBuffer_native(JNIEnv* env, jobject object, jint row,
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      jint column, jint bufferSize, jobject buf)
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t err;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("Copying string for %d,%d from %p", row, column, window);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_slot_t field;
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = window->read_field_slot(row, column, &field);
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0) {
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException", "Unable to get field slot");
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jcharArray buffer = (jcharArray)env->GetObjectField(buf, gBufferField);
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (buffer == NULL) {
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException", "buf should not be null");
38103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        return NULL;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jchar* dst = env->GetCharArrayElements(buffer, NULL);
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t type = field.type;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t sizeCopied = 0;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jcharArray newArray = NULL;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (type == FIELD_TYPE_STRING) {
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t size = field.data.buffer.size;
38903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        if (size > 0) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Pass size - 1 since the UTF8 is null terminated and we don't want a null terminator on the UTF16 string
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 utf16((char const *)window->offsetToPtr(field.data.buffer.offset), size - 1);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int32_t strSize = utf16.size();
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strSize > bufferSize || dst == NULL) {
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newArray = env->NewCharArray(strSize);
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                env->SetCharArrayRegion(newArray, 0, strSize, (jchar const *)utf16.string());
39703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana            } else {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(dst, (jchar const *)utf16.string(), strSize * 2);
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sizeCopied = strSize;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sizeCopied = size/2 + size % 2;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (size > bufferSize * 2 || dst == NULL) {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newArray = env->NewCharArray(sizeCopied);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(newArray, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(dst, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
41003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        }
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_INTEGER) {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int64_t value;
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (window->getLong(row, column, &value)) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char buf[32];
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int len;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            snprintf(buf, sizeof(buf), "%lld", value);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jchar* dst = env->GetCharArrayElements(buffer, NULL);
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sizeCopied = charToJchar(buf, dst, bufferSize);
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         }
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_FLOAT) {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double value;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (window->getDouble(row, column, &value)) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char tempbuf[32];
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            snprintf(tempbuf, sizeof(tempbuf), "%g", value);
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jchar* dst = env->GetCharArrayElements(buffer, NULL);
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sizeCopied = charToJchar(tempbuf, dst, bufferSize);
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_NULL) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_BLOB) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw_sqlite3_exception(env, "Unable to convert BLOB to string");
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Unknown field type %d", type);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw_sqlite3_exception(env, "UNKNOWN type in copyStringToBuffer_native()");
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SET_SIZE_COPIED(env, buf, sizeCopied);
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseCharArrayElements(buffer, dst, JNI_OK);
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return newArray;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jdouble getDouble_native(JNIEnv* env, jobject object, jint row, jint column)
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t err;
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("Getting double for %d,%d from %p", row, column, window);
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_slot_t field;
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = window->read_field_slot(row, column, &field);
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0) {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwExceptionWithRowCol(env, row, column);
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0.0;
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t type = field.type;
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (type == FIELD_TYPE_FLOAT) {
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double value;
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (window->getDouble(row, column, &value)) {
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return value;
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0.0;
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_STRING) {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t size = field.data.buffer.size;
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (size > 0) {
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return strtod((char const *)window->offsetToPtr(field.data.buffer.offset), NULL);
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char const * str = ascii.string();
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return strtod(str, NULL);
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0.0;
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_INTEGER) {
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int64_t value;
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (window->getLong(row, column, &value)) {
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (double) value;
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0.0;
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_NULL) {
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0.0;
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (type == FIELD_TYPE_BLOB) {
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw_sqlite3_exception(env, "Unable to convert BLOB to double");
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0.0;
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throwUnknowTypeException(env, type);
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0.0;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean isNull_native(JNIEnv* env, jobject object, jint row, jint column)
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOG_WINDOW("Checking for NULL at %d,%d from %p", row, column, window);
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool isNull;
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (window->getNull(row, column, &isNull)) {
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return isNull;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //TODO throw execption?
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint getNumRows(JNIEnv * env, jobject object)
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return window->getNumRows();
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean setNumColumns(JNIEnv * env, jobject object, jint columnNum)
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return window->setNumColumns(columnNum);
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean allocRow(JNIEnv * env, jobject object)
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return window->allocRow() != NULL;
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean putBlob_native(JNIEnv * env, jobject object, jbyteArray value, jint row, jint col)
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!value) {
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW("How did a null value send to here");
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, col);
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fieldSlot == NULL) {
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW(" getFieldSlotWithCheck error ");
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint len = env->GetArrayLength(value);
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int offset = window->alloc(len);
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!offset) {
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW("Failed allocating %u bytes", len);
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jbyte * bytes = env->GetByteArrayElements(value, NULL);
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    window->copyIn(offset, (uint8_t const *)bytes, len);
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This must be updated after the call to alloc(), since that
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // may move the field around in the window
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fieldSlot->type = FIELD_TYPE_BLOB;
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fieldSlot->data.buffer.offset = offset;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fieldSlot->data.buffer.size = len;
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseByteArrayElements(value, bytes, JNI_ABORT);
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_WINDOW("%d,%d is BLOB with %u bytes @ %d", row, col, len, offset);
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean putString_native(JNIEnv * env, jobject object, jstring value, jint row, jint col)
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!value) {
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW("How did a null value send to here");
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, col);
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fieldSlot == NULL) {
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW(" getFieldSlotWithCheck error ");
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int len = env->GetStringUTFLength(value) + 1;
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char const * valStr = env->GetStringUTFChars(value, NULL);
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int len = env->GetStringLength(value);
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // GetStringLength return number of chars and one char takes 2 bytes
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    len *= 2;
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const jchar* valStr = env->GetStringChars(value, NULL);
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!valStr) {
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW("value can't be transfer to UTFChars");
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int offset = window->alloc(len);
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!offset) {
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW("Failed allocating %u bytes", len);
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(value, valStr);
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringChars(value, valStr);
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    window->copyIn(offset, (uint8_t const *)valStr, len);
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This must be updated after the call to alloc(), since that
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // may move the field around in the window
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fieldSlot->type = FIELD_TYPE_STRING;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fieldSlot->data.buffer.offset = offset;
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fieldSlot->data.buffer.size = len;
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_WINDOW("%d,%d is TEXT with %u bytes @ %d", row, col, len, offset);
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if WINDOW_STORAGE_UTF8
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseStringUTFChars(value, valStr);
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseStringChars(value, valStr);
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean putLong_native(JNIEnv * env, jobject object, jlong value, jint row, jint col)
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!window->putLong(row, col, value)) {
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW(" getFieldSlotWithCheck error ");
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_WINDOW("%d,%d is INTEGER 0x%016llx", row, col, value);
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean putDouble_native(JNIEnv * env, jobject object, jdouble value, jint row, jint col)
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!window->putDouble(row, col, value)) {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW(" getFieldSlotWithCheck error ");
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_WINDOW("%d,%d is FLOAT %lf", row, col, value);
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean putNull_native(JNIEnv * env, jobject object, jint row, jint col)
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!window->putNull(row, col)) {
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_WINDOW(" getFieldSlotWithCheck error ");
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_WINDOW("%d,%d is NULL", row, col);
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// free the last row
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void freeLastRow(JNIEnv * env, jobject object) {
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CursorWindow * window = GET_WINDOW(env, object);
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    window->freeLastRow();
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] =
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_init", "(Z)V", (void *)native_init_empty},
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_init", "(Landroid/os/IBinder;)V", (void *)native_init_memory},
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_getBinder", "()Landroid/os/IBinder;", (void *)native_getBinder},
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"native_clear", "()V", (void *)native_clear},
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"close_native", "()V", (void *)native_close},
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getLong_native", "(II)J", (void *)getLong_native},
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getBlob_native", "(II)[B", (void *)getBlob_native},
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"isBlob_native", "(II)Z", (void *)isBlob_native},
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getString_native", "(II)Ljava/lang/String;", (void *)getString_native},
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"copyStringToBuffer_native", "(IIILandroid/database/CharArrayBuffer;)[C", (void *)copyStringToBuffer_native},
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getDouble_native", "(II)D", (void *)getDouble_native},
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"isNull_native", "(II)Z", (void *)isNull_native},
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getNumRows_native", "()I", (void *)getNumRows},
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"setNumColumns_native", "(I)Z", (void *)setNumColumns},
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"allocRow_native", "()Z", (void *)allocRow},
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"putBlob_native", "([BII)Z", (void *)putBlob_native},
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"putString_native", "(Ljava/lang/String;II)Z", (void *)putString_native},
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"putLong_native", "(JII)Z", (void *)putLong_native},
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"putDouble_native", "(DII)Z", (void *)putDouble_native},
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"freeLastRow_native", "()V", (void *)freeLastRow},
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"putNull_native", "(II)Z", (void *)putNull_native},
67903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    {"isString_native", "(II)Z", (void *)isString_native},
68003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    {"isFloat_native", "(II)Z", (void *)isFloat_native},
68103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    {"isInteger_native", "(II)Z", (void *)isInteger_native},
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_database_CursorWindow(JNIEnv * env)
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz;
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass("android/database/CursorWindow");
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (clazz == NULL) {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Can't find android/database/CursorWindow");
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gWindowField = env->GetFieldID(clazz, "nWindow", "I");
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (gWindowField == NULL) {
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Error locating fields");
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
70003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz =  env->FindClass("android/database/CharArrayBuffer");
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (clazz == NULL) {
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Can't find android/database/CharArrayBuffer");
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBufferField = env->GetFieldID(clazz, "data", "[C");
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (gBufferField == NULL) {
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Error locating fields data in CharArrayBuffer");
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gSizeCopiedField = env->GetFieldID(clazz, "sizeCopied", "I");
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (gSizeCopiedField == NULL) {
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Error locating fields sizeCopied in CharArrayBuffer");
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(env, "android/database/CursorWindow",
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sMethods, NELEM(sMethods));
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android
726