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 
16 #ifndef FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_DATA_BUF_H
17 #define FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_DATA_BUF_H
18 
19 #include <algorithm>
20 #include <cstdint>
21 #include <limits>
22 #include <sstream>
23 #include <vector>
24 
25 namespace OHOS {
26 namespace Media {
27 using byte = uint8_t;
28 using URational = std::pair<uint32_t, uint32_t>;
29 using Rational = std::pair<int32_t, int32_t>;
30 constexpr int DATA_BUF_BYTE_SIZE = 8;
31 
32 // Type to express the byte order (little or big endian)
33 enum ByteOrder {
34     invalidByteOrder,
35     littleEndian,
36     bigEndian,
37 };
38 
39 // Container for binary data
40 using Blob = std::vector<byte>;
41 
42 /*
43   @brief Utility class containing a character array. All it does is to take
44          care of memory allocation and deletion. Its primary use is meant to
45          be as a stack variable in functions that need a temporary data
46          buffer.
47  */
48 struct DataBuf {
49     using ByteVector = std::vector<byte>;
50     using iterator = ByteVector::iterator;
51     using const_iterator = ByteVector::const_iterator;
52 
53     /* *
54      * Default constructor
55      */
56     DataBuf() = default;
57 
58     /* *
59      * Constructor to create a buffer with a specific size
60      * @param size The size of the buffer
61      */
62     explicit DataBuf(size_t size);
63 
64     /* *
65      * Constructor to create a buffer from a byte array
66      * @param pData Pointer to the byte array
67      * @param size Size of the byte array
68      */
69     DataBuf(const byte *pData, size_t size);
70 
71     /* *
72      * Resize the buffer
73      * @param size The new size of the buffer
74      */
75     void Resize(size_t size);
76 
77     /* *
78      * Reset the buffer
79      */
80     void Reset();
81 
82     /* *
83      * Get an iterator pointing to the beginning of the buffer
84      * @return An iterator pointing to the beginning of the buffer
85      */
BeginDataBuf86     iterator Begin() noexcept
87     {
88         return pData_.begin();
89     }
90 
91     /* *
92      * Get a const iterator pointing to the beginning of the buffer
93      * @return A const iterator pointing to the beginning of the buffer
94      */
CBeginDataBuf95     const_iterator CBegin() const noexcept
96     {
97         return pData_.cbegin();
98     }
99 
100     /* *
101      * Get an iterator pointing to the end of the buffer
102      * @return An iterator pointing to the end of the buffer
103      */
EndDataBuf104     iterator End() noexcept
105     {
106         return pData_.end();
107     }
108 
109     /* *
110      * Get a const iterator pointing to the end of the buffer
111      * @return A const iterator pointing to the end of the buffer
112      */
CEndDataBuf113     const_iterator CEnd() const noexcept
114     {
115         return pData_.cend();
116     }
117 
118     /* *
119      * Get the size of the buffer
120      * @return The size of the buffer
121      */
SizeDataBuf122     size_t Size() const
123     {
124         return pData_.size();
125     }
126 
127     /* *
128      * Write a uint8_t value to the buffer at a specific offset
129      * @param offset The offset to write to
130      * @param value The value to write
131      */
132     void WriteUInt8(size_t offset, uint8_t value);
133 
134     /* *
135      * Read a uint8_t value from the buffer at a specific offset
136      * @param offset The offset to read from
137      * @return The uint8_t value at the offset
138      */
139     uint8_t ReadUInt8(size_t offset) const;
140 
141     /* *
142      * Read a uint32_t value from the buffer at a specific offset
143      * @param offset The offset to read from
144      * @param byteOrder The byte order to use when reading the value
145      * @return The read value
146      */
147     uint32_t ReadUInt32(size_t offset, ByteOrder byteOrder);
148 
149     /* *
150      * Write a uint32_t value to the buffer at a specific offset
151      * @param offset The offset to write to
152      * @param x The value to write
153      * @param byteOrder The byte order to use when writing the value
154      */
155     void WriteUInt32(size_t offset, uint32_t x, ByteOrder byteOrder);
156 
157     /* *
158      * Compare a sequence of bytes in the buffer with another sequence of bytes
159      * @param offset The offset in the buffer to start the comparison
160      * @param buf The sequence of bytes to compare with
161      * @param bufsize The size of the sequence of bytes
162      * @return 0 if the sequences are equal, a positive value if the sequence in
163      * the buffer is greater, a negative value otherwise
164      */
165     int CmpBytes(size_t offset, const void *buf, size_t bufsize) const;
166 
167     /* *
168      * Get a pointer to the data in the buffer at a specific offset
169      * @param offset The offset to get the data from
170      * @return A pointer to the data
171      */
172     byte *Data(size_t offset = 0);
173 
174     /* *
175      * Get a const pointer to the data in the buffer at a specific offset
176      * @param offset The offset to get the data from
177      * @return A const pointer to the data
178      */
179     const byte *CData(size_t offset = 0) const;
180 
181     /* *
182      * Check if the buffer is empty
183      * @return true if the buffer is empty, false otherwise
184      */
EmptyDataBuf185     bool Empty() const
186     {
187         return pData_.empty();
188     }
189 
190 private:
191     ByteVector pData_;
192 };
193 
194 /**
195  * Read a 4 byte unsigned long value from the data buffer
196  * @param buf The data buffer to read from
197  * @param byteOrder The byte order to use when reading the value
198  * @return The read value
199  */
200 uint32_t GetULong(const byte *buf, ByteOrder byteOrder);
201 
202 /**
203  * Write a 4 byte unsigned long value to the data buffer
204  * @param buf The data buffer to write to
205  * @param l The value to write
206  * @param byteOrder The byte order to use when writing the value
207  * @return The number of bytes written
208  */
209 size_t UL2Data(byte *buf, uint32_t l, ByteOrder byteOrder);
210 
211 /**
212  * Read a 2 byte unsigned short value from the data buffer
213  * @param buf The data buffer to read from
214  * @param byteOrder The byte order to use when reading the value
215  * @return The read value
216  */
217 uint16_t GetUShort(const byte *buf, ByteOrder byteOrder);
218 
219 /**
220  * Convert an unsigned short to data, write the data to the buffer,
221  * and return the number of bytes written.
222  * @param buf The buffer to write to
223  * @param value The value to write
224  * @param byteOrder The byte order to use when writing the value
225  */
226 void US2Data(byte *buf, uint16_t value, ByteOrder byteOrder);
227 } // namespace Media
228 } // namespace OHOS
229 
230 #endif // FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_DATA_BUF_H
231