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