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