1 /*
2 * Copyright (C) 2024 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 #include <array>
16 #include <cctype>
17 #include <climits>
18 #include <cmath>
19 #include <cstring>
20 #include <iomanip>
21 #include <numeric>
22 #include <sstream>
23 #include <utility>
24
25 #include "image_log.h"
26 #include "data_buf.h"
27
28 #undef LOG_DOMAIN
29 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
30
31 #undef LOG_TAG
32 #define LOG_TAG "DataBuffer"
33
34 namespace OHOS {
35 namespace Media {
36 const uint32_t BYTE_1_MASK = 0x000000ffU;
37 const uint32_t BYTE_2_MASK = 0x0000ff00U;
38 const uint32_t BYTE_3_MASK = 0x00ff0000U;
39 const uint32_t BYTE_4_MASK = 0xff000000U;
40
41 const uint32_t BYTE_1_SHIFT = 0;
42 const uint32_t BYTE_2_SHIFT = 8;
43 const uint32_t BYTE_3_SHIFT = 16;
44 const uint32_t BYTE_4_SHIFT = 24;
45
46 const uint32_t BYTE_1_POSITION = 0;
47 const uint32_t BYTE_2_POSITION = 1;
48 const uint32_t BYTE_3_POSITION = 2;
49 const uint32_t BYTE_4_POSITION = 3;
50
51 const size_t UINT32_SIZE = 4;
52
53 const uint16_t LOWER_BYTE_MASK = 0x00ffU;
54 const uint16_t UPPER_BYTE_MASK = 0xff00U;
55
DataBuf(size_t size)56 DataBuf::DataBuf(size_t size) : pData_(size) {}
57
DataBuf(const byte * pData,size_t size)58 DataBuf::DataBuf(const byte *pData, size_t size) : pData_(size)
59 {
60 std::copy_n(pData, size, pData_.begin());
61 }
62
Resize(size_t size)63 void DataBuf::Resize(size_t size)
64 {
65 pData_.resize(size);
66 }
67
Reset()68 void DataBuf::Reset()
69 {
70 pData_.clear();
71 }
72
ReadUInt8(size_t offset) const73 uint8_t DataBuf::ReadUInt8(size_t offset) const
74 {
75 if (offset >= pData_.size()) {
76 IMAGE_LOGE("Attempted to read beyond the buffer size while reading an 8-bit unsigned integer. "
77 "Offset: %{public}zu, Buffer size: %{public}zu",
78 offset, pData_.size());
79 return 0;
80 }
81 return pData_[offset];
82 }
83
WriteUInt8(size_t offset,uint8_t value)84 void DataBuf::WriteUInt8(size_t offset, uint8_t value)
85 {
86 if (offset >= pData_.size()) {
87 IMAGE_LOGE("Attempted to write beyond the buffer size while writing an 8-bit unsigned integer. "
88 "Offset: %{public}zu, Buffer size: %{public}zu",
89 offset, pData_.size());
90 return;
91 }
92 pData_[offset] = value;
93 }
94
WriteUInt32(size_t offset,uint32_t x,ByteOrder byteOrder)95 void DataBuf::WriteUInt32(size_t offset, uint32_t x, ByteOrder byteOrder)
96 {
97 bool cond = pData_.size() < UINT32_SIZE || offset > (pData_.size() - UINT32_SIZE);
98 CHECK_ERROR_RETURN_LOG(cond, "Attempted to write beyond the buffer size while writing a 32-bit unsigned integer. "
99 "Offset: %{public}zu, Buffer size: %{public}zu", offset, pData_.size());
100 UL2Data(&pData_[offset], x, byteOrder);
101 }
102
ReadUInt32(size_t offset,ByteOrder byteOrder)103 uint32_t DataBuf::ReadUInt32(size_t offset, ByteOrder byteOrder)
104 {
105 if (pData_.size() < UINT32_SIZE || offset > (pData_.size() - UINT32_SIZE)) {
106 IMAGE_LOGE("Attempted to read beyond the buffer size while reading a 32-bit unsigned integer. "
107 "Offset: %{public}zu, Buffer size: %{public}zu",
108 offset, pData_.size());
109 return 0;
110 }
111 return GetULong(&pData_[offset], byteOrder);
112 }
113
CmpBytes(size_t offset,const void * buf,size_t bufsize) const114 int DataBuf::CmpBytes(size_t offset, const void *buf, size_t bufsize) const
115 {
116 if (pData_.size() < bufsize || offset > pData_.size() - bufsize) {
117 IMAGE_LOGE("Attempted to compare bytes beyond the buffer size. "
118 "Offset: %{public}zu, Buffer size: %{public}zu, Compare size: %{public}zu",
119 offset, pData_.size(), bufsize);
120 return -1;
121 }
122 return memcmp(&pData_[offset], buf, bufsize);
123 }
124
Data(size_t offset)125 byte *DataBuf::Data(size_t offset)
126 {
127 return const_cast<byte *>(CData(offset));
128 }
129
CData(size_t offset) const130 const byte *DataBuf::CData(size_t offset) const
131 {
132 if (pData_.empty() || offset == pData_.size()) {
133 return nullptr;
134 }
135 if (offset > pData_.size()) {
136 IMAGE_LOGE("Attempted to access beyond the buffer size. "
137 "Offset: %{public}zu, Buffer size: %{public}zu",
138 offset, pData_.size());
139 return nullptr;
140 }
141 return &pData_[offset];
142 }
143
GetUShort(const byte * buf,ByteOrder byteOrder)144 uint16_t GetUShort(const byte *buf, ByteOrder byteOrder)
145 {
146 if (byteOrder == littleEndian) {
147 return static_cast<byte>(buf[1]) << DATA_BUF_BYTE_SIZE | static_cast<byte>(buf[0]);
148 }
149 return static_cast<byte>(buf[0]) << DATA_BUF_BYTE_SIZE | static_cast<byte>(buf[1]);
150 }
151
US2Data(byte * buf,uint16_t value,ByteOrder byteOrder)152 void US2Data(byte *buf, uint16_t value, ByteOrder byteOrder)
153 {
154 if (byteOrder == littleEndian) {
155 buf[0] = static_cast<byte>(value & LOWER_BYTE_MASK);
156 buf[1] = static_cast<byte>((value & UPPER_BYTE_MASK) >> DATA_BUF_BYTE_SIZE);
157 } else {
158 buf[0] = static_cast<byte>((value & UPPER_BYTE_MASK) >> DATA_BUF_BYTE_SIZE);
159 buf[1] = static_cast<byte>(value & LOWER_BYTE_MASK);
160 }
161 }
162
UL2Data(byte * buf,uint32_t l,ByteOrder byteOrder)163 size_t UL2Data(byte *buf, uint32_t l, ByteOrder byteOrder)
164 {
165 if (buf == nullptr) {
166 return 0;
167 }
168 if (byteOrder == littleEndian) {
169 buf[BYTE_1_POSITION] = static_cast<byte>(l & BYTE_1_MASK);
170 buf[BYTE_2_POSITION] = static_cast<byte>((l & BYTE_2_MASK) >> BYTE_2_SHIFT);
171 buf[BYTE_3_POSITION] = static_cast<byte>((l & BYTE_3_MASK) >> BYTE_3_SHIFT);
172 buf[BYTE_4_POSITION] = static_cast<byte>((l & BYTE_4_MASK) >> BYTE_4_SHIFT);
173 } else {
174 buf[BYTE_1_POSITION] = static_cast<byte>((l & BYTE_4_MASK) >> BYTE_4_SHIFT);
175 buf[BYTE_2_POSITION] = static_cast<byte>((l & BYTE_3_MASK) >> BYTE_3_SHIFT);
176 buf[BYTE_3_POSITION] = static_cast<byte>((l & BYTE_2_MASK) >> BYTE_2_SHIFT);
177 buf[BYTE_4_POSITION] = static_cast<byte>(l & BYTE_1_MASK);
178 }
179 return UINT32_SIZE;
180 }
181
GetULong(const byte * buf,ByteOrder byteOrder)182 uint32_t GetULong(const byte *buf, ByteOrder byteOrder)
183 {
184 if (buf == nullptr) {
185 return 0;
186 }
187 if (byteOrder == littleEndian) {
188 return (buf[BYTE_4_POSITION] << BYTE_4_SHIFT) | (buf[BYTE_3_POSITION] << BYTE_3_SHIFT) |
189 (buf[BYTE_2_POSITION] << BYTE_2_SHIFT) | (buf[BYTE_1_POSITION] << BYTE_1_SHIFT);
190 }
191 return (buf[BYTE_1_POSITION] << BYTE_4_SHIFT) | (buf[BYTE_2_POSITION] << BYTE_3_SHIFT) |
192 (buf[BYTE_3_POSITION] << BYTE_2_SHIFT) | (buf[BYTE_4_POSITION] << BYTE_1_SHIFT);
193 }
194 } // namespace Media
195 } // namespace OHOS
196