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