| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2006 The Android Open Source Project | 
 | 3 |  * | 
| Vasu Nori | 8b0dd7d | 2010-05-18 11:54:31 -0700 | [diff] [blame] | 4 |  * 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 7 |  * | 
| Vasu Nori | 8b0dd7d | 2010-05-18 11:54:31 -0700 | [diff] [blame] | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 9 |  * | 
| Vasu Nori | 8b0dd7d | 2010-05-18 11:54:31 -0700 | [diff] [blame] | 10 |  * 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 14 |  * 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 Agopian | d1f74d0 | 2010-01-29 16:54:04 -0800 | [diff] [blame] | 24 | #include <binder/IMemory.h> | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 25 | #include <utils/RefBase.h> | 
 | 26 |  | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 27 | #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 |  | 
 | 57 | namespace android { | 
 | 58 |  | 
 | 59 | typedef struct | 
 | 60 | { | 
 | 61 |     uint32_t numRows; | 
 | 62 |     uint32_t numColumns; | 
 | 63 | } window_header_t; | 
 | 64 |  | 
 | 65 | typedef struct | 
 | 66 | { | 
 | 67 |     uint32_t offset; | 
 | 68 | } row_slot_t; | 
 | 69 |  | 
 | 70 | typedef 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 Nori | 8b0dd7d | 2010-05-18 11:54:31 -0700 | [diff] [blame] | 83 | #define FIELD_TYPE_NULL 0 | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 84 | #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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 88 |  | 
 | 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 |  */ | 
 | 97 | class CursorWindow | 
 | 98 | { | 
 | 99 | public: | 
 | 100 |                         CursorWindow(size_t maxSize); | 
 | 101 |                         CursorWindow(){} | 
| Mathias Agopian | d1f74d0 | 2010-01-29 16:54:04 -0800 | [diff] [blame] | 102 |     bool                setMemory(const sp<IMemory>&); | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 103 |                         ~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 Nori | 8b0dd7d | 2010-05-18 11:54:31 -0700 | [diff] [blame] | 173 |  | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 174 |                         /** | 
 | 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 |  | 
 | 185 | private: | 
 | 186 |     uint8_t * mData; | 
 | 187 |     size_t mSize; | 
 | 188 |     size_t mMaxSize; | 
 | 189 |     window_header_t * mHeader; | 
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 190 |     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 |