blob: 4fbff2ac9476ebef4da6fe9877adacd40c1ee8c7 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
Vasu Nori8b0dd7d2010-05-18 11:54:31 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007 *
Vasu Nori8b0dd7d2010-05-18 11:54:31 -07008 * http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009 *
Vasu Nori8b0dd7d2010-05-18 11:54:31 -070010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014 * limitations under the License.
15 */
16
17#ifndef _ANDROID__DATABASE_WINDOW_H
18#define _ANDROID__DATABASE_WINDOW_H
19
20#include <cutils/log.h>
21#include <stddef.h>
22#include <stdint.h>
23
Mathias Agopiand1f74d02010-01-29 16:54:04 -080024#include <binder/IMemory.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025#include <utils/RefBase.h>
26
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027#define DEFAULT_WINDOW_SIZE 4096
28#define MAX_WINDOW_SIZE (1024 * 1024)
29#define WINDOW_ALLOCATION_SIZE 4096
30
31#define ROW_SLOT_CHUNK_NUM_ROWS 16
32
33// Row slots are allocated in chunks of ROW_SLOT_CHUNK_NUM_ROWS,
34// with an offset after the rows that points to the next chunk
35#define ROW_SLOT_CHUNK_SIZE ((ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t)) + sizeof(uint32_t))
36
37
38#if LOG_NDEBUG
39
40#define IF_LOG_WINDOW() if (false)
41#define LOG_WINDOW(...)
42
43#else
44
45#define IF_LOG_WINDOW() IF_LOG(LOG_DEBUG, "CursorWindow")
46#define LOG_WINDOW(...) LOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__)
47
48#endif
49
50
51// When defined to true strings are stored as UTF8, otherwise they're UTF16
52#define WINDOW_STORAGE_UTF8 1
53
54// When defined to true numberic values are stored inline in the field_slot_t, otherwise they're allocated in the window
55#define WINDOW_STORAGE_INLINE_NUMERICS 1
56
57namespace android {
58
59typedef struct
60{
61 uint32_t numRows;
62 uint32_t numColumns;
63} window_header_t;
64
65typedef struct
66{
67 uint32_t offset;
68} row_slot_t;
69
70typedef struct
71{
72 uint8_t type;
73 union {
74 double d;
75 int64_t l;
76 struct {
77 uint32_t offset;
78 uint32_t size;
79 } buffer;
80 } data;
81} __attribute__((packed)) field_slot_t;
82
Vasu Nori8b0dd7d2010-05-18 11:54:31 -070083#define FIELD_TYPE_NULL 0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084#define FIELD_TYPE_INTEGER 1
85#define FIELD_TYPE_FLOAT 2
86#define FIELD_TYPE_STRING 3
87#define FIELD_TYPE_BLOB 4
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89/**
90 * This class stores a set of rows from a database in a buffer. The begining of the
91 * window has first chunk of row_slot_ts, which are offsets to the row directory, followed by
92 * an offset to the next chunk in a linked-list of additional chunk of row_slot_ts in case
93 * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a
94 * field_slot_t per column, which has the size, offset, and type of the data for that field.
95 * Note that the data types come from sqlite3.h.
96 */
97class CursorWindow
98{
99public:
100 CursorWindow(size_t maxSize);
101 CursorWindow(){}
Mathias Agopiand1f74d02010-01-29 16:54:04 -0800102 bool setMemory(const sp<IMemory>&);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 ~CursorWindow();
104
105 bool initBuffer(bool localOnly);
106 sp<IMemory> getMemory() {return mMemory;}
107
108 size_t size() {return mSize;}
109 uint8_t * data() {return mData;}
110 uint32_t getNumRows() {return mHeader->numRows;}
111 uint32_t getNumColumns() {return mHeader->numColumns;}
112 void freeLastRow() {
113 if (mHeader->numRows > 0) {
114 mHeader->numRows--;
115 }
116 }
117 bool setNumColumns(uint32_t numColumns)
118 {
119 uint32_t cur = mHeader->numColumns;
120 if (cur > 0 && cur != numColumns) {
121 LOGE("Trying to go from %d columns to %d", cur, numColumns);
122 return false;
123 }
124 mHeader->numColumns = numColumns;
125 return true;
126 }
127
128 int32_t freeSpace();
129
130 void clear();
131
132 /**
133 * Allocate a row slot and its directory. The returned
134 * pointer points to the begining of the row's directory
135 * or NULL if there wasn't room. The directory is
136 * initialied with NULL entries for each field.
137 */
138 field_slot_t * allocRow();
139
140 /**
141 * Allocate a portion of the window. Returns the offset
142 * of the allocation, or 0 if there isn't enough space.
143 * If aligned is true, the allocation gets 4 byte alignment.
144 */
145 uint32_t alloc(size_t size, bool aligned = false);
146
147 uint32_t read_field_slot(int row, int column, field_slot_t * slot);
148
149 /**
150 * Copy data into the window at the given offset.
151 */
152 void copyIn(uint32_t offset, uint8_t const * data, size_t size);
153 void copyIn(uint32_t offset, int64_t data);
154 void copyIn(uint32_t offset, double data);
155
156 void copyOut(uint32_t offset, uint8_t * data, size_t size);
157 int64_t copyOutLong(uint32_t offset);
158 double copyOutDouble(uint32_t offset);
159
160 bool putLong(unsigned int row, unsigned int col, int64_t value);
161 bool putDouble(unsigned int row, unsigned int col, double value);
162 bool putNull(unsigned int row, unsigned int col);
163
164 bool getLong(unsigned int row, unsigned int col, int64_t * valueOut);
165 bool getDouble(unsigned int row, unsigned int col, double * valueOut);
166 bool getNull(unsigned int row, unsigned int col, bool * valueOut);
167
168 uint8_t * offsetToPtr(uint32_t offset) {return mData + offset;}
169
170 row_slot_t * allocRowSlot();
171
172 row_slot_t * getRowSlot(int row);
Vasu Nori8b0dd7d2010-05-18 11:54:31 -0700173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 /**
175 * return NULL if Failed to find rowSlot or
176 * Invalid rowSlot
177 */
178 field_slot_t * getFieldSlotWithCheck(int row, int column);
179 field_slot_t * getFieldSlot(int row, int column)
180 {
181 int fieldDirOffset = getRowSlot(row)->offset;
182 return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;
183 }
184
185private:
186 uint8_t * mData;
187 size_t mSize;
188 size_t mMaxSize;
189 window_header_t * mHeader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 sp<IMemory> mMemory;
191
192 /**
193 * Offset of the lowest unused data byte in the array.
194 */
195 uint32_t mFreeOffset;
196};
197
198}; // namespace android
199
200#endif