• 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 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     API_EXPORT ~SharedBlock();
102 
103     /**
104      * @brief Create a shared block.
105      */
106     API_EXPORT static int Create(const std::string &name, size_t size, SharedBlock *&outSharedBlock);
107 
108     /**
109      * @brief Clear current shared block.
110      */
111     API_EXPORT int Clear();
112 
113     /**
114      * @brief Set a shared block column.
115      */
116     API_EXPORT int SetColumnNum(uint32_t numColumns);
117 
118     /**
119      * @brief Allocate a row unit and its directory.
120      */
121     API_EXPORT int AllocRow();
122 
123     /**
124      * @brief Release the value of the last row.
125      */
126     API_EXPORT int FreeLastRow();
127 
128     /**
129      * @brief Put blob data to the shared block.
130      */
131     API_EXPORT int PutBlob(uint32_t row, uint32_t column, const void *value, size_t Size);
132 
133     /**
134      * @brief Put string data to the shared block.
135      */
136     API_EXPORT int PutString(uint32_t row, uint32_t column, const char *value, size_t sizeIncludingNull);
137 
138     /**
139      * @brief Put long data to the shared block.
140      */
141     API_EXPORT int PutLong(uint32_t row, uint32_t column, int64_t value);
142 
143     /**
144      * @brief Put Double data to the shared block.
145      */
146     API_EXPORT int PutDouble(uint32_t row, uint32_t column, double value);
147 
148     /**
149      * @brief Put Asset data to the shared block.
150      */
151     API_EXPORT int PutAsset(uint32_t row, uint32_t column, const void *value, size_t size);
152 
153     /**
154      * @brief Put Assets data to the shared block.
155      */
156     API_EXPORT int PutAssets(uint32_t row, uint32_t column, const void *value, size_t size);
157 
158     /**
159      * @brief Put vector<float> data to the shared block.
160      */
161     API_EXPORT int PutFloats(uint32_t row, uint32_t column, const void *value, size_t size);
162 
163     /**
164      * @brief Put BigInt data to the shared block.
165      */
166     API_EXPORT int PutBigInt(uint32_t row, uint32_t column, const void *value, size_t size);
167 
168     /**
169      * @brief Put Null data to the shared block.
170      */
171     API_EXPORT int PutNull(uint32_t row, uint32_t column);
172 
173     /**
174      * @brief Obtains the cell unit at the specified row and column.
175      */
176     API_EXPORT CellUnit *GetCellUnit(uint32_t row, uint32_t column);
177 
178     /**
179      * @brief Obtains string type data from cell unit.
180      */
GetCellUnitValueString(CellUnit * cellUnit,size_t * outSizeIncludingNull)181     API_EXPORT const char *GetCellUnitValueString(CellUnit *cellUnit, size_t *outSizeIncludingNull)
182     {
183         if (cellUnit == nullptr || outSizeIncludingNull == nullptr) {
184             return nullptr;
185         }
186         *outSizeIncludingNull = cellUnit->cell.stringOrBlobValue.size;
187         return static_cast<char *>(
188             OffsetToPtr(cellUnit->cell.stringOrBlobValue.offset, cellUnit->cell.stringOrBlobValue.size));
189     }
190 
191     /**
192      * @brief Obtains blob type data from cell unit.
193      */
GetCellUnitValueBlob(CellUnit * cellUnit,size_t * outSize)194     API_EXPORT const void *GetCellUnitValueBlob(CellUnit *cellUnit, size_t *outSize)
195     {
196         if (cellUnit == nullptr || outSize == nullptr) {
197             return nullptr;
198         }
199         *outSize = cellUnit->cell.stringOrBlobValue.size;
200         return OffsetToPtr(cellUnit->cell.stringOrBlobValue.offset, cellUnit->cell.stringOrBlobValue.size);
201     }
202 
203     /**
204      * @brief Obtains the mHeader of the current result set.
205      */
GetHeader()206     API_EXPORT const void *GetHeader()
207     {
208         return mHeader;
209     }
210 
211     /**
212      * @brief Obtains size of the used byte in the block.
213      */
GetUsedBytes()214     API_EXPORT size_t GetUsedBytes()
215     {
216         return mHeader->unusedOffset;
217     }
218 
219     /**
220      * @brief Obtains the name of the current result set.
221      */
Name()222     API_EXPORT std::string Name()
223     {
224         return mName;
225     }
226 
227     /**
228      * @brief Obtains the size of the current result set.
229      */
Size()230     API_EXPORT size_t Size()
231     {
232         return mSize;
233     }
234 
235     /**
236      * @brief Obtains the row number of the current result set.
237      */
GetRowNum()238     API_EXPORT uint32_t GetRowNum()
239     {
240         return mHeader->rowNums;
241     }
242 
243     /**
244      * @brief Obtains the column number of the current result set.
245      */
GetColumnNum()246     API_EXPORT uint32_t GetColumnNum()
247     {
248         return mHeader->columnNums;
249     }
250 
251     /**
252      * @brief Write message to parcel.
253      */
254     API_EXPORT int WriteMessageParcel(MessageParcel &parcel);
255 
256     /**
257      * @brief Read message to parcel.
258      */
259     API_EXPORT static int ReadMessageParcel(MessageParcel &parcel, SharedBlock *&block);
260 
261     /**
262      * @brief Write raw data in block.
263      */
264     API_EXPORT size_t SetRawData(const void *rawData, size_t size);
265 
266     /**
267      * @brief Obtains the fd of shared memory
268      */
GetFd()269     API_EXPORT int GetFd()
270     {
271         if (ashmem_ == nullptr) {
272             return -1;
273         }
274         return ashmem_->GetAshmemFd();
275     }
276 
277     /**
278      * @brief Obtains the start position of the current result set.
279      */
GetStartPos()280     API_EXPORT uint32_t GetStartPos()
281     {
282         return mHeader->startPos_;
283     }
284 
285     /**
286      * @brief Obtains the last position of the current result set.
287      */
GetLastPos()288     API_EXPORT uint32_t GetLastPos()
289     {
290         return mHeader->lastPos_;
291     }
292 
293     /**
294      * @brief Obtains the block position of the current result set.
295      */
GetBlockPos()296     API_EXPORT uint32_t GetBlockPos()
297     {
298         return mHeader->blockPos_;
299     }
300 
301     /**
302      * @brief Set the start position of the current result set.
303      */
SetStartPos(uint32_t startPos)304     API_EXPORT void SetStartPos(uint32_t startPos)
305     {
306         mHeader->startPos_ = startPos;
307     }
308 
309     /**
310      * @brief Set the last position of the current result set.
311      */
SetLastPos(uint32_t lastPos)312     API_EXPORT void SetLastPos(uint32_t lastPos)
313     {
314         mHeader->lastPos_ = lastPos;
315     }
316 
317     /**
318      * @brief Set the block position of the current result set.
319      */
SetBlockPos(uint32_t blockPos)320     API_EXPORT void SetBlockPos(uint32_t blockPos)
321     {
322         mHeader->blockPos_ = blockPos;
323     }
324 
325 private:
326     std::string mName;
327     sptr<Ashmem> ashmem_;
328     uint8_t *mData;
329     size_t mSize;
330     bool mReadOnly;
331     static const size_t ROW_NUM_IN_A_GROUP = 128;
332     static const uint32_t GROUP_NUM = 128;
333     /**
334     * Default setting for SQLITE_MAX_COLUMN is 2000.
335     * We can set it at compile time to as large as 32767
336     */
337     static const size_t COL_MAX_NUM = 32767;
338 
339     struct SharedBlockHeader {
340         /* Offset of the lowest unused byte in the block. */
341         uint32_t unusedOffset;
342         /* Row numbers of the row group block. */
343         uint32_t rowNums;
344         /* Column numbers of the row group block. */
345         uint32_t columnNums;
346         /* start position of the current block. */
347         uint32_t startPos_;
348         /* last position of the current block. */
349         uint32_t lastPos_;
350         /* current position of the current block. */
351         uint32_t blockPos_;
352         uint32_t groupOffset[GROUP_NUM];
353     };
354 
355     struct RowGroupHeader {
356         uint32_t rowOffsets[ROW_NUM_IN_A_GROUP];
357     };
358 
359     SharedBlockHeader *mHeader;
360 
361     SharedBlock(const std::string &name, sptr<Ashmem> ashmem, size_t size, bool readOnly);
362 
363     bool Init();
364 
365     /**
366      * Allocate a portion of the block. Returns the offset of the allocation.
367      * Returns 0 if there isn't enough space.
368      */
369     inline uint32_t Alloc(size_t size);
370 
371     inline uint32_t *AllocRowOffset();
372 
373     inline int PutBlobOrString(uint32_t row, uint32_t column, const void *value, size_t size, int32_t type);
374 
375     static int CreateSharedBlock(
376         const std::string &name, size_t size, sptr<Ashmem> ashmem, SharedBlock *&outSharedBlock);
377 
378     inline void *OffsetToPtr(uint32_t offset, uint32_t bufferSize = 0)
379     {
380         uint32_t safeOffset = offset;
381         if (safeOffset + bufferSize > mSize) {
382             return nullptr;
383         }
384         return mData + safeOffset;
385     }
386 };
387 } // namespace AppDataFwk
388 } // namespace OHOS
389 #endif
390