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
18 #include <cmath>
19 #include <iostream>
20
21 #include "securec.h"
22
23 using namespace std;
24
25 namespace OHOS::buffer {
Init(uint32_t size)26 void Buffer::Init(uint32_t size)
27 {
28 raw_ = reinterpret_cast<uint8_t *>(malloc(size));
29 if (raw_ == nullptr) {
30 HILOG_FATAL("Buffer constructor malloc failed");
31 length_ = 0;
32 } else {
33 length_ = size;
34 }
35 }
36
Init(Buffer * buffer)37 void Buffer::Init(Buffer *buffer)
38 {
39 if (buffer != nullptr && buffer->length_ > 0) {
40 this->raw_ = reinterpret_cast<uint8_t *>(malloc(buffer->length_));
41 if (raw_ == nullptr) {
42 HILOG_FATAL("Buffer constructor malloc failed");
43 } else {
44 this->length_ = buffer->length_;
45 if (memcpy_s(raw_, length_, buffer->raw_ + buffer->byteOffset_, length_) != EOK) {
46 HILOG_FATAL("Buffer constructor memcpy_s failed");
47 }
48 }
49 }
50 }
51
Init(Buffer * pool,unsigned int poolOffset,unsigned int length)52 void Buffer::Init(Buffer *pool, unsigned int poolOffset, unsigned int length)
53 {
54 if (pool != nullptr) {
55 this->raw_ = pool->GetRaw();
56 this->byteOffset_ = poolOffset;
57 this->length_ = length;
58 }
59 this->needRelease_ = false;
60 }
61
Init(uint8_t * buffer,unsigned int byteOffset,unsigned int length)62 void Buffer::Init(uint8_t *buffer, unsigned int byteOffset, unsigned int length)
63 {
64 if (buffer != nullptr) {
65 this->raw_ = buffer;
66 this->length_ = length;
67 this->byteOffset_ = byteOffset;
68 }
69 this->needRelease_ = false;
70 }
71
~Buffer()72 Buffer::~Buffer()
73 {
74 if (raw_ != nullptr && needRelease_) {
75 free(raw_);
76 raw_ = nullptr;
77 }
78 }
79
GetEncodingType(string encode)80 EncodingType Buffer::GetEncodingType(string encode)
81 {
82 if (encode == "hex") {
83 return HEX;
84 } else if (encode == "base64url") {
85 return BASE64URL;
86 } else if (encode == "ascii") {
87 return ASCII;
88 } else if (encode == "base64") {
89 return BASE64;
90 } else if (encode == "latin1") {
91 return LATIN1;
92 } else if (encode == "binary") {
93 return BINARY;
94 } else if (encode == "utf16le") {
95 return UTF16LE;
96 } else {
97 return UTF8;
98 }
99 }
100
GetRaw()101 uint8_t *Buffer::GetRaw()
102 {
103 return raw_;
104 }
105
GetLength()106 unsigned int Buffer::GetLength()
107 {
108 return length_;
109 }
110
SetLength(unsigned int len)111 void Buffer::SetLength(unsigned int len)
112 {
113 length_ = len;
114 }
115
GetByteOffset()116 unsigned int Buffer::GetByteOffset()
117 {
118 return byteOffset_;
119 }
120
SubBuffer(Buffer * tBuf,uint32_t start,uint32_t end)121 void Buffer::SubBuffer(Buffer *tBuf, uint32_t start, uint32_t end)
122 {
123 if (tBuf == nullptr) {
124 HILOG_ERROR("buffer: buffer is nullptr.");
125 return;
126 }
127 this->Init(tBuf->GetRaw(), tBuf->byteOffset_ + start, (end - start));
128 }
129
Copy(Buffer * tBuf,uint32_t tStart,uint32_t sStart,uint32_t sEnd)130 uint32_t Buffer::Copy(Buffer *tBuf, uint32_t tStart, uint32_t sStart, uint32_t sEnd)
131 {
132 if (tBuf == nullptr) {
133 return 0; // 0 : cannot copy anything
134 }
135 uint8_t *dest = tBuf->raw_ + tBuf->byteOffset_ + tStart;
136 uint32_t tLength = tBuf->length_ - tStart;
137 uint8_t *src = this->raw_ + this->byteOffset_ + sStart;
138 uint32_t sLength = sEnd - sStart;
139 uint32_t len = tLength > sLength ? sLength : tLength;
140 WriteBytes(src, len, dest);
141 return len;
142 }
143
Compare(Buffer * tBuf,uint32_t targetStart,uint32_t sourceStart,uint32_t length)144 int Buffer::Compare(Buffer *tBuf, uint32_t targetStart, uint32_t sourceStart, uint32_t length)
145 {
146 if (tBuf == nullptr) {
147 return 0;
148 }
149 uint8_t *dest = tBuf->GetRaw() + tBuf->byteOffset_ + targetStart;
150 uint8_t *src = this->GetRaw() + this->byteOffset_ + sourceStart;
151 return memcmp(dest, src, length);
152 }
153
WriteBE(int32_t value,uint32_t bytes)154 void Buffer::WriteBE(int32_t value, uint32_t bytes)
155 {
156 uint32_t uValue = static_cast<uint32_t>(value);
157 for (uint32_t i = bytes; i > 0; i--) {
158 uint8_t va = static_cast<uint8_t>(uValue & 0x000000FF);
159 data_[i - 1] = va;
160 // 8 : shift right 8 bits(i.e 1 byte)
161 uValue = uValue >> 8;
162 }
163 }
164
WriteLE(int32_t value,uint32_t bytes)165 void Buffer::WriteLE(int32_t value, uint32_t bytes)
166 {
167 uint32_t uValue = static_cast<uint32_t>(value);
168 for (uint32_t i = 0, len = bytes - 1; i <= len; i++) {
169 uint8_t va = static_cast<uint8_t>(uValue & 0x000000FF);
170 data_[i] = va;
171 // 8 : shift right 8 bits(i.e 1 byte)
172 uValue = uValue >> 8;
173 }
174 }
175
ReadBE(uint32_t bytes)176 uint32_t Buffer::ReadBE(uint32_t bytes)
177 {
178 uint32_t result = 0x0000;
179 for (uint32_t i = 0; i < bytes; i++) {
180 // 8 : shift left 8 bits(i.e 1 byte)
181 result = result << 8;
182 result |= data_[i];
183 }
184 return result;
185 }
186
ReadLE(uint32_t bytes)187 uint32_t Buffer::ReadLE(uint32_t bytes)
188 {
189 uint32_t result = 0x0000;
190 for (uint32_t i = bytes; i > 0; i--) {
191 // 8 : shift left 8 bits(i.e 1 byte)
192 result = result << 8;
193 result |= data_[i - 1];
194 }
195 return result;
196 }
197
WriteInt32BE(int32_t value,uint32_t offset)198 void Buffer::WriteInt32BE(int32_t value, uint32_t offset)
199 {
200 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
201 WriteBE(value, 4);
202 // 4 : write 4 bytes
203 WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
204 }
205
ReadInt32BE(uint32_t offset)206 int32_t Buffer::ReadInt32BE(uint32_t offset)
207 {
208 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
209 ReadBytes(data_, offset, 4);
210 // 4 : read 4 bytes
211 return static_cast<int32_t>(ReadBE(4));
212 }
213
WriteInt32LE(int32_t value,uint32_t offset)214 void Buffer::WriteInt32LE(int32_t value, uint32_t offset)
215 {
216 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
217 WriteLE(value, 4);
218 // 4 : write 4 bytes
219 WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
220 }
221
ReadInt32LE(uint32_t offset)222 int32_t Buffer::ReadInt32LE(uint32_t offset)
223 {
224 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
225 ReadBytes(data_, offset, 4);
226 // 4 : read 4 bytes
227 return static_cast<int32_t>(ReadLE(4));
228 }
229
WriteUInt32BE(int32_t value,uint32_t offset)230 void Buffer::WriteUInt32BE(int32_t value, uint32_t offset)
231 {
232 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
233 WriteBE(value, 4);
234 // 4 : write 4 bytes
235 WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
236 }
237
ReadUInt32BE(uint32_t offset)238 uint32_t Buffer::ReadUInt32BE(uint32_t offset)
239 {
240 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
241 ReadBytes(data_, offset, 4);
242 // 4 : read 4 bytes
243 return ReadBE(4);
244 }
245
WriteUInt32LE(int32_t value,uint32_t offset)246 void Buffer::WriteUInt32LE(int32_t value, uint32_t offset)
247 {
248 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
249 WriteLE(value, 4);
250 // 4 : write 4 bytes
251 WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
252 }
253
ReadUInt32LE(uint32_t offset)254 uint32_t Buffer::ReadUInt32LE(uint32_t offset)
255 {
256 // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
257 ReadBytes(data_, offset, 4);
258 // 4 : read 4 bytes
259 return ReadLE(4);
260 }
261
Get(uint32_t index)262 int32_t Buffer::Get(uint32_t index)
263 {
264 uint8_t value;
265 uint32_t count = 1;
266 if (memcpy_s(&value, count, raw_ + byteOffset_ + index, count) != EOK) {
267 HILOG_FATAL("Buffer get memcpy_s failed");
268 }
269 return value;
270 }
271
Set(uint32_t index,uint8_t value)272 void Buffer::Set(uint32_t index, uint8_t value)
273 {
274 WriteByte(value, index);
275 }
276
ReadBytes(uint8_t * data,uint32_t offset,uint32_t length)277 void Buffer::ReadBytes(uint8_t *data, uint32_t offset, uint32_t length)
278 {
279 if (data == nullptr) {
280 return;
281 }
282
283 if (length == 0) {
284 HILOG_DEBUG("Buffer::ReadBytes size is 0");
285 return;
286 }
287 if (memcpy_s(data, length, raw_ + byteOffset_ + offset, length) != EOK) {
288 HILOG_FATAL("Buffer ReadBytes memcpy_s failed");
289 }
290 }
291
WriteByte(uint8_t number,uint32_t offset)292 void Buffer::WriteByte(uint8_t number, uint32_t offset)
293 {
294 WriteBytes(&number, 1, raw_ + byteOffset_ + offset);
295 }
296
WriteString(std::string value,unsigned int size)297 unsigned int Buffer::WriteString(std::string value, unsigned int size)
298 {
299 uint8_t *str = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.data()));
300 bool isWriteSuccess = WriteBytes(str, size, raw_ + byteOffset_);
301 return isWriteSuccess ? size : 0; // 0: write failed
302 }
303
WriteString(string value,unsigned int offset,unsigned int size)304 unsigned int Buffer::WriteString(string value, unsigned int offset, unsigned int size)
305 {
306 uint8_t *str = reinterpret_cast<uint8_t *>(const_cast<char *>(value.c_str()));
307 bool isWriteSuccess = WriteBytes(str, size, raw_ + byteOffset_ + offset);
308 return isWriteSuccess ? size : 0; // 0: write failed
309 }
310
WriteStringLoop(string value,unsigned int offset,unsigned int end,unsigned int length)311 void Buffer::WriteStringLoop(string value, unsigned int offset, unsigned int end, unsigned int length)
312 {
313 if (end - offset <= 0) {
314 return;
315 }
316 unsigned int loop = length > end - offset ? end - offset : length;
317
318 uint8_t *str = reinterpret_cast<uint8_t *>(const_cast<char *>(value.c_str()));
319 while (offset < end) {
320 if (loop + offset > end) {
321 WriteBytes(str, end - offset, raw_ + byteOffset_ + offset);
322 } else {
323 WriteBytes(str, loop, raw_ + byteOffset_ + offset);
324 }
325 offset += loop;
326 }
327 }
328
Utf16StrToStr(std::u16string value)329 std::string Buffer::Utf16StrToStr(std::u16string value)
330 {
331 string str = "";
332 char16_t *data = const_cast<char16_t *>(reinterpret_cast<const char16_t *>(value.data()));
333 for (unsigned int i = 0; i < value.length(); i++) {
334 char16_t c = data[i];
335 char high = static_cast<char>((c >> 8) & 0x00FF);
336 char low = static_cast<char>(c & 0x00FF);
337 str.push_back(low);
338 str.push_back(high);
339 }
340 return str;
341 }
342
WriteString(std::u16string value,unsigned int offset,unsigned int length)343 unsigned int Buffer::WriteString(std::u16string value, unsigned int offset, unsigned int length)
344 {
345 string str = Utf16StrToStr(value);
346 return this->WriteString(str, offset, length);
347 }
348
WriteStringLoop(std::u16string value,unsigned int offset,unsigned int end)349 void Buffer::WriteStringLoop(std::u16string value, unsigned int offset, unsigned int end)
350 {
351 string str = Utf16StrToStr(value);
352 // 2 : utf16 is 2 times of length of ascii
353 this->WriteStringLoop(str, offset, end, value.length() * 2);
354 }
355
WriteBytes(uint8_t * src,unsigned int size,uint8_t * dest)356 bool Buffer::WriteBytes(uint8_t *src, unsigned int size, uint8_t *dest)
357 {
358 if (src == nullptr || dest == nullptr) {
359 return false;
360 }
361 if (size == 0) {
362 HILOG_DEBUG("Buffer::WriteBytes size is 0");
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, encodingType);
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, BASE64);
463 }
464
ToBase64Url(uint32_t start,uint32_t length)465 std::string Buffer::ToBase64Url(uint32_t start, uint32_t length)
466 {
467 uint8_t data[length];
468 ReadBytes(data, start, length);
469 return Base64Encode(reinterpret_cast<const unsigned char*>(data), length, BASE64URL);
470 }
471
IndexOf(const char * data,uint32_t offset,uint32_t len)472 int Buffer::IndexOf(const char *data, uint32_t offset, uint32_t len)
473 {
474 if (data == nullptr) {
475 return -1;
476 }
477 uint8_t sData[length_ - offset];
478 ReadBytes(sData, offset, length_ - offset);
479 int index = FindIndex(sData, reinterpret_cast<uint8_t *>(const_cast<char *>(data)), length_ - offset, len);
480 return index == -1 ? index : (offset + index);
481 }
482
LastIndexOf(const char * data,uint32_t offset,uint32_t len)483 int Buffer::LastIndexOf(const char *data, uint32_t offset, uint32_t len)
484 {
485 if (data == nullptr) {
486 return -1;
487 }
488 uint8_t sData[length_ - offset];
489 ReadBytes(sData, offset, length_ - offset);
490 return FindLastIndex(sData, reinterpret_cast<uint8_t *>(const_cast<char *>(data)), length_ - offset, len);
491 }
492 } // namespace OHOS::Buffer
493