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