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