OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / core / jni / CursorWindow.h
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
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 
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0 
9  *
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 
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
24 #include <binder/IMemory.h>
25 #include <utils/RefBase.h>
26
27 #include <jni.h>
28
29 #define DEFAULT_WINDOW_SIZE 4096
30 #define MAX_WINDOW_SIZE (1024 * 1024)
31 #define WINDOW_ALLOCATION_SIZE 4096
32
33 #define ROW_SLOT_CHUNK_NUM_ROWS 16
34
35 // Row slots are allocated in chunks of ROW_SLOT_CHUNK_NUM_ROWS,
36 // with an offset after the rows that points to the next chunk
37 #define ROW_SLOT_CHUNK_SIZE ((ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t)) + sizeof(uint32_t))
38
39
40 #if LOG_NDEBUG
41
42 #define IF_LOG_WINDOW() if (false)
43 #define LOG_WINDOW(...)
44
45 #else
46
47 #define IF_LOG_WINDOW() IF_LOG(LOG_DEBUG, "CursorWindow")
48 #define LOG_WINDOW(...) LOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__)
49
50 #endif
51
52
53 // When defined to true strings are stored as UTF8, otherwise they're UTF16
54 #define WINDOW_STORAGE_UTF8 1
55
56 // When defined to true numberic values are stored inline in the field_slot_t, otherwise they're allocated in the window
57 #define WINDOW_STORAGE_INLINE_NUMERICS 1
58
59 namespace android {
60
61 typedef struct
62 {
63     uint32_t numRows;
64     uint32_t numColumns;
65 } window_header_t;
66
67 typedef struct
68 {
69     uint32_t offset;
70 } row_slot_t;
71
72 typedef struct
73 {
74     uint8_t type;
75     union {
76         double d;
77         int64_t l;
78         struct {
79             uint32_t offset;
80             uint32_t size;
81         } buffer;
82     } data;
83 } __attribute__((packed)) field_slot_t;
84
85 #define FIELD_TYPE_INTEGER 1
86 #define FIELD_TYPE_FLOAT 2
87 #define FIELD_TYPE_STRING 3
88 #define FIELD_TYPE_BLOB 4
89 #define FIELD_TYPE_NULL 5
90
91 /**
92  * This class stores a set of rows from a database in a buffer. The begining of the
93  * window has first chunk of row_slot_ts, which are offsets to the row directory, followed by
94  * an offset to the next chunk in a linked-list of additional chunk of row_slot_ts in case
95  * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a
96  * field_slot_t per column, which has the size, offset, and type of the data for that field.
97  * Note that the data types come from sqlite3.h.
98  */
99 class CursorWindow
100 {
101 public:
102                         CursorWindow(size_t maxSize);
103                         CursorWindow(){}
104     bool                setMemory(const sp<IMemory>&);
105                         ~CursorWindow();
106
107     bool                initBuffer(bool localOnly);
108     sp<IMemory>         getMemory() {return mMemory;}
109
110     size_t              size() {return mSize;}
111     uint8_t *           data() {return mData;}
112     uint32_t            getNumRows() {return mHeader->numRows;}
113     uint32_t            getNumColumns() {return mHeader->numColumns;}
114     void                freeLastRow() {
115                             if (mHeader->numRows > 0) {
116                                 mHeader->numRows--;
117                             }
118                         }
119     bool                setNumColumns(uint32_t numColumns)
120                             {
121                                 uint32_t cur = mHeader->numColumns;
122                                 if (cur > 0 && cur != numColumns) {
123                                     LOGE("Trying to go from %d columns to %d", cur, numColumns);
124                                     return false;
125                                 }
126                                 mHeader->numColumns = numColumns;
127                                 return true;
128                             }
129
130     int32_t             freeSpace();
131
132     void                clear();
133
134                         /**
135                          * Allocate a row slot and its directory. The returned
136                          * pointer points to the begining of the row's directory
137                          * or NULL if there wasn't room. The directory is
138                          * initialied with NULL entries for each field.
139                          */
140     field_slot_t *      allocRow();
141
142                         /**
143                          * Allocate a portion of the window. Returns the offset
144                          * of the allocation, or 0 if there isn't enough space.
145                          * If aligned is true, the allocation gets 4 byte alignment.
146                          */
147     uint32_t            alloc(size_t size, bool aligned = false);
148
149     uint32_t            read_field_slot(int row, int column, field_slot_t * slot);
150
151                         /**
152                          * Copy data into the window at the given offset.
153                          */
154     void                copyIn(uint32_t offset, uint8_t const * data, size_t size);
155     void                copyIn(uint32_t offset, int64_t data);
156     void                copyIn(uint32_t offset, double data);
157
158     void                copyOut(uint32_t offset, uint8_t * data, size_t size);
159     int64_t             copyOutLong(uint32_t offset);
160     double              copyOutDouble(uint32_t offset);
161
162     bool                putLong(unsigned int row, unsigned int col, int64_t value);
163     bool                putDouble(unsigned int row, unsigned int col, double value);
164     bool                putNull(unsigned int row, unsigned int col);
165
166     bool                getLong(unsigned int row, unsigned int col, int64_t * valueOut);
167     bool                getDouble(unsigned int row, unsigned int col, double * valueOut);
168     bool                getNull(unsigned int row, unsigned int col, bool * valueOut);
169
170     uint8_t *           offsetToPtr(uint32_t offset) {return mData + offset;}
171
172     row_slot_t *        allocRowSlot();
173
174     row_slot_t *        getRowSlot(int row);
175     
176                         /**
177                          * return NULL if Failed to find rowSlot or
178                          * Invalid rowSlot
179                          */
180     field_slot_t *      getFieldSlotWithCheck(int row, int column);
181     field_slot_t *      getFieldSlot(int row, int column)
182                             {
183                                 int fieldDirOffset = getRowSlot(row)->offset;
184                                 return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;
185                             }
186
187 private:
188     uint8_t * mData;
189     size_t mSize;
190     size_t mMaxSize;
191     window_header_t * mHeader;
192     sp<IMemory> mMemory;
193
194     /**
195      * Offset of the lowest unused data byte in the array.
196      */
197     uint32_t mFreeOffset;
198 };
199
200 }; // namespace android
201
202 #endif