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 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 * Init current shared block. 80 */ 81 bool Init(); 82 83 /** 84 * Create a shared block. 85 */ 86 static int Create(const std::string &name, size_t size, SharedBlock *&outSharedBlock); 87 88 /** 89 * Clear current shared block. 90 */ 91 int Clear(); 92 93 /** 94 * Set a shared block column. 95 */ 96 int SetColumnNum(uint32_t numColumns); 97 98 /** 99 * Allocate a row unit and its directory. 100 */ 101 int AllocRow(); 102 103 /** 104 * Release the value of the last row. 105 */ 106 int FreeLastRow(); 107 108 /** 109 * Put blob data to the shared block. 110 */ 111 int PutBlob(uint32_t row, uint32_t column, const void *value, size_t Size); 112 113 /** 114 * Put string data to the shared block. 115 */ 116 int PutString(uint32_t row, uint32_t column, const char *value, size_t sizeIncludingNull); 117 118 /** 119 * Put long data to the shared block. 120 */ 121 int PutLong(uint32_t row, uint32_t column, int64_t value); 122 123 /** 124 * Put Double data to the shared block. 125 */ 126 int PutDouble(uint32_t row, uint32_t column, double value); 127 128 /** 129 * Put Null data to the shared block. 130 */ 131 int PutNull(uint32_t row, uint32_t column); 132 133 /** 134 * Gets the cell unit at the specified row and column. 135 */ 136 CellUnit *GetCellUnit(uint32_t row, uint32_t column); 137 138 /** 139 * Get string type data from cell unit. 140 */ GetCellUnitValueString(CellUnit * cellUnit,size_t * outSizeIncludingNull)141 const char *GetCellUnitValueString(CellUnit *cellUnit, size_t *outSizeIncludingNull) 142 { 143 *outSizeIncludingNull = cellUnit->cell.stringOrBlobValue.size; 144 return static_cast<char *>( 145 OffsetToPtr(cellUnit->cell.stringOrBlobValue.offset, cellUnit->cell.stringOrBlobValue.size)); 146 } 147 148 /** 149 * Get blob type data from cell unit. 150 */ GetCellUnitValueBlob(CellUnit * cellUnit,size_t * outSize)151 const void *GetCellUnitValueBlob(CellUnit *cellUnit, size_t *outSize) 152 { 153 *outSize = cellUnit->cell.stringOrBlobValue.size; 154 return OffsetToPtr(cellUnit->cell.stringOrBlobValue.offset, cellUnit->cell.stringOrBlobValue.size); 155 } 156 157 /** 158 * The mHeader of the current result set. 159 */ GetHeader()160 const void *GetHeader() 161 { 162 return mHeader; 163 } 164 165 /** 166 * Size of the used byte in the block. 167 */ GetUsedBytes()168 size_t GetUsedBytes() 169 { 170 return mHeader->unusedOffset; 171 } 172 173 /** 174 * The name of the current result set. 175 */ Name()176 std::string Name() 177 { 178 return mName; 179 } 180 181 /** 182 * The size of the current result set. 183 */ Size()184 size_t Size() 185 { 186 return mSize; 187 } 188 189 /** 190 * The row number of the current result set. 191 */ GetRowNum()192 uint32_t GetRowNum() 193 { 194 return mHeader->rowNums; 195 } 196 197 /** 198 * The column number of the current result set. 199 */ GetColumnNum()200 uint32_t GetColumnNum() 201 { 202 return mHeader->columnNums; 203 } 204 205 int WriteMessageParcel(MessageParcel &parcel); 206 207 static int ReadMessageParcel(MessageParcel &parcel, SharedBlock *&block); 208 /** 209 * Write raw data in block. 210 */ 211 size_t SetRawData(const void *rawData, size_t size); 212 /** 213 * The fd of shared memory 214 */ GetFd()215 int GetFd() 216 { 217 if (ashmem_ == nullptr) { 218 return -1; 219 } 220 return ashmem_->GetAshmemFd(); 221 } 222 private: 223 std::string mName; 224 sptr<Ashmem> ashmem_; 225 void *mData; 226 size_t mSize; 227 bool mReadOnly; 228 static const size_t ROW_OFFSETS_NUM = 100; 229 /** 230 * Default setting for SQLITE_MAX_COLUMN is 2000. 231 * We can set it at compile time to as large as 32767 232 */ 233 static const size_t COL_MAX_NUM = 32767; 234 235 struct SharedBlockHeader { 236 /* Offset of the lowest unused byte in the block. */ 237 uint32_t unusedOffset; 238 /* Offset of the first row group. */ 239 uint32_t firstRowGroupOffset; 240 /* Row numbers of the row group block. */ 241 uint32_t rowNums; 242 /* Column numbers of the row group block. */ 243 uint32_t columnNums; 244 }; 245 246 struct RowGroupHeader { 247 uint32_t rowOffsets[ROW_OFFSETS_NUM]; 248 uint32_t nextGroupOffset; 249 }; 250 251 SharedBlockHeader *mHeader; 252 253 /** 254 * Allocate a portion of the block. Returns the offset of the allocation. 255 * Returns 0 if there isn't enough space. 256 */ 257 uint32_t Alloc(size_t size, bool aligned = false); 258 259 uint32_t *GetRowOffset(uint32_t row); 260 261 uint32_t *AllocRowOffset(); 262 263 int PutBlobOrString(uint32_t row, uint32_t column, const void *value, size_t size, int32_t type); 264 265 static int CreateSharedBlock(const std::string &name, size_t size, sptr<Ashmem> ashmem, 266 SharedBlock *&outSharedBlock); 267 268 uint32_t OffsetFromPtr(void *ptr); 269 270 void *OffsetToPtr(uint32_t offset, uint32_t bufferSize = 0); 271 272 /** 273 * Convert utf8 string to utf16. 274 */ 275 static std::u16string ToUtf16(std::string str); 276 277 /** 278 * Convert utf16 string to utf8. 279 */ 280 static std::string ToUtf8(std::u16string str16); 281 }; 282 } // namespace AppDataFwk 283 } // namespace OHOS 284 #endif 285