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