* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DISPLAY_COMMAND_DATA_UNPACKER_H
#define DISPLAY_COMMAND_DATA_UNPACKER_H
#include <memory>
#include "common/include/display_interface_utils.h"
#include "hilog/log.h"
namespace OHOS {
namespace HDI {
namespace Display {
class CommandDataUnpacker {
public:
CommandDataUnpacker() : packSize_(0), readPos_(0), curSecOffset_(0), curSecLen_(0), data_(nullptr) {}
void Init(char* unpackData, size_t size)
{
packSize_ = size;
data_ = unpackData;
return;
}
bool ReadUint64(uint64_t& value)
{
return Read<uint64_t>(value);
}
bool ReadUint32(uint32_t& value)
{
return Read<uint32_t>(value);
}
bool ReadUint8(uint8_t& value)
{
uint32_t intVal = 0;
bool ret = Read<uint32_t>(intVal);
if (ret == true) {
value = static_cast<uint8_t>(intVal & 0xFF);
}
return ret;
}
bool ReadInt32(int32_t& value)
{
return Read<int32_t>(value);
}
bool ReadBool(bool& value)
{
int32_t intVal = 0;
bool ret = Read<int32_t>(intVal);
if (ret == true) {
value = (intVal == 0 ? false : true);
}
return ret;
}
char *GetDataPtr()
{
return data_;
}
bool PackBegin(int32_t& beginCmd)
{
readPos_ = 0;
curSecLen_ = sizeof(int32_t);
curSecOffset_ = readPos_;
DISPLAY_CHK_RETURN(ReadInt32(beginCmd) == false, false,
HDF_LOGE("%{public}s, read beginCmd error", __func__));
return true;
}
bool BeginSection(int32_t& cmdId)
{
uint32_t magic;
curSecOffset_ = readPos_;
DISPLAY_CHK_RETURN(ReadUint32(magic) == false, false,
HDF_LOGE("%{public}s, read magic error", __func__));
DISPLAY_CHK_RETURN(magic != SECTION_END_MAGIC, false,
HDF_LOGE("%{public}s, err: magic number is corrupted", __func__));
DISPLAY_CHK_RETURN(ReadInt32(cmdId) == false, false,
HDF_LOGE("%{public}s, read cmdId error", __func__));
DISPLAY_CHK_RETURN(ReadUint32(curSecLen_) == false, false,
HDF_LOGE("%{public}s, read curSecLen_ error", __func__));
return true;
}
bool NextSection()
{
readPos_ = curSecOffset_ + curSecLen_;
if (readPos_ >= (packSize_ - COMMAND_ID_SIZE)) {
return false;
}
return true;
}
bool PackEnd(int32_t& endCmd)
{
DISPLAY_CHK_RETURN(ReadInt32(endCmd) == false, false,
HDF_LOGE("%{public}s, endCmd error", __func__));
DISPLAY_CHK_RETURN(readPos_ != packSize_, false,
HDF_LOGE("%{public}s, error: eadPos_ != packSize_", __func__));
return true;
}
void Dump()
{
HDF_LOGI("---------------------------------------------\n");
HDF_LOGI("SECTION_END_MAGIC =0x%{public}x\n", SECTION_END_MAGIC);
HDF_LOGI("COMMAND_ID_SIZE =%{public}d\n", COMMAND_ID_SIZE);
HDF_LOGI("packSize_ =%{public}zu\n", packSize_);
HDF_LOGI("readPos_ =%{public}zu\n", readPos_);
HDF_LOGI("curSecOffset_ =%{public}zu\n", curSecOffset_);
HDF_LOGI("curSecLen_ =%{public}d\n", curSecLen_);
uint32_t i = 0;
for (; sizeof(int32_t) * i < packSize_;) {
HDF_LOGI("%{public}08x ", *reinterpret_cast<uint32_t *>(data_ + sizeof(int32_t) * i));
i++;
if (i % DUMP_LINE_LEN == 0) {
HDF_LOGI("\n");
} else if (i % SECTION_LEN_ALIGN == 0) {
HDF_LOGI(" ");
} else {
}
}
HDF_LOGI("\n");
}
private:
template <typename T>
bool Read(T& value)
{
size_t dataSize = sizeof(T);
if (readPos_ + dataSize > packSize_) {
HDF_LOGE("Read overflow, readPos=%{public}zu + %{public}zu}, packSize=%{public}zu.",
readPos_, dataSize, packSize_);
return false;
}
value = *reinterpret_cast<T *>(data_ + readPos_);
readPos_ += dataSize;
return true;
}
private:
static constexpr uint32_t SECTION_END_MAGIC = 0xB5B5B5B5;
static constexpr uint32_t COMMAND_ID_SIZE = sizeof(int32_t);
static constexpr int32_t SECTION_LEN_ALIGN = 4;
static constexpr uint32_t DUMP_HALF_LINE_SPACE = 4;
static constexpr uint32_t DUMP_LINE_LEN = 8;
private:
size_t packSize_;
size_t readPos_;
size_t curSecOffset_;
uint32_t curSecLen_;
char *data_;
};
}
}
}
#endif