• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef SHARED_BLOCK_H
17 #define SHARED_BLOCK_H
18 
19 #include <cinttypes>
20 
21 #include <string>
22 #include <ashmem.h>
23 #include "message_parcel.h"
24 #include "parcel.h"
25 #include "securec.h"
26 #include "rdb_visibility.h"
27 
28 namespace OHOS {
29 namespace AppDataFwk {
30 /**
31  * @brief The constant indicates the error is due to an invalid row record.
32  */
33 static const uint32_t INVALID_ROW_RECORD = 0xFFFFFFFF;
34 /**
35  * This class stores a set of rows from a database in a buffer,
36  * which is used as the set of query result.
37  */
38 class API_EXPORT SharedBlock {
39 public:
40     /**
41      * @brief Cell Unit types.
42      */
43     enum {
44         /** Indicates the Cell Unit data type is NULL at the specified row and column.*/
45         CELL_UNIT_TYPE_NULL = 0,
46         /** Indicates the current Cell Unit data type is INT at the specified row and column.*/
47         CELL_UNIT_TYPE_INTEGER = 1,
48         /** Indicates the current Cell Unit data type is FLOAT at the specified row and column.*/
49         CELL_UNIT_TYPE_FLOAT = 2,
50         /** Indicates the current Cell Unit data type is STRING at the specified row and column.*/
51         CELL_UNIT_TYPE_STRING = 3,
52         /** Indicates the current Cell Unit data type is BLOB at the specified row and column.*/
53         CELL_UNIT_TYPE_BLOB = 4,
54         /** Indicates the current Cell Unit data type is Asset at the specified row and column.*/
55         CELL_UNIT_TYPE_ASSET = 5,
56         /** Indicates the current Cell Unit data type is Assets at the specified row and column.*/
57         CELL_UNIT_TYPE_ASSETS = 6,
58     };
59 
60     /**
61      * @brief SharedBlock error types.
62      */
63     enum {
64         /** Indicates that the operation on SHARED BLOCK was successful.*/
65         SHARED_BLOCK_OK = 0,
66         /** Indicates that the result returned by the shared block operation is a bad value.*/
67         SHARED_BLOCK_BAD_VALUE = 1,
68         /** Indicates the current shared block space is not enough.*/
69         SHARED_BLOCK_NO_MEMORY = 2,
70         /** Indicates that the current operation on SHARED BLOCK is invalid.*/
71         SHARED_BLOCK_INVALID_OPERATION = 3,
72         /** Indicates that an ashmem error occurred in the operation of shared memory.*/
73         SHARED_BLOCK_ASHMEM_ERROR = 4,
74         /** Indicates that the set port error occurred in the operation of shared memory.*/
75         SHARED_BLOCK_SET_PORT_ERROR = 5,
76     };
77 
78     /**
79      * Cell Unit
80      * */
81     struct CellUnit {
82         int32_t type;
83         union {
84             double doubleValue;
85             int64_t longValue;
86             struct {
87                 uint32_t offset;
88                 uint32_t size;
89             } stringOrBlobValue;
90         } cell;
91     } __attribute((packed));
92 
93     /**
94      * @brief Constructor.
95      */
96     API_EXPORT SharedBlock(const std::string &name, sptr<Ashmem> ashmem, size_t size, bool readOnly);
97 
98     /**
99      * @brief Destructor.
100      */
101     API_EXPORT ~SharedBlock();
102 
103     /**
104      * @brief Init current shared block.
105      */
106     API_EXPORT bool Init();
107 
108     /**
109      * @brief Create a shared block.
110      */
111     API_EXPORT static int Create(const std::string &name, size_t size, SharedBlock *&outSharedBlock);
112 
113     /**
114      * @brief Clear current shared block.
115      */
116     API_EXPORT int Clear();
117 
118     /**
119      * @brief Set a shared block column.
120      */
121     API_EXPORT int SetColumnNum(uint32_t numColumns);
122 
123     /**
124      * @brief Allocate a row unit and its directory.
125      */
126     API_EXPORT int AllocRow();
127 
128     /**
129      * @brief Release the value of the last row.
130      */
131     API_EXPORT int FreeLastRow();
132 
133     /**
134      * @brief Put blob data to the shared block.
135      */
136     API_EXPORT int PutBlob(uint32_t row, uint32_t column, const void *value, size_t Size);
137 
138     /**
139      * @brief Put string data to the shared block.
140      */
141     API_EXPORT int PutString(uint32_t row, uint32_t column, const char *value, size_t sizeIncludingNull);
142 
143     /**
144      * @brief Put long data to the shared block.
145      */
146     API_EXPORT int PutLong(uint32_t row, uint32_t column, int64_t value);
147 
148     /**
149      * @brief Put Double data to the shared block.
150      */
151     API_EXPORT int PutDouble(uint32_t row, uint32_t column, double value);
152 
153     /**
154      * @brief Put Asset data to the shared block.
155      */
156     API_EXPORT int PutAsset(uint32_t row, uint32_t column, const void *value, size_t size);
157 
158     /**
159      * @brief Put Assets data to the shared block.
160      */
161     API_EXPORT int PutAssets(uint32_t row, uint32_t column, const void *value, size_t size);
162 
163     /**
164      * @brief Put Null data to the shared block.
165      */
166     API_EXPORT int PutNull(uint32_t row, uint32_t column);
167 
168     /**
169      * @brief Obtains the cell unit at the specified row and column.
170      */
171     API_EXPORT CellUnit *GetCellUnit(uint32_t row, uint32_t column);
172 
173     /**
174      * @brief Obtains string type data from cell unit.
175      */
GetCellUnitValueString(CellUnit * cellUnit,size_t * outSizeIncludingNull)176     API_EXPORT const char *GetCellUnitValueString(CellUnit *cellUnit, size_t *outSizeIncludingNull)
177     {
178         *outSizeIncludingNull = cellUnit->cell.stringOrBlobValue.size;
179         return static_cast<char *>(
180             OffsetToPtr(cellUnit->cell.stringOrBlobValue.offset, cellUnit->cell.stringOrBlobValue.size));
181     }
182 
183     /**
184      * @brief Obtains blob type data from cell unit.
185      */
GetCellUnitValueBlob(CellUnit * cellUnit,size_t * outSize)186     API_EXPORT const void *GetCellUnitValueBlob(CellUnit *cellUnit, size_t *outSize)
187     {
188         *outSize = cellUnit->cell.stringOrBlobValue.size;
189         return OffsetToPtr(cellUnit->cell.stringOrBlobValue.offset, cellUnit->cell.stringOrBlobValue.size);
190     }
191 
192     /**
193      * @brief Obtains the mHeader of the current result set.
194      */
GetHeader()195     API_EXPORT const void *GetHeader()
196     {
197         return mHeader;
198     }
199 
200     /**
201      * @brief Obtains size of the used byte in the block.
202      */
GetUsedBytes()203     API_EXPORT size_t GetUsedBytes()
204     {
205         return mHeader->unusedOffset;
206     }
207 
208     /**
209      * @brief Obtains the name of the current result set.
210      */
Name()211     API_EXPORT std::string Name()
212     {
213         return mName;
214     }
215 
216     /**
217      * @brief Obtains the size of the current result set.
218      */
Size()219     API_EXPORT size_t Size()
220     {
221         return mSize;
222     }
223 
224     /**
225      * @brief Obtains the row number of the current result set.
226      */
GetRowNum()227     API_EXPORT uint32_t GetRowNum()
228     {
229         return mHeader->rowNums;
230     }
231 
232     /**
233      * @brief Obtains the column number of the current result set.
234      */
GetColumnNum()235     API_EXPORT uint32_t GetColumnNum()
236     {
237         return mHeader->columnNums;
238     }
239 
240     /**
241      * @brief Write message to parcel.
242      */
243     API_EXPORT int WriteMessageParcel(MessageParcel &parcel);
244 
245     /**
246      * @brief Read message to parcel.
247      */
248     API_EXPORT static int ReadMessageParcel(MessageParcel &parcel, SharedBlock *&block);
249 
250     /**
251      * @brief Write raw data in block.
252      */
253     API_EXPORT size_t SetRawData(const void *rawData, size_t size);
254 
255     /**
256      * @brief Obtains the fd of shared memory
257      */
GetFd()258     API_EXPORT int GetFd()
259     {
260         if (ashmem_ == nullptr) {
261             return -1;
262         }
263         return ashmem_->GetAshmemFd();
264     }
265 
266     /**
267      * @brief Obtains the start position of the current result set.
268      */
GetStartPos()269     API_EXPORT uint32_t GetStartPos()
270     {
271         return mHeader->startPos_;
272     }
273 
274     /**
275      * @brief Obtains the last position of the current result set.
276      */
GetLastPos()277     API_EXPORT uint32_t GetLastPos()
278     {
279         return mHeader->lastPos_;
280     }
281 
282     /**
283      * @brief Obtains the block position of the current result set.
284      */
GetBlockPos()285     API_EXPORT uint32_t GetBlockPos()
286     {
287         return mHeader->blockPos_;
288     }
289 
290     /**
291      * @brief Set the start position of the current result set.
292      */
SetStartPos(uint32_t startPos)293     API_EXPORT void SetStartPos(uint32_t startPos)
294     {
295         mHeader->startPos_ = startPos;
296     }
297 
298     /**
299      * @brief Set the last position of the current result set.
300      */
SetLastPos(uint32_t lastPos)301     API_EXPORT void SetLastPos(uint32_t lastPos)
302     {
303         mHeader->lastPos_ = lastPos;
304     }
305 
306     /**
307      * @brief Set the block position of the current result set.
308      */
SetBlockPos(uint32_t blockPos)309     API_EXPORT void SetBlockPos(uint32_t blockPos)
310     {
311         mHeader->blockPos_ = blockPos;
312     }
313 
314 private:
315     std::string mName;
316     sptr<Ashmem> ashmem_;
317     uint8_t *mData;
318     size_t mSize;
319     bool mReadOnly;
320     static const size_t ROW_NUM_IN_A_GROUP = 128;
321     static const uint32_t GROUP_NUM = 128;
322     /**
323     * Default setting for SQLITE_MAX_COLUMN is 2000.
324     * We can set it at compile time to as large as 32767
325     */
326     static const size_t COL_MAX_NUM = 32767;
327 
328     struct SharedBlockHeader {
329         /* Offset of the lowest unused byte in the block. */
330         uint32_t unusedOffset;
331         /* Row numbers of the row group block. */
332         uint32_t rowNums;
333         /* Column numbers of the row group block. */
334         uint32_t columnNums;
335         /* start position of the current block. */
336         uint32_t startPos_;
337         /* last position of the current block. */
338         uint32_t lastPos_;
339         /* current position of the current block. */
340         uint32_t blockPos_;
341         uint32_t groupOffset[GROUP_NUM];
342     };
343 
344     struct RowGroupHeader {
345         uint32_t rowOffsets[ROW_NUM_IN_A_GROUP];
346     };
347 
348     SharedBlockHeader *mHeader;
349 
350     /**
351      * Allocate a portion of the block. Returns the offset of the allocation.
352      * Returns 0 if there isn't enough space.
353      */
354     inline uint32_t Alloc(size_t size);
355 
356     inline uint32_t *AllocRowOffset();
357 
358     inline int PutBlobOrString(uint32_t row, uint32_t column, const void *value, size_t size, int32_t type);
359 
360     static int CreateSharedBlock(const std::string &name, size_t size, sptr<Ashmem> ashmem,
361         SharedBlock *&outSharedBlock);
362 
363     inline void *OffsetToPtr(uint32_t offset, uint32_t bufferSize = 0) {
364         if (offset + bufferSize > mSize) {
365             return nullptr;
366         }
367         return mData + offset;
368     }
369 };
370 } // namespace AppDataFwk
371 } // namespace OHOS
372 #endif
373