19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 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#ifndef _ANDROID__DATABASE_WINDOW_H 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define _ANDROID__DATABASE_WINDOW_H 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/log.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stddef.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24d1f74d0e3352987467f12a65b8685b60b057d9adMathias Agopian#include <binder/IMemory.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/RefBase.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <jni.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEFAULT_WINDOW_SIZE 4096 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define MAX_WINDOW_SIZE (1024 * 1024) 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define WINDOW_ALLOCATION_SIZE 4096 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ROW_SLOT_CHUNK_NUM_ROWS 16 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Row slots are allocated in chunks of ROW_SLOT_CHUNK_NUM_ROWS, 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// with an offset after the rows that points to the next chunk 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ROW_SLOT_CHUNK_SIZE ((ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t)) + sizeof(uint32_t)) 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if LOG_NDEBUG 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define IF_LOG_WINDOW() if (false) 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_WINDOW(...) 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define IF_LOG_WINDOW() IF_LOG(LOG_DEBUG, "CursorWindow") 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_WINDOW(...) LOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__) 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// When defined to true strings are stored as UTF8, otherwise they're UTF16 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define WINDOW_STORAGE_UTF8 1 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// When defined to true numberic values are stored inline in the field_slot_t, otherwise they're allocated in the window 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define WINDOW_STORAGE_INLINE_NUMERICS 1 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t numRows; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t numColumns; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} window_header_t; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t offset; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} row_slot_t; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t type; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project union { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double d; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int64_t l; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t offset; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t size; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } buffer; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } data; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} __attribute__((packed)) field_slot_t; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define FIELD_TYPE_INTEGER 1 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define FIELD_TYPE_FLOAT 2 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define FIELD_TYPE_STRING 3 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define FIELD_TYPE_BLOB 4 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define FIELD_TYPE_NULL 5 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class stores a set of rows from a database in a buffer. The begining of the 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window has first chunk of row_slot_ts, which are offsets to the row directory, followed by 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * an offset to the next chunk in a linked-list of additional chunk of row_slot_ts in case 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * field_slot_t per column, which has the size, offset, and type of the data for that field. 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note that the data types come from sqlite3.h. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass CursorWindow 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWindow(size_t maxSize); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWindow(){} 104d1f74d0e3352987467f12a65b8685b60b057d9adMathias Agopian bool setMemory(const sp<IMemory>&); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~CursorWindow(); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool initBuffer(bool localOnly); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemory> getMemory() {return mMemory;} 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size() {return mSize;} 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t * data() {return mData;} 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t getNumRows() {return mHeader->numRows;} 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t getNumColumns() {return mHeader->numColumns;} 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void freeLastRow() { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->numRows > 0) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeader->numRows--; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool setNumColumns(uint32_t numColumns) 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t cur = mHeader->numColumns; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cur > 0 && cur != numColumns) { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Trying to go from %d columns to %d", cur, numColumns); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeader->numColumns = numColumns; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t freeSpace(); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void clear(); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Allocate a row slot and its directory. The returned 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pointer points to the begining of the row's directory 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or NULL if there wasn't room. The directory is 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * initialied with NULL entries for each field. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project field_slot_t * allocRow(); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Allocate a portion of the window. Returns the offset 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the allocation, or 0 if there isn't enough space. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If aligned is true, the allocation gets 4 byte alignment. 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t alloc(size_t size, bool aligned = false); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t read_field_slot(int row, int column, field_slot_t * slot); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copy data into the window at the given offset. 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void copyIn(uint32_t offset, uint8_t const * data, size_t size); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void copyIn(uint32_t offset, int64_t data); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void copyIn(uint32_t offset, double data); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void copyOut(uint32_t offset, uint8_t * data, size_t size); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int64_t copyOutLong(uint32_t offset); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double copyOutDouble(uint32_t offset); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool putLong(unsigned int row, unsigned int col, int64_t value); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool putDouble(unsigned int row, unsigned int col, double value); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool putNull(unsigned int row, unsigned int col); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool getLong(unsigned int row, unsigned int col, int64_t * valueOut); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool getDouble(unsigned int row, unsigned int col, double * valueOut); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool getNull(unsigned int row, unsigned int col, bool * valueOut); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t * offsetToPtr(uint32_t offset) {return mData + offset;} 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row_slot_t * allocRowSlot(); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row_slot_t * getRowSlot(int row); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return NULL if Failed to find rowSlot or 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Invalid rowSlot 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project field_slot_t * getFieldSlotWithCheck(int row, int column); 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project field_slot_t * getFieldSlot(int row, int column) 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fieldDirOffset = getRowSlot(row)->offset; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t * mData; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t mSize; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t mMaxSize; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project window_header_t * mHeader; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemory> mMemory; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Offset of the lowest unused data byte in the array. 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t mFreeOffset; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 203