116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Copyright (C) 2006 The Android Open Source Project 316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you may not use this file except in compliance with the License. 616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * You may obtain a copy of the License at 716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 1016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Unless required by applicable law or agreed to in writing, software 1116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 1216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * See the License for the specific language governing permissions and 1416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * limitations under the License. 1516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 1616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 1716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifndef _ANDROID__DATABASE_WINDOW_H 1816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define _ANDROID__DATABASE_WINDOW_H 1916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 2016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <cutils/log.h> 214e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov#include <inttypes.h> 2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stddef.h> 2316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdint.h> 2416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 2516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <binder/Parcel.h> 2616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/String8.h> 2716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 2816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#if LOG_NDEBUG 2916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define IF_LOG_WINDOW() if (false) 3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_WINDOW(...) 3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#else 3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define IF_LOG_WINDOW() IF_ALOG(LOG_DEBUG, "CursorWindow") 3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_WINDOW(...) ALOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__) 3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 4016c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android { 4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski/** 4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * This class stores a set of rows from a database in a buffer. The begining of the 4416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * window has first chunk of RowSlots, which are offsets to the row directory, followed by 4516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * an offset to the next chunk in a linked-list of additional chunk of RowSlots in case 4616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a 4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * FieldSlot per column, which has the size, offset, and type of the data for that field. 4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Note that the data types come from sqlite3.h. 4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Strings are stored in UTF-8. 5116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 5216c4d154dca43c662571129af31b27433b919a32Adam Lesinskiclass CursorWindow { 5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski CursorWindow(const String8& name, int ashmemFd, 5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski void* data, size_t size, bool readOnly); 5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 5616c4d154dca43c662571129af31b27433b919a32Adam Lesinskipublic: 5716c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* Field types. */ 5816c4d154dca43c662571129af31b27433b919a32Adam Lesinski enum { 5916c4d154dca43c662571129af31b27433b919a32Adam Lesinski FIELD_TYPE_NULL = 0, 6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski FIELD_TYPE_INTEGER = 1, 6116c4d154dca43c662571129af31b27433b919a32Adam Lesinski FIELD_TYPE_FLOAT = 2, 6216c4d154dca43c662571129af31b27433b919a32Adam Lesinski FIELD_TYPE_STRING = 3, 6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski FIELD_TYPE_BLOB = 4, 6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski }; 6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* Opaque type that describes a field slot. */ 6716c4d154dca43c662571129af31b27433b919a32Adam Lesinski struct FieldSlot { 6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski private: 6916c4d154dca43c662571129af31b27433b919a32Adam Lesinski int32_t type; 7016c4d154dca43c662571129af31b27433b919a32Adam Lesinski union { 7116c4d154dca43c662571129af31b27433b919a32Adam Lesinski double d; 7216c4d154dca43c662571129af31b27433b919a32Adam Lesinski int64_t l; 7316c4d154dca43c662571129af31b27433b919a32Adam Lesinski struct { 7416c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t offset; 7516c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t size; 7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } buffer; 7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } data; 7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski friend class CursorWindow; 8016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } __attribute((packed)); 8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ~CursorWindow(); 8316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski static status_t create(const String8& name, size_t size, CursorWindow** outCursorWindow); 8516c4d154dca43c662571129af31b27433b919a32Adam Lesinski static status_t createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow); 8616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8716c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t writeToParcel(Parcel* parcel); 8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8916c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline String8 name() { return mName; } 9016c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline size_t size() { return mSize; } 9116c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline size_t freeSpace() { return mSize - mHeader->freeOffset; } 9216c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline uint32_t getNumRows() { return mHeader->numRows; } 9316c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline uint32_t getNumColumns() { return mHeader->numColumns; } 9416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 9516c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t clear(); 9616c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t setNumColumns(uint32_t numColumns); 9716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 9816c4d154dca43c662571129af31b27433b919a32Adam Lesinski /** 9916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Allocate a row slot and its directory. 10016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * The row is initialized will null entries for each field. 10116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 10216c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t allocRow(); 10316c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t freeLastRow(); 10416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 10516c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t putBlob(uint32_t row, uint32_t column, const void* value, size_t size); 10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t putString(uint32_t row, uint32_t column, const char* value, size_t sizeIncludingNull); 10716c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t putLong(uint32_t row, uint32_t column, int64_t value); 10816c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t putDouble(uint32_t row, uint32_t column, double value); 10916c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t putNull(uint32_t row, uint32_t column); 11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /** 11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Gets the field slot at the specified row and column. 11316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Returns null if the requested row or column is not in the window. 11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski FieldSlot* getFieldSlot(uint32_t row, uint32_t column); 11616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 11716c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline int32_t getFieldSlotType(FieldSlot* fieldSlot) { 11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return fieldSlot->type; 11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline int64_t getFieldSlotValueLong(FieldSlot* fieldSlot) { 12216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return fieldSlot->data.l; 12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline double getFieldSlotValueDouble(FieldSlot* fieldSlot) { 12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return fieldSlot->data.d; 12716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 12816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 12916c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline const char* getFieldSlotValueString(FieldSlot* fieldSlot, 13016c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t* outSizeIncludingNull) { 13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski *outSizeIncludingNull = fieldSlot->data.buffer.size; 1324e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov return static_cast<char*>(offsetToPtr( 1334e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov fieldSlot->data.buffer.offset, fieldSlot->data.buffer.size)); 13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 13616c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline const void* getFieldSlotValueBlob(FieldSlot* fieldSlot, size_t* outSize) { 13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski *outSize = fieldSlot->data.buffer.size; 1384e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov return offsetToPtr(fieldSlot->data.buffer.offset, fieldSlot->data.buffer.size); 13916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 14016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 14116c4d154dca43c662571129af31b27433b919a32Adam Lesinskiprivate: 14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski static const size_t ROW_SLOT_CHUNK_NUM_ROWS = 100; 14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski struct Header { 14516c4d154dca43c662571129af31b27433b919a32Adam Lesinski // Offset of the lowest unused byte in the window. 14616c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t freeOffset; 14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 14816c4d154dca43c662571129af31b27433b919a32Adam Lesinski // Offset of the first row slot chunk. 14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t firstChunkOffset; 15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 15116c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t numRows; 15216c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t numColumns; 15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski }; 15416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 15516c4d154dca43c662571129af31b27433b919a32Adam Lesinski struct RowSlot { 15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t offset; 15716c4d154dca43c662571129af31b27433b919a32Adam Lesinski }; 15816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 15916c4d154dca43c662571129af31b27433b919a32Adam Lesinski struct RowSlotChunk { 16016c4d154dca43c662571129af31b27433b919a32Adam Lesinski RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS]; 16116c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t nextChunkOffset; 16216c4d154dca43c662571129af31b27433b919a32Adam Lesinski }; 16316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 16416c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 mName; 16516c4d154dca43c662571129af31b27433b919a32Adam Lesinski int mAshmemFd; 16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski void* mData; 16716c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t mSize; 16816c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool mReadOnly; 16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski Header* mHeader; 17016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 1714e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov inline void* offsetToPtr(uint32_t offset, uint32_t bufferSize = 0) { 1724e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov if (offset >= mSize) { 1734e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov ALOGE("Offset %" PRIu32 " out of bounds, max value %zu", offset, mSize); 1744e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov return NULL; 1754e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov } 1764e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov if (offset + bufferSize > mSize) { 1774e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov ALOGE("End offset %" PRIu32 " out of bounds, max value %zu", 1784e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov offset + bufferSize, mSize); 1794e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov return NULL; 1804e110ab20bb91e945a17c6e166e14e2da9608f08Fyodor Kupolov } 18116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return static_cast<uint8_t*>(mData) + offset; 18216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 18316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 18416c4d154dca43c662571129af31b27433b919a32Adam Lesinski inline uint32_t offsetFromPtr(void* ptr) { 18516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData); 18616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 18716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 18816c4d154dca43c662571129af31b27433b919a32Adam Lesinski /** 18916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Allocate a portion of the window. Returns the offset 19016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * of the allocation, or 0 if there isn't enough space. 19116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * If aligned is true, the allocation gets 4 byte alignment. 19216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 19316c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t alloc(size_t size, bool aligned = false); 19416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 19516c4d154dca43c662571129af31b27433b919a32Adam Lesinski RowSlot* getRowSlot(uint32_t row); 19616c4d154dca43c662571129af31b27433b919a32Adam Lesinski RowSlot* allocRowSlot(); 19716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 19816c4d154dca43c662571129af31b27433b919a32Adam Lesinski status_t putBlobOrString(uint32_t row, uint32_t column, 19916c4d154dca43c662571129af31b27433b919a32Adam Lesinski const void* value, size_t size, int32_t type); 20016c4d154dca43c662571129af31b27433b919a32Adam Lesinski}; 20116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 20216c4d154dca43c662571129af31b27433b919a32Adam Lesinski}; // namespace android 20316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 20416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 205