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 if (pData_.size() < UINT32_SIZE || offset > (pData_.size() - UINT32_SIZE)) {
98 IMAGE_LOGE("Attempted to write beyond the buffer size while writing a 32-bit unsigned integer. "
99 "Offset: %{public}zu, Buffer size: %{public}zu",
100 offset, pData_.size());
101 return;
102 }
103 UL2Data(&pData_[offset], x, byteOrder);
104 }
105
ReadUInt32(size_t offset,ByteOrder byteOrder)106 uint32_t DataBuf::ReadUInt32(size_t offset, ByteOrder byteOrder)
107 {
108 if (pData_.size() < UINT32_SIZE || offset > (pData_.size() - UINT32_SIZE)) {
109 IMAGE_LOGE("Attempted to read beyond the buffer size while reading a 32-bit unsigned integer. "
110 "Offset: %{public}zu, Buffer size: %{public}zu",
111 offset, pData_.size());
112 return 0;
113 }
114 return GetULong(&pData_[offset], byteOrder);
115 }
116
CmpBytes(size_t offset,const void * buf,size_t bufsize) const117 int DataBuf::CmpBytes(size_t offset, const void *buf, size_t bufsize) const
118 {
119 if (pData_.size() < bufsize || offset > pData_.size() - bufsize) {
120 IMAGE_LOGE("Attempted to compare bytes beyond the buffer size. "
121 "Offset: %{public}zu, Buffer size: %{public}zu, Compare size: %{public}zu",
122 offset, pData_.size(), bufsize);
123 return -1;
124 }
125 return memcmp(&pData_[offset], buf, bufsize);
126 }
127
Data(size_t offset)128 byte *DataBuf::Data(size_t offset)
129 {
130 return const_cast<byte *>(CData(offset));
131 }
132
CData(size_t offset) const133 const byte *DataBuf::CData(size_t offset) const
134 {
135 if (pData_.empty() || offset == pData_.size()) {
136 return nullptr;
137 }
138 if (offset > pData_.size()) {
139 IMAGE_LOGE("Attempted to access beyond the buffer size. "
140 "Offset: %{public}zu, Buffer size: %{public}zu",
141 offset, pData_.size());
142 return nullptr;
143 }
144 return &pData_[offset];
145 }
146
GetUShort(const byte * buf,ByteOrder byteOrder)147 uint16_t GetUShort(const byte *buf, ByteOrder byteOrder)
148 {
149 if (byteOrder == littleEndian) {
150 return static_cast<byte>(buf[1]) << DATA_BUF_BYTE_SIZE | static_cast<byte>(buf[0]);
151 }
152 return static_cast<byte>(buf[0]) << DATA_BUF_BYTE_SIZE | static_cast<byte>(buf[1]);
153 }
154
US2Data(byte * buf,uint16_t value,ByteOrder byteOrder)155 void US2Data(byte *buf, uint16_t value, ByteOrder byteOrder)
156 {
157 if (byteOrder == littleEndian) {
158 buf[0] = static_cast<byte>(value & LOWER_BYTE_MASK);
159 buf[1] = static_cast<byte>((value & UPPER_BYTE_MASK) >> DATA_BUF_BYTE_SIZE);
160 } else {
161 buf[0] = static_cast<byte>((value & UPPER_BYTE_MASK) >> DATA_BUF_BYTE_SIZE);
162 buf[1] = static_cast<byte>(value & LOWER_BYTE_MASK);
163 }
164 }
165
UL2Data(byte * buf,uint32_t l,ByteOrder byteOrder)166 size_t UL2Data(byte *buf, uint32_t l, ByteOrder byteOrder)
167 {
168 if (buf == nullptr) {
169 return 0;
170 }
171 if (byteOrder == littleEndian) {
172 buf[BYTE_1_POSITION] = static_cast<byte>(l & BYTE_1_MASK);
173 buf[BYTE_2_POSITION] = static_cast<byte>((l & BYTE_2_MASK) >> BYTE_2_SHIFT);
174 buf[BYTE_3_POSITION] = static_cast<byte>((l & BYTE_3_MASK) >> BYTE_3_SHIFT);
175 buf[BYTE_4_POSITION] = static_cast<byte>((l & BYTE_4_MASK) >> BYTE_4_SHIFT);
176 } else {
177 buf[BYTE_1_POSITION] = static_cast<byte>((l & BYTE_4_MASK) >> BYTE_4_SHIFT);
178 buf[BYTE_2_POSITION] = static_cast<byte>((l & BYTE_3_MASK) >> BYTE_3_SHIFT);
179 buf[BYTE_3_POSITION] = static_cast<byte>((l & BYTE_2_MASK) >> BYTE_2_SHIFT);
180 buf[BYTE_4_POSITION] = static_cast<byte>(l & BYTE_1_MASK);
181 }
182 return UINT32_SIZE;
183 }
184
GetULong(const byte * buf,ByteOrder byteOrder)185 uint32_t GetULong(const byte *buf, ByteOrder byteOrder)
186 {
187 if (buf == nullptr) {
188 return 0;
189 }
190 if (byteOrder == littleEndian) {
191 return (buf[BYTE_4_POSITION] << BYTE_4_SHIFT) | (buf[BYTE_3_POSITION] << BYTE_3_SHIFT) |
192 (buf[BYTE_2_POSITION] << BYTE_2_SHIFT) | (buf[BYTE_1_POSITION] << BYTE_1_SHIFT);
193 }
194 return (buf[BYTE_1_POSITION] << BYTE_4_SHIFT) | (buf[BYTE_2_POSITION] << BYTE_3_SHIFT) |
195 (buf[BYTE_3_POSITION] << BYTE_2_SHIFT) | (buf[BYTE_4_POSITION] << BYTE_1_SHIFT);
196 }
197 } // namespace Media
198 } // namespace OHOS
199