1c5e268c6Sopenharmony_ci/*
2c5e268c6Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3c5e268c6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c5e268c6Sopenharmony_ci * you may not use this file except in compliance with the License.
5c5e268c6Sopenharmony_ci * You may obtain a copy of the License at
6c5e268c6Sopenharmony_ci *
7c5e268c6Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8c5e268c6Sopenharmony_ci *
9c5e268c6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c5e268c6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c5e268c6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c5e268c6Sopenharmony_ci * See the License for the specific language governing permissions and
13c5e268c6Sopenharmony_ci * limitations under the License.
14c5e268c6Sopenharmony_ci */
15c5e268c6Sopenharmony_ci
16c5e268c6Sopenharmony_ci#ifndef DISPLAY_COMMAND_DATA_UNPACKER_H
17c5e268c6Sopenharmony_ci#define DISPLAY_COMMAND_DATA_UNPACKER_H
18c5e268c6Sopenharmony_ci
19c5e268c6Sopenharmony_ci#include <memory>
20c5e268c6Sopenharmony_ci#include "common/include/display_interface_utils.h"
21c5e268c6Sopenharmony_ci#include "hilog/log.h"
22c5e268c6Sopenharmony_ci
23c5e268c6Sopenharmony_cinamespace OHOS {
24c5e268c6Sopenharmony_cinamespace HDI {
25c5e268c6Sopenharmony_cinamespace Display {
26c5e268c6Sopenharmony_ciclass CommandDataUnpacker {
27c5e268c6Sopenharmony_cipublic:
28c5e268c6Sopenharmony_ci    CommandDataUnpacker() : packSize_(0), readPos_(0), curSecOffset_(0), curSecLen_(0), data_(nullptr) {}
29c5e268c6Sopenharmony_ci
30c5e268c6Sopenharmony_ci    void Init(char* unpackData, size_t size)
31c5e268c6Sopenharmony_ci    {
32c5e268c6Sopenharmony_ci        packSize_ = size;
33c5e268c6Sopenharmony_ci        data_ = unpackData;
34c5e268c6Sopenharmony_ci        return;
35c5e268c6Sopenharmony_ci    }
36c5e268c6Sopenharmony_ci
37c5e268c6Sopenharmony_ci    bool ReadUint64(uint64_t& value)
38c5e268c6Sopenharmony_ci    {
39c5e268c6Sopenharmony_ci        return Read<uint64_t>(value);
40c5e268c6Sopenharmony_ci    }
41c5e268c6Sopenharmony_ci
42c5e268c6Sopenharmony_ci    bool ReadUint32(uint32_t& value)
43c5e268c6Sopenharmony_ci    {
44c5e268c6Sopenharmony_ci        return Read<uint32_t>(value);
45c5e268c6Sopenharmony_ci    }
46c5e268c6Sopenharmony_ci
47c5e268c6Sopenharmony_ci    bool ReadUint8(uint8_t& value)
48c5e268c6Sopenharmony_ci    {
49c5e268c6Sopenharmony_ci        uint32_t intVal = 0;
50c5e268c6Sopenharmony_ci        bool ret = Read<uint32_t>(intVal);
51c5e268c6Sopenharmony_ci        if (ret == true) {
52c5e268c6Sopenharmony_ci            value = static_cast<uint8_t>(intVal & 0xFF);
53c5e268c6Sopenharmony_ci        }
54c5e268c6Sopenharmony_ci
55c5e268c6Sopenharmony_ci        return ret;
56c5e268c6Sopenharmony_ci    }
57c5e268c6Sopenharmony_ci
58c5e268c6Sopenharmony_ci    bool ReadInt32(int32_t& value)
59c5e268c6Sopenharmony_ci    {
60c5e268c6Sopenharmony_ci        return Read<int32_t>(value);
61c5e268c6Sopenharmony_ci    }
62c5e268c6Sopenharmony_ci
63c5e268c6Sopenharmony_ci    bool ReadBool(bool& value)
64c5e268c6Sopenharmony_ci    {
65c5e268c6Sopenharmony_ci        int32_t intVal = 0;
66c5e268c6Sopenharmony_ci        bool ret = Read<int32_t>(intVal);
67c5e268c6Sopenharmony_ci        if (ret == true) {
68c5e268c6Sopenharmony_ci            value = (intVal == 0 ? false : true);
69c5e268c6Sopenharmony_ci        }
70c5e268c6Sopenharmony_ci
71c5e268c6Sopenharmony_ci        return ret;
72c5e268c6Sopenharmony_ci    }
73c5e268c6Sopenharmony_ci
74c5e268c6Sopenharmony_ci    char *GetDataPtr()
75c5e268c6Sopenharmony_ci    {
76c5e268c6Sopenharmony_ci        return data_;
77c5e268c6Sopenharmony_ci    }
78c5e268c6Sopenharmony_ci
79c5e268c6Sopenharmony_ci    bool PackBegin(int32_t& beginCmd)
80c5e268c6Sopenharmony_ci    {
81c5e268c6Sopenharmony_ci        readPos_ = 0;
82c5e268c6Sopenharmony_ci        curSecLen_ = sizeof(int32_t);
83c5e268c6Sopenharmony_ci        curSecOffset_ = readPos_;
84c5e268c6Sopenharmony_ci
85c5e268c6Sopenharmony_ci        DISPLAY_CHK_RETURN(ReadInt32(beginCmd) == false, false,
86c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s, read beginCmd error", __func__));
87c5e268c6Sopenharmony_ci        return true;
88c5e268c6Sopenharmony_ci    }
89c5e268c6Sopenharmony_ci
90c5e268c6Sopenharmony_ci    bool BeginSection(int32_t& cmdId)
91c5e268c6Sopenharmony_ci    {
92c5e268c6Sopenharmony_ci        uint32_t magic;
93c5e268c6Sopenharmony_ci        curSecOffset_ = readPos_;
94c5e268c6Sopenharmony_ci
95c5e268c6Sopenharmony_ci        DISPLAY_CHK_RETURN(ReadUint32(magic) == false, false,
96c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s, read magic error", __func__));
97c5e268c6Sopenharmony_ci        DISPLAY_CHK_RETURN(magic != SECTION_END_MAGIC, false,
98c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s, err: magic number is corrupted", __func__));
99c5e268c6Sopenharmony_ci        DISPLAY_CHK_RETURN(ReadInt32(cmdId) == false, false,
100c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s, read cmdId error", __func__));
101c5e268c6Sopenharmony_ci        DISPLAY_CHK_RETURN(ReadUint32(curSecLen_) == false, false,
102c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s, read curSecLen_ error", __func__));
103c5e268c6Sopenharmony_ci        return true;
104c5e268c6Sopenharmony_ci    }
105c5e268c6Sopenharmony_ci
106c5e268c6Sopenharmony_ci    bool NextSection()
107c5e268c6Sopenharmony_ci    {
108c5e268c6Sopenharmony_ci        readPos_ = curSecOffset_ + curSecLen_;
109c5e268c6Sopenharmony_ci        if (readPos_ >= (packSize_ - COMMAND_ID_SIZE)) {
110c5e268c6Sopenharmony_ci            return false;
111c5e268c6Sopenharmony_ci        }
112c5e268c6Sopenharmony_ci        return true;
113c5e268c6Sopenharmony_ci    }
114c5e268c6Sopenharmony_ci
115c5e268c6Sopenharmony_ci    bool PackEnd(int32_t& endCmd)
116c5e268c6Sopenharmony_ci    {
117c5e268c6Sopenharmony_ci        DISPLAY_CHK_RETURN(ReadInt32(endCmd) == false, false,
118c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s, endCmd error", __func__));
119c5e268c6Sopenharmony_ci        DISPLAY_CHK_RETURN(readPos_ != packSize_, false,
120c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s, error: eadPos_ != packSize_", __func__));
121c5e268c6Sopenharmony_ci        return true;
122c5e268c6Sopenharmony_ci    }
123c5e268c6Sopenharmony_ci
124c5e268c6Sopenharmony_ci    void Dump()
125c5e268c6Sopenharmony_ci    {
126c5e268c6Sopenharmony_ci        HDF_LOGI("---------------------------------------------\n");
127c5e268c6Sopenharmony_ci        HDF_LOGI("SECTION_END_MAGIC =0x%{public}x\n", SECTION_END_MAGIC);
128c5e268c6Sopenharmony_ci        HDF_LOGI("COMMAND_ID_SIZE   =%{public}d\n", COMMAND_ID_SIZE);
129c5e268c6Sopenharmony_ci        HDF_LOGI("packSize_         =%{public}zu\n", packSize_);
130c5e268c6Sopenharmony_ci        HDF_LOGI("readPos_          =%{public}zu\n", readPos_);
131c5e268c6Sopenharmony_ci        HDF_LOGI("curSecOffset_     =%{public}zu\n", curSecOffset_);
132c5e268c6Sopenharmony_ci        HDF_LOGI("curSecLen_        =%{public}d\n", curSecLen_);
133c5e268c6Sopenharmony_ci        uint32_t i = 0;
134c5e268c6Sopenharmony_ci        for (; sizeof(int32_t) * i < packSize_;) {
135c5e268c6Sopenharmony_ci            HDF_LOGI("%{public}08x ", *reinterpret_cast<uint32_t *>(data_ + sizeof(int32_t) * i));
136c5e268c6Sopenharmony_ci            i++;
137c5e268c6Sopenharmony_ci            if (i % DUMP_LINE_LEN == 0) {
138c5e268c6Sopenharmony_ci                HDF_LOGI("\n");
139c5e268c6Sopenharmony_ci            } else if (i % SECTION_LEN_ALIGN == 0) {
140c5e268c6Sopenharmony_ci                HDF_LOGI(" ");
141c5e268c6Sopenharmony_ci            } else {
142c5e268c6Sopenharmony_ci            }
143c5e268c6Sopenharmony_ci        }
144c5e268c6Sopenharmony_ci        HDF_LOGI("\n");
145c5e268c6Sopenharmony_ci    }
146c5e268c6Sopenharmony_ci
147c5e268c6Sopenharmony_ciprivate:
148c5e268c6Sopenharmony_ci    template <typename T>
149c5e268c6Sopenharmony_ci    bool Read(T& value)
150c5e268c6Sopenharmony_ci    {
151c5e268c6Sopenharmony_ci        size_t dataSize = sizeof(T);
152c5e268c6Sopenharmony_ci
153c5e268c6Sopenharmony_ci        if (readPos_ + dataSize > packSize_) {
154c5e268c6Sopenharmony_ci            HDF_LOGE("Read overflow, readPos=%{public}zu + %{public}zu}, packSize=%{public}zu.",
155c5e268c6Sopenharmony_ci                readPos_, dataSize, packSize_);
156c5e268c6Sopenharmony_ci            return false;
157c5e268c6Sopenharmony_ci        }
158c5e268c6Sopenharmony_ci
159c5e268c6Sopenharmony_ci        value = *reinterpret_cast<T *>(data_ + readPos_);
160c5e268c6Sopenharmony_ci        readPos_ += dataSize;
161c5e268c6Sopenharmony_ci
162c5e268c6Sopenharmony_ci        return true;
163c5e268c6Sopenharmony_ci    }
164c5e268c6Sopenharmony_ci
165c5e268c6Sopenharmony_ciprivate:
166c5e268c6Sopenharmony_ci    static constexpr uint32_t SECTION_END_MAGIC = 0xB5B5B5B5;
167c5e268c6Sopenharmony_ci    static constexpr uint32_t COMMAND_ID_SIZE = sizeof(int32_t);
168c5e268c6Sopenharmony_ci    static constexpr int32_t SECTION_LEN_ALIGN = 4;
169c5e268c6Sopenharmony_ci    static constexpr uint32_t DUMP_HALF_LINE_SPACE = 4;
170c5e268c6Sopenharmony_ci    static constexpr uint32_t DUMP_LINE_LEN = 8;
171c5e268c6Sopenharmony_ci
172c5e268c6Sopenharmony_ciprivate:
173c5e268c6Sopenharmony_ci    size_t packSize_;
174c5e268c6Sopenharmony_ci    size_t readPos_;
175c5e268c6Sopenharmony_ci    size_t curSecOffset_;
176c5e268c6Sopenharmony_ci    uint32_t curSecLen_;
177c5e268c6Sopenharmony_ci    char *data_;
178c5e268c6Sopenharmony_ci};
179c5e268c6Sopenharmony_ci} // namespace Display
180c5e268c6Sopenharmony_ci} // namespace HDI
181c5e268c6Sopenharmony_ci} // namespace OHOS
182c5e268c6Sopenharmony_ci#endif // DISPLAY_COMMAND_DATA_UNPACKER_H
183