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_UNPACKER_H_ 17 #define DISPLAY_COMMAND_DATA_UNPACKER_H_ 18 19 #include <memory> 20 #include "hdf_log.h" 21 22 namespace OHOS { 23 namespace HDI { 24 namespace Display { 25 class CommandDataUnpacker { 26 public: CommandDataUnpacker()27 CommandDataUnpacker() : packSize_(0), readPos_(0), curSecOffset_(0), curSecLen_(0), data_(nullptr) {} 28 Init(char * unpackData,size_t size)29 void Init(char *unpackData, size_t size) 30 { 31 packSize_ = size; 32 data_ = unpackData; 33 return; 34 } 35 ReadUint64(uint64_t & value)36 bool ReadUint64(uint64_t &value) 37 { 38 return Read<uint64_t>(value); 39 } 40 ReadUint32(uint32_t & value)41 bool ReadUint32(uint32_t &value) 42 { 43 return Read<uint32_t>(value); 44 } 45 ReadUint8(uint8_t & value)46 bool ReadUint8(uint8_t &value) 47 { 48 int32_t intVal = 0; 49 bool ret = Read<int32_t>(intVal); 50 if (ret == true) { 51 value = static_cast<uint8_t>(intVal & 0xFF); 52 } 53 54 return ret; 55 } 56 ReadInt32(int32_t & value)57 bool ReadInt32(int32_t &value) 58 { 59 return Read<int32_t>(value); 60 } 61 ReadBool(bool & value)62 bool ReadBool(bool &value) 63 { 64 int32_t intVal = 0; 65 bool ret = Read<int32_t>(intVal); 66 if (ret == true) { 67 value = (intVal == 0 ? false : true); 68 } 69 70 return ret; 71 } 72 GetDataPtr()73 char *GetDataPtr() 74 { 75 return data_; 76 } 77 PackBegin(int32_t & beginCmd)78 bool PackBegin(int32_t &beginCmd) 79 { 80 readPos_ = 0; 81 curSecLen_ = sizeof(int32_t); 82 curSecOffset_ = readPos_; 83 84 return ReadInt32(beginCmd); 85 } 86 BeginSection(int32_t & cmdId)87 bool BeginSection(int32_t &cmdId) 88 { 89 uint32_t magic; 90 curSecOffset_ = readPos_; 91 92 bool ret = ReadUint32(magic); 93 if (ret == true) { 94 ret = (magic == SECTION_END_MAGIC ? true : false); 95 } 96 if (ret == true && !(ReadInt32(cmdId) && ReadUint32(curSecLen_))) { 97 HDF_LOGE("error: cmdId=%{public}d or curSecLen_=%{public}d error.", cmdId, curSecLen_); 98 ret = false; 99 } 100 return ret; 101 } 102 NextSection()103 bool NextSection() 104 { 105 readPos_ = curSecOffset_ + curSecLen_; 106 bool ret = ((readPos_ >= (packSize_ - COMMAND_ID_SIZE)) ? false : true); 107 return ret; 108 } 109 PackEnd(int32_t & endCmd)110 bool PackEnd(int32_t &endCmd) 111 { 112 bool ret = ReadInt32(endCmd); 113 if ((ret == true) && (readPos_ == packSize_)) { 114 ret = true; 115 } else { 116 HDF_LOGE("error: readPos_(%{public}zu) > packSize_(%{public}zu), read overflow.", readPos_, curSecOffset_); 117 ret = false; 118 } 119 return ret; 120 } 121 Dump()122 void Dump() 123 { 124 HDF_LOGI("---------------------------------------------\n"); 125 HDF_LOGI("SECTION_END_MAGIC =0x%{public}x\n", SECTION_END_MAGIC); 126 HDF_LOGI("COMMAND_ID_SIZE =%{public}d\n", COMMAND_ID_SIZE); 127 HDF_LOGI("packSize_ =%{public}zu\n", packSize_); 128 HDF_LOGI("readPos_ =%{public}zu\n", readPos_); 129 HDF_LOGI("curSecOffset_ =%{public}zu\n", curSecOffset_); 130 HDF_LOGI("curSecLen_ =%{public}d\n", curSecLen_); 131 HDF_LOGI("data_ =%{public}p\n", data_); 132 uint32_t i = 0; 133 for (; sizeof(int32_t) * i < packSize_;) { 134 HDF_LOGI("%{public}08x ", *reinterpret_cast<uint32_t *>(data_ + sizeof(int32_t) * i)); 135 i++; 136 if (i % DUMP_LINE_LEN == 0) { 137 HDF_LOGI("\n"); 138 } else if (i % SECTION_LEN_ALIGN == 0) { 139 HDF_LOGI(" "); 140 } else { 141 } 142 } 143 HDF_LOGI("\n"); 144 } 145 146 private: 147 template <typename T> Read(T & value)148 bool Read(T &value) 149 { 150 size_t dataSize = sizeof(T); 151 152 if (readPos_ + dataSize > packSize_) { 153 HDF_LOGE("Read overflow, readPos=%{public}zu + %{public}zu}, packSize=%{public}zu.", readPos_, dataSize, 154 packSize_); 155 return false; 156 } 157 158 value = *reinterpret_cast<T *>(data_ + readPos_); 159 readPos_ += dataSize; 160 161 return true; 162 } 163 164 private: 165 static constexpr uint32_t SECTION_END_MAGIC = 0xB5B5B5B5; 166 static constexpr uint32_t COMMAND_ID_SIZE = sizeof(int32_t); 167 static constexpr int32_t SECTION_LEN_ALIGN = 4; 168 static constexpr uint32_t DUMP_HALF_LINE_SPACE = 4; 169 static constexpr uint32_t DUMP_LINE_LEN = 8; 170 171 private: 172 size_t packSize_; 173 size_t readPos_; 174 size_t curSecOffset_; 175 uint32_t curSecLen_; 176 char *data_; 177 }; 178 } // namespace Display 179 } // namespace HDI 180 } // namespace OHOS 181 #endif // DISPLAY_COMMAND_DATA_UNPACKER_H_ 182