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