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