1 /*
2 * Copyright (c) 2022 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 #include "commonlibrary/ets_utils/js_api_module/buffer/js_buffer.h"
17
18 #include <cmath>
19 #include <iostream>
20
21 #include "commonlibrary/ets_utils/js_api_module/buffer/converter.h"
22 #include "securec.h"
23
24 using namespace std;
25
26 namespace OHOS::buffer {
Init(uint32_t size)27 void Buffer::Init(uint32_t size)
28 {
29 raw_ = reinterpret_cast<uint8_t *>(malloc(size));
30 if (raw_ == nullptr) {
31 HILOG_FATAL("Buffer constructor malloc failed");
32 length_ = 0;
33 } else {
34 length_ = size;
35 }
36 }
37
Init(Buffer * buffer)38 void Buffer::Init(Buffer *buffer)
39 {
40 if (buffer != nullptr && buffer->length_ > 0) {
41 this->raw_ = reinterpret_cast<uint8_t *>(malloc(buffer->length_));
42 if (raw_ == nullptr) {
43 HILOG_FATAL("Buffer constructor malloc failed");
44 } else {
45 this->length_ = buffer->length_;
46 if (memcpy_s(raw_, length_, buffer->raw_ + buffer->byteOffset_, length_) != EOK) {
47 HILOG_FATAL("Buffer constructor memcpy_s failed");
48 }
49 }
50 }
51 }
52
Init(Buffer * pool,unsigned int poolOffset,unsigned int length)53 void Buffer::Init(Buffer *pool, unsigned int poolOffset, unsigned int length)
54 {
55 if (pool != nullptr) {
56 this->raw_ = pool->GetRaw();
57 this->byteOffset_ = poolOffset;
58 this->length_ = length;
59 }
60 this->needRelease_ = false;
61 }
62
Init(uint8_t * buffer,unsigned int byteOffset,unsigned int length)63 void Buffer::Init(uint8_t *buffer, unsigned int byteOffset, unsigned int length)
64 {
65 if (buffer != nullptr) {
66 this->raw_ = buffer;
67 this->length_ = length;
68 this->byteOffset_ = byteOffset;
69 }
70 this->needRelease_ = false;
71 }
72
~Buffer()73 Buffer::~Buffer()
74 {
75 if (raw_ != nullptr && needRelease_) {
76 free(raw_);
77 raw_ = nullptr;
78 }
79 }
80
GetEncodingType(string encode)81 EncodingType Buffer::GetEncodingType(string encode)
82 {
83 if (encode == "hex") {
84 return HEX;
85 } else if (encode == "base64url") {
86 return BASE64URL;
87 } else if (encode == "ascii") {
88 return ASCII;
89 } else if (encode == "base64") {
90 return BASE64;
91 } else if (encode == "latin1") {
92 return LATIN1;
93 } else if (encode == "binary") {
94 return BINARY;
95 } else if (encode == "utf16le") {
96 return UTF16LE;
97 } else {
98 return UTF8;
99 }
100 }
101
GetRaw()102 uint8_t *Buffer::GetRaw()
103 {
104 return raw_;
105 }
106
GetLength()107 unsigned int Buffer::GetLength()
108 {
109 return length_;
110 }
111
SetLength(unsigned int len)112 void Buffer::SetLength(unsigned int len)
113 {
114 length_ = len;
115 }
116
GetByteOffset()117 unsigned int Buffer::GetByteOffset()
118 {
119 return byteOffset_;
120 }
121
SubBuffer(uint32_t start,uint32_t end)122 Buffer* Buffer::SubBuffer(uint32_t start, uint32_t end)
123 {
124 Buffer *buffer = new Buffer();
125 if (buffer != nullptr) {
126 buffer->Init(this, this->byteOffset_ + start, (end - start));
127 }
128 return buffer;
129 }
130
Copy(Buffer * tBuf,uint32_t tStart,uint32_t sStart,uint32_t sEnd)131 uint32_t Buffer::Copy(Buffer *tBuf, uint32_t tStart, uint32_t sStart, uint32_t sEnd)
132 {
133 if (tBuf == nullptr) {
134 return 0; // 0 : cannot copy anything
135 }
136 uint8_t *dest = tBuf->raw_ + tBuf->byteOffset_ + tStart;
137 uint32_t tLength = tBuf->length_ - tStart;
138 uint8_t *src = this->raw_ + this->byteOffset_ + sStart;
139 uint32_t sLength = sEnd - sStart;
140 uint32_t len = tLength > sLength ? sLength : tLength;
141 WriteBytes(src, len, dest);
142 return len;
143 }
144
Compare(Buffer * tBuf,uint32_t targetStart,uint32_t sourceStart,uint32_t length)145 int Buffer::Compare(Buffer *tBuf, uint32_t targetStart, uint32_t sourceStart, uint32_t length)
146 {
147 if (tBuf == nullptr) {
148 return 0;
149 }
150 uint8_t *dest = tBuf->GetRaw() + tBuf->byteOffset_ + targetStart;
151 uint8_t *src = this->GetRaw() + this->byteOffset_ + sourceStart;
152 return memcmp(dest, src, length);
153 }
154
WriteBE(int32_t value,uint32_t bytes)155 void Buffer::WriteBE(int32_t value, uint32_t bytes)
156 {
157 uint32_t uValue = static_cast<uint32_t>(value);
158 for (uint32_t i = bytes; i > 0; i--) {
159 uint8_t va = static_cast<uint8_t>(uValue & 0x000000FF);
160 data_[i - 1] = va;
161 // 8 : shift right 8 bits(i.e 1 byte)
162 uValue = uValue >> 8;
163 }
164 }
165
WriteLE(int32_t value,uint32_t bytes)166 void Buffer::WriteLE(int32_t value, uint32_t bytes)
167 {
168 if (bytes == 0) {
169 return;
170 }
171 uint32_t uValue = static_cast<uint32_t>(value);
172 for (uint32_t i = 0, len = bytes - 1; i <= len; i++) {
173 uint8_t va = static_cast<uint8_t>(uValue & 0x000000FF);
174 data_[i] = va;
175 // 8 : shift right 8 bits(i.e 1 byte)
176 uValue = uValue >> 8;
177 }
178 }
179
ReadBE(uint32_t bytes)180 uint32_t Buffer::ReadBE(uint32_t bytes)
181 {
182 uint32_t result = 0x0000;
183 for (uint32_t i = 0; i < bytes; i++) {
184 // 8 : shift left 8 bits(i.e 1 byte)
185 result = result << 8;
186 result |= data_[i];
187 }
188 return result;
189 }
190
ReadLE(uint32_t bytes)191 uint32_t Buffer::ReadLE(uint32_t bytes)
192 {
193 uint32_t result = 0x0000;
194 if (bytes == 0) {
195 return result;
196 }
197 for (uint32_t i = bytes; i > 0; i--) {
198 // 8 : shift left 8 bits(i.e 1 byte)
199 result = result << 8;
200 result |= data_[i - 1];
201 }
202 return result;
203 }
204
WriteInt32BE(int32_t value,uint32_t offset)205 void Buffer::WriteInt32BE(int32_t value, uint32_t offset)
206 {
207 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
208 WriteBE(value, 4);
209 // 4 : write 4 bytes
210 WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
211 }
212
ReadInt32BE(uint32_t offset)213 int32_t Buffer::ReadInt32BE(uint32_t offset)
214 {
215 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
216 ReadBytes(data_, offset, 4);
217 // 4 : read 4 bytes
218 return static_cast<int32_t>(ReadBE(4));
219 }
220
WriteInt32LE(int32_t value,uint32_t offset)221 void Buffer::WriteInt32LE(int32_t value, uint32_t offset)
222 {
223 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
224 WriteLE(value, 4);
225 // 4 : write 4 bytes
226 WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
227 }
228
ReadInt32LE(uint32_t offset)229 int32_t Buffer::ReadInt32LE(uint32_t offset)
230 {
231 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
232 ReadBytes(data_, offset, 4);
233 // 4 : read 4 bytes
234 return static_cast<int32_t>(ReadLE(4));
235 }
236
WriteUInt32BE(int32_t value,uint32_t offset)237 void Buffer::WriteUInt32BE(int32_t value, uint32_t offset)
238 {
239 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
240 WriteBE(value, 4);
241 // 4 : write 4 bytes
242 WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
243 }
244
ReadUInt32BE(uint32_t offset)245 uint32_t Buffer::ReadUInt32BE(uint32_t offset)
246 {
247 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
248 ReadBytes(data_, offset, 4);
249 // 4 : read 4 bytes
250 return ReadBE(4);
251 }
252
WriteUInt32LE(int32_t value,uint32_t offset)253 void Buffer::WriteUInt32LE(int32_t value, uint32_t offset)
254 {
255 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
256 WriteLE(value, 4);
257 // 4 : write 4 bytes
258 WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
259 }
260
ReadUInt32LE(uint32_t offset)261 uint32_t Buffer::ReadUInt32LE(uint32_t offset)
262 {
263 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
264 ReadBytes(data_, offset, 4);
265 // 4 : read 4 bytes
266 return ReadLE(4);
267 }
268
Get(uint32_t index)269 int32_t Buffer::Get(uint32_t index)
270 {
271 uint8_t value;
272 uint32_t count = 1;
273 if (memcpy_s(&value, count, raw_ + byteOffset_ + index, count) != EOK) {
274 HILOG_FATAL("Buffer get memcpy_s failed");
275 }
276 return value;
277 }
278
Set(uint32_t index,uint8_t value)279 void Buffer::Set(uint32_t index, uint8_t value)
280 {
281 WriteByte(value, index);
282 }
283
ReadBytes(uint8_t * data,uint32_t offset,uint32_t length)284 void Buffer::ReadBytes(uint8_t *data, uint32_t offset, uint32_t length)
285 {
286 if (data == nullptr) {
287 return;
288 }
289 if (memcpy_s(data, length, raw_ + byteOffset_ + offset, length) != EOK) {
290 HILOG_FATAL("Buffer ReadBytes memcpy_s failed");
291 }
292 }
293
WriteByte(uint8_t number,uint32_t offset)294 void Buffer::WriteByte(uint8_t number, uint32_t offset)
295 {
296 WriteBytes(&number, 1, raw_ + byteOffset_ + offset);
297 }
298
WriteString(std::string value,unsigned int size)299 unsigned int Buffer::WriteString(std::string value, unsigned int size)
300 {
301 uint8_t *str = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.data()));
302 bool isWriteSuccess = WriteBytes(str, size, raw_ + byteOffset_);
303 return isWriteSuccess ? size : 0; // 0: write failed
304 }
305
WriteString(string value,unsigned int offset,unsigned int size)306 unsigned int Buffer::WriteString(string value, unsigned int offset, unsigned int size)
307 {
308 const char *data = value.c_str();
309 uint8_t *str = reinterpret_cast<uint8_t *>(const_cast<char *>(data));
310 bool isWriteSuccess = WriteBytes(str, size, raw_ + byteOffset_ + offset);
311 return isWriteSuccess ? size : 0; // 0: write failed
312 }
313
WriteStringLoop(string value,unsigned int offset,unsigned int end,unsigned int length)314 void Buffer::WriteStringLoop(string value, unsigned int offset, unsigned int end, unsigned int length)
315 {
316 if (end - offset <= 0) {
317 return;
318 }
319 const char *data = value.c_str();
320 unsigned int loop = length > end - offset ? end - offset : length;
321
322 uint8_t *str = reinterpret_cast<uint8_t *>(const_cast<char *>(data));
323 while (offset < end) {
324 if (loop + offset > end) {
325 WriteBytes(str, end - offset, raw_ + byteOffset_ + offset);
326 } else {
327 WriteBytes(str, loop, raw_ + byteOffset_ + offset);
328 }
329 offset += loop;
330 }
331 }
332
Utf16StrToStr(std::u16string value)333 std::string Buffer::Utf16StrToStr(std::u16string value)
334 {
335 string str = "";
336 char16_t *data = const_cast<char16_t *>(reinterpret_cast<const char16_t *>(value.data()));
337 for (unsigned int i = 0; i < value.length(); i++) {
338 char16_t c = data[i];
339 char high = (char)((c >> 8) & 0x00FF);
340 char low = (char)(c & 0x00FF);
341 str.push_back(low);
342 str.push_back(high);
343 }
344 return str;
345 }
346
WriteString(std::u16string value,unsigned int offset,unsigned int length)347 unsigned int Buffer::WriteString(std::u16string value, unsigned int offset, unsigned int length)
348 {
349 string str = Utf16StrToStr(value);
350 return this->WriteString(str, offset, length);
351 }
352
WriteStringLoop(std::u16string value,unsigned int offset,unsigned int end)353 void Buffer::WriteStringLoop(std::u16string value, unsigned int offset, unsigned int end)
354 {
355 string str = Utf16StrToStr(value);
356 // 2 : utf16 is 2 times of length of ascii
357 this->WriteStringLoop(str, offset, end, value.length() * 2);
358 }
359
WriteBytes(uint8_t * src,unsigned int size,uint8_t * dest)360 bool Buffer::WriteBytes(uint8_t *src, unsigned int size, uint8_t *dest)
361 {
362 if (src == nullptr || dest == nullptr) {
363 return false;
364 }
365 if (memcpy_s(dest, size, src, size) != EOK) {
366 HILOG_FATAL("Buffer WriteBytes memcpy_s failed");
367 return false;
368 }
369 return true;
370 }
371
SetArray(vector<uint8_t> array,unsigned int offset)372 void Buffer::SetArray(vector<uint8_t> array, unsigned int offset)
373 {
374 unsigned int arrLen = array.size();
375 unsigned int size = arrLen <= length_ ? arrLen : length_;
376 WriteBytes(array.data(), size, raw_ + byteOffset_ + offset);
377 }
378
FillBuffer(Buffer * buffer,unsigned int offset,unsigned int end)379 void Buffer::FillBuffer(Buffer *buffer, unsigned int offset, unsigned int end)
380 {
381 if (buffer == nullptr) {
382 return;
383 }
384 if (end - offset <= 0) {
385 return;
386 }
387 unsigned int loop = buffer->GetLength() > end - offset ? end - offset : buffer->GetLength();
388
389 while (offset < end) {
390 WriteBytes(buffer->GetRaw() + buffer->byteOffset_, loop, raw_ + byteOffset_ + offset);
391 offset += loop;
392 }
393 }
394
FillNumber(vector<uint8_t> numbers,unsigned int offset,unsigned int end)395 void Buffer::FillNumber(vector<uint8_t> numbers, unsigned int offset, unsigned int end)
396 {
397 if (end - offset <= 0) {
398 return;
399 }
400 unsigned int loop = numbers.size() > end - offset ? end - offset : numbers.size();
401
402 while (offset < end) {
403 WriteBytes(numbers.data(), loop, raw_ + byteOffset_ + offset);
404 offset += loop;
405 }
406 }
407
GetString(std::string value,EncodingType encodingType)408 std::string Buffer::GetString(std::string value, EncodingType encodingType)
409 {
410 string str = "";
411 switch (encodingType) {
412 case ASCII:
413 case LATIN1:
414 str = Utf8ToUtf16BEToANSI(value);
415 break;
416 case UTF8:
417 str = value;
418 break;
419 case BASE64:
420 case BASE64URL:
421 str = Base64Decode(value);
422 break;
423 case BINARY:
424 str = Utf8ToUtf16BEToANSI(value);
425 break;
426 default:
427 break;
428 }
429 return str;
430 }
431
FillString(string value,unsigned int offset,unsigned int end,string encoding)432 void Buffer::FillString(string value, unsigned int offset, unsigned int end, string encoding)
433 {
434 EncodingType encodingType = GetEncodingType(encoding);
435 if (encodingType == UTF16LE) {
436 u16string u16Str = Utf8ToUtf16BE(value);
437 this->WriteStringLoop(u16Str, offset, end);
438 } else {
439 string str = GetString(value, encodingType);
440 this->WriteStringLoop(str, offset, end, str.length());
441 }
442 }
443
WriteString(string value,unsigned int offset,unsigned int length,string encoding)444 unsigned int Buffer::WriteString(string value, unsigned int offset, unsigned int length, string encoding)
445 {
446 EncodingType encodingType = GetEncodingType(encoding);
447 unsigned int lengthWrote = 0;
448 if (encodingType == UTF16LE) {
449 u16string u16Str = Utf8ToUtf16BE(value);
450 lengthWrote = this->WriteString(u16Str, offset, length);
451 } else {
452 string str = GetString(value, encodingType);
453 lengthWrote = this->WriteString(str, offset, length);
454 }
455 return lengthWrote;
456 }
457
ToBase64(uint32_t start,uint32_t length)458 std::string Buffer::ToBase64(uint32_t start, uint32_t length)
459 {
460 uint8_t data[length];
461 ReadBytes(data, start, length);
462 return Base64Encode(reinterpret_cast<const unsigned char*>(data), length);
463 }
464
IndexOf(const char * data,uint32_t offset,uint32_t len)465 int Buffer::IndexOf(const char *data, uint32_t offset, uint32_t len)
466 {
467 if (data == nullptr) {
468 return -1;
469 }
470 uint8_t sData[length_ - offset];
471 ReadBytes(sData, offset, length_ - offset);
472 int index = FindIndex(sData, reinterpret_cast<uint8_t *>(const_cast<char *>(data)), length_ - offset, len);
473 return index == -1 ? index : (offset + index);
474 }
475
LastIndexOf(const char * data,uint32_t offset,uint32_t len)476 int Buffer::LastIndexOf(const char *data, uint32_t offset, uint32_t len)
477 {
478 if (data == nullptr) {
479 return -1;
480 }
481 uint8_t sData[length_ - offset];
482 ReadBytes(sData, offset, length_ - offset);
483 return FindLastIndex(sData, reinterpret_cast<uint8_t *>(const_cast<char *>(data)), length_ - offset, len);
484 }
485 } // namespace OHOS::Buffer
486