• 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 <inttypes.h>
20 
21 #include <string>
22 #include <ashmem.h>
23 #include "message_parcel.h"
24 #include "parcel.h"
25 #include "securec.h"
26 
27 namespace OHOS {
28 namespace AppDataFwk {
29 static const uint32_t INVALID_ROW_RECORD = 0xFFFFFFFF;
30 /**
31  * This class stores a set of rows from a database in a buffer,
32  * which is used as the set of query result.
33  */
34 class SharedBlock {
35 public:
36     /* Cell Unit types. */
37     enum {
38         CELL_UNIT_TYPE_NULL = 0,
39         CELL_UNIT_TYPE_INTEGER = 1,
40         CELL_UNIT_TYPE_FLOAT = 2,
41         CELL_UNIT_TYPE_STRING = 3,
42         CELL_UNIT_TYPE_BLOB = 4,
43     };
44 
45     /* SharedBlock error types. */
46     enum {
47         SHARED_BLOCK_OK = 0,
48         SHARED_BLOCK_BAD_VALUE = 1,
49         SHARED_BLOCK_NO_MEMORY = 2,
50         SHARED_BLOCK_INVALID_OPERATION = 3,
51         SHARED_BLOCK_ASHMEM_ERROR = 4,
52         SHARED_BLOCK_SET_PORT_ERROR = 5,
53     };
54 
55     /* Cell Unit */
56     struct CellUnit {
57         int32_t type;
58         union {
59             double doubleValue;
60             int64_t longValue;
61             struct {
62                 uint32_t offset;
63                 uint32_t size;
64             } stringOrBlobValue;
65         } cell;
66     } __attribute((packed));
67 
68     /**
69      * SharedBlock constructor.
70      */
71     SharedBlock(const std::string &name, sptr<Ashmem> ashmem, size_t size, bool readOnly);
72 
73     /**
74      * SharedBlock constructor.
75      */
76     ~SharedBlock();
77 
78     /**
79      * Create a shared block.
80      */
81     static int Create(const std::string &name, size_t size, SharedBlock *&outSharedBlock);
82 
83     /**
84      * Clear current shared block.
85      */
86     int Clear();
87 
88     /**
89      * Set a shared block column.
90      */
91     int SetColumnNum(uint32_t numColumns);
92 
93     /**
94      * Allocate a row unit and its directory.
95      */
96     int AllocRow();
97 
98     /**
99      * Release the value of the last row.
100      */
101     int FreeLastRow();
102 
103     /**
104      * Put blob data to the shared block.
105      */
106     int PutBlob(uint32_t row, uint32_t column, const void *value, size_t Size);
107 
108     /**
109      * Put string data to the shared block.
110      */
111     int PutString(uint32_t row, uint32_t column, const char *value, size_t sizeIncludingNull);
112 
113     /**
114      * Put long data to the shared block.
115      */
116     int PutLong(uint32_t row, uint32_t column, int64_t value);
117 
118     /**
119      * Put Double data to the shared block.
120      */
121     int PutDouble(uint32_t row, uint32_t column, double value);
122 
123     /**
124      * Put Null data to the shared block.
125      */
126     int PutNull(uint32_t row, uint32_t column);
127 
128     /**
129      * Gets the cell unit at the specified row and column.
130      */
131     CellUnit *GetCellUnit(uint32_t row, uint32_t column);
132 
133     /**
134      * Get string type data from cell unit.
135      */
GetCellUnitValueString(CellUnit * cellUnit,size_t * outSizeIncludingNull)136     const char *GetCellUnitValueString(CellUnit *cellUnit, size_t *outSizeIncludingNull)
137     {
138         *outSizeIncludingNull = cellUnit->cell.stringOrBlobValue.size;
139         return static_cast<char *>(
140             OffsetToPtr(cellUnit->cell.stringOrBlobValue.offset, cellUnit->cell.stringOrBlobValue.size));
141     }
142 
143     /**
144      * Get blob type data from cell unit.
145      */
GetCellUnitValueBlob(CellUnit * cellUnit,size_t * outSize)146     const void *GetCellUnitValueBlob(CellUnit *cellUnit, size_t *outSize)
147     {
148         *outSize = cellUnit->cell.stringOrBlobValue.size;
149         return OffsetToPtr(cellUnit->cell.stringOrBlobValue.offset, cellUnit->cell.stringOrBlobValue.size);
150     }
151 
152     /**
153      * The mHeader of the current result set.
154      */
GetHeader()155     const void *GetHeader()
156     {
157         return mHeader;
158     }
159 
160     /**
161      * Size of the used byte in the block.
162      */
GetUsedBytes()163     size_t GetUsedBytes()
164     {
165         return mHeader->unusedOffset;
166     }
167 
168     /**
169      * The name of the current result set.
170      */
Name()171     std::string Name()
172     {
173         return mName;
174     }
175 
176     /**
177      * The size of the current result set.
178      */
Size()179     size_t Size()
180     {
181         return mSize;
182     }
183 
184     /**
185      * The row number of the current result set.
186      */
GetRowNum()187     uint32_t GetRowNum()
188     {
189         return mHeader->rowNums;
190     }
191 
192     /**
193      * The column number of the current result set.
194      */
GetColumnNum()195     uint32_t GetColumnNum()
196     {
197         return mHeader->columnNums;
198     }
199 
200     int WriteMessageParcel(MessageParcel &parcel);
201 
202     static int ReadMessageParcel(MessageParcel &parcel, SharedBlock *&block);
203     /**
204      * Write raw data in block.
205      */
206     size_t SetRawData(const void *rawData, size_t size);
207     /**
208      * The fd of shared memory
209      */
GetFd()210     int GetFd()
211     {
212         if (ashmem_ == nullptr) {
213             return -1;
214         }
215         return ashmem_->GetAshmemFd();
216     }
217 private:
218     std::string mName;
219     sptr<Ashmem> ashmem_;
220     void *mData;
221     size_t mSize;
222     bool mReadOnly;
223     static const size_t ROW_OFFSETS_NUM = 100;
224     /**
225     * Default setting for SQLITE_MAX_COLUMN is 2000.
226     * We can set it at compile time to as large as 32767
227     */
228     static const size_t COL_MAX_NUM = 32767;
229 
230     struct SharedBlockHeader {
231         /* Offset of the lowest unused byte in the block. */
232         uint32_t unusedOffset;
233         /* Offset of the first row group. */
234         uint32_t firstRowGroupOffset;
235         /* Row numbers of the row group block. */
236         uint32_t rowNums;
237         /* Column numbers of the row group block. */
238         uint32_t columnNums;
239     };
240 
241     struct RowGroupHeader {
242         uint32_t rowOffsets[ROW_OFFSETS_NUM];
243         uint32_t nextGroupOffset;
244     };
245 
246     SharedBlockHeader *mHeader;
247 
248     /**
249      * Allocate a portion of the block. Returns the offset of the allocation.
250      * Returns 0 if there isn't enough space.
251      */
252     uint32_t Alloc(size_t size, bool aligned = false);
253 
254     uint32_t *GetRowOffset(uint32_t row);
255 
256     uint32_t *AllocRowOffset();
257 
258     int PutBlobOrString(uint32_t row, uint32_t column, const void *value, size_t size, int32_t type);
259 
260     static int CreateSharedBlock(const std::string &name, size_t size, sptr<Ashmem> ashmem,
261         SharedBlock *&outSharedBlock);
262 
263     uint32_t OffsetFromPtr(void *ptr);
264 
265     void *OffsetToPtr(uint32_t offset, uint32_t bufferSize = 0);
266 
267     /**
268      * Convert utf8 string to utf16.
269      */
270     static std::u16string ToUtf16(std::string str);
271 
272     /**
273      * Convert utf16 string to utf8.
274      */
275     static std::string ToUtf8(std::u16string str16);
276 };
277 } // namespace AppDataFwk
278 } // namespace OHOS
279 #endif
280