• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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