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