1 /* 2 * Copyright (c) 2022 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 DISPLAY_COMMAND_DATA_PACKER_H_ 17 #define DISPLAY_COMMAND_DATA_PACKER_H_ 18 19 #include <memory> 20 #include <securec.h> 21 #include "hdf_log.h" 22 23 namespace OHOS { 24 namespace HDI { 25 namespace Display { 26 class CommandDataPacker { 27 public: CommandDataPacker()28 CommandDataPacker() 29 : packSize_(0), 30 writePos_(0), 31 curSecOffset_(0), 32 settingSecLen_(0), 33 curSecLenPos_(0), 34 data_(nullptr) 35 { 36 } 37 ~CommandDataPacker()38 ~CommandDataPacker() 39 { 40 if (data_ != nullptr) { 41 delete data_; 42 } 43 } 44 45 bool Init(size_t size = INIT_DATA_SIZE) 46 { 47 bool ret = true; 48 packSize_ = size; 49 uint32_t alignedSize = (packSize_ + ALLOC_PAGE_SIZE - 1) & (~(ALLOC_PAGE_SIZE - 1)); 50 data_ = new char[alignedSize](); 51 if (data_ == nullptr) { 52 HDF_LOGE("%{public}s: alloc memory failed", __func__); 53 ret = false; 54 } else { 55 packSize_ = alignedSize; 56 } 57 return ret; 58 } 59 WriteUint64(uint64_t value)60 bool WriteUint64(uint64_t value) 61 { 62 return Write<uint64_t>(value); 63 } 64 WriteUint32(uint32_t value)65 bool WriteUint32(uint32_t value) 66 { 67 return Write<uint32_t>(value); 68 } 69 WriteUint8(uint8_t value)70 bool WriteUint8(uint8_t value) 71 { 72 return Write<uint32_t>(value); 73 } 74 WriteInt32(int32_t value)75 bool WriteInt32(int32_t value) 76 { 77 return Write<int32_t>(value); 78 } 79 WriteBool(bool value)80 bool WriteBool(bool value) 81 { 82 return Write<int32_t>(value); 83 } 84 ValidSize()85 size_t ValidSize() 86 { 87 return writePos_; 88 } 89 PackSize()90 size_t PackSize() 91 { 92 return packSize_; 93 } 94 GetDataPtr()95 char *GetDataPtr() 96 { 97 return data_; 98 } 99 PackBegin(int32_t beginCmd)100 bool PackBegin(int32_t beginCmd) 101 { 102 writePos_ = 0; 103 settingSecLen_ = sizeof(int32_t); 104 curSecLenPos_ = 0; 105 curSecOffset_ = writePos_; 106 return WriteInt32(beginCmd); 107 } 108 109 bool BeginSection(int32_t cmdId, int32_t len = 0) 110 { 111 bool ret = false; 112 // len must be 4 byte alignment. 113 if ((len & SECTION_LEN_ALIGN - 1) != 0) { 114 HDF_LOGE("%{public}s: length is not aligned by 4 bytes", __func__); 115 } else { 116 ret = true; 117 } 118 // Update current data before next section. 119 if (ret == true) { 120 curSecOffset_ = writePos_; 121 if (WriteUint32(SECTION_END_MAGIC) == false) { 122 ret = false; 123 } else if (WriteInt32(cmdId) == true) { 124 curSecLenPos_ = writePos_; 125 settingSecLen_ = len; 126 // Now we don't write section len here, 127 // but write it on EndSection. 128 writePos_ += sizeof(uint32_t); 129 } else { 130 ret = false; 131 } 132 } 133 return ret; 134 } 135 EndSection()136 bool EndSection() 137 { 138 // Write cmd len before data related is updated. 139 if (writePos_ >= curSecOffset_) { 140 uint32_t actualLen = writePos_ - curSecOffset_; 141 uint32_t updatedLen = actualLen > settingSecLen_ ? actualLen : settingSecLen_; 142 *reinterpret_cast<uint32_t *>(data_ + curSecLenPos_) = updatedLen; 143 writePos_ = curSecOffset_ + updatedLen; 144 } else { 145 HDF_LOGE("%{public}s: writePos_(%{public}zu) before curSecOffset_(%{public}zu)", __func__, writePos_, 146 curSecOffset_); 147 return false; 148 } 149 return (writePos_ >= packSize_ ? false : true); 150 } 151 PackEnd(int32_t endCmd)152 bool PackEnd(int32_t endCmd) 153 { 154 bool ret = WriteInt32(endCmd); 155 if (writePos_ >= packSize_) { 156 HDF_LOGE("%{public}s: writePos_(%{public}zu) > packSize_(%{public}zu), write overflow.", __func__, 157 writePos_, curSecOffset_); 158 ret = false; 159 } 160 return ret; 161 } 162 Dump()163 void Dump() 164 { 165 HDF_LOGI("---------------------------------------------\n"); 166 HDF_LOGI("ALLOC_PAGE_SIZE =%{public}d\n", ALLOC_PAGE_SIZE); 167 HDF_LOGI("INIT_DATA_SIZE =%{public}d\n", INIT_DATA_SIZE); 168 HDF_LOGI("SECTION_END_MAGIC =0x%{public}x\n", SECTION_END_MAGIC); 169 HDF_LOGI("packSize_ =%{public}zu\n", packSize_); 170 HDF_LOGI("writePos_ =%{public}zu\n", writePos_); 171 HDF_LOGI("curSecOffset_ =%{public}zu\n", curSecOffset_); 172 HDF_LOGI("settingSecLen_ =%{public}d\n", settingSecLen_); 173 HDF_LOGI("curSecLenPos_ =%{public}zu\n", curSecLenPos_); 174 HDF_LOGI("data_ =%{public}p\n", data_); 175 uint32_t i = 0; 176 for (; sizeof(int32_t) * i < writePos_;) { 177 HDF_LOGI("%{public}08x ", *reinterpret_cast<uint32_t *>(data_ + sizeof(int32_t) * i)); 178 i++; 179 if ((i % DUMP_LINE_LEN) == 0) { 180 HDF_LOGI("\n"); 181 } else if ((i % DUMP_HALF_LINE_SPACE) == 0) { 182 HDF_LOGI(" "); 183 } else { 184 } 185 } 186 HDF_LOGI("\n"); 187 } 188 189 private: 190 template <typename T> Write(T value)191 bool Write(T value) 192 { 193 size_t writeSize = sizeof(T); 194 size_t newSize = writePos_ + writeSize; 195 if (newSize > packSize_) { 196 newSize = (newSize + ALLOC_PAGE_SIZE - 1) & (~(ALLOC_PAGE_SIZE - 1)); 197 198 char *newData = new char[newSize]; 199 if (memcpy_s(newData, newSize, data_, packSize_) != EOK) { 200 HDF_LOGE("%{public}s: memcpy_s failed", __func__); 201 return false; 202 } 203 data_ = newData; 204 packSize_ = newSize; 205 delete data_; 206 data_ = nullptr; 207 } 208 *reinterpret_cast<T *>(data_ + writePos_) = value; 209 writePos_ += writeSize; 210 211 return true; 212 } 213 214 private: 215 static constexpr uint32_t ALLOC_PAGE_SIZE = 1024; 216 static constexpr uint32_t INIT_DATA_SIZE = 32 * ALLOC_PAGE_SIZE; 217 static constexpr uint32_t SECTION_END_MAGIC = 0xB5B5B5B5; 218 static constexpr int32_t SECTION_LEN_ALIGN = 4; 219 static constexpr uint32_t DUMP_HALF_LINE_SPACE = 4; 220 static constexpr uint32_t DUMP_LINE_LEN = 8; 221 222 private: 223 size_t packSize_; 224 size_t writePos_; 225 size_t curSecOffset_; 226 uint32_t settingSecLen_; 227 size_t curSecLenPos_; 228 char *data_; 229 }; 230 } // namespace Display 231 } // namespace HDI 232 } // namespace OHOS 233 #endif // DISPLAY_COMMAND_DATA_PACKER_H_ 234