• 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 "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(Buffer * tBuf,uint32_t start,uint32_t end)122 void Buffer::SubBuffer(Buffer *tBuf, uint32_t start, uint32_t end)
123 {
124     if (tBuf == nullptr) {
125         HILOG_ERROR("buffer: buffer is nullptr.");
126         return;
127     }
128     this->Init(tBuf->GetRaw(), tBuf->byteOffset_ + start, (end - start));
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     uint32_t uValue = static_cast<uint32_t>(value);
169     for (uint32_t i = 0, len = bytes - 1; i <= len; i++) {
170         uint8_t va = static_cast<uint8_t>(uValue & 0x000000FF);
171         data_[i] = va;
172         // 8 : shift right 8 bits(i.e 1 byte)
173         uValue = uValue >> 8;
174     }
175 }
176 
ReadBE(uint32_t bytes)177 uint32_t Buffer::ReadBE(uint32_t bytes)
178 {
179     uint32_t result = 0x0000;
180     for (uint32_t i = 0; i < bytes; i++) {
181         // 8 : shift left 8 bits(i.e 1 byte)
182         result = result << 8;
183         result |= data_[i];
184     }
185     return result;
186 }
187 
ReadLE(uint32_t bytes)188 uint32_t Buffer::ReadLE(uint32_t bytes)
189 {
190     uint32_t result = 0x0000;
191     for (uint32_t i = bytes; i > 0; i--) {
192         // 8 : shift left 8 bits(i.e 1 byte)
193         result = result << 8;
194         result |= data_[i - 1];
195     }
196     return result;
197 }
198 
WriteInt32BE(int32_t value,uint32_t offset)199 void Buffer::WriteInt32BE(int32_t value, uint32_t offset)
200 {
201     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
202     WriteBE(value, 4);
203     // 4 : write 4 bytes
204     WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
205 }
206 
ReadInt32BE(uint32_t offset)207 int32_t Buffer::ReadInt32BE(uint32_t offset)
208 {
209     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
210     ReadBytes(data_, offset, 4);
211     // 4 : read 4 bytes
212     return static_cast<int32_t>(ReadBE(4));
213 }
214 
WriteInt32LE(int32_t value,uint32_t offset)215 void Buffer::WriteInt32LE(int32_t value, uint32_t offset)
216 {
217     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
218     WriteLE(value, 4);
219     // 4 : write 4 bytes
220     WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
221 }
222 
ReadInt32LE(uint32_t offset)223 int32_t Buffer::ReadInt32LE(uint32_t offset)
224 {
225     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
226     ReadBytes(data_, offset, 4);
227     // 4 : read 4 bytes
228     return static_cast<int32_t>(ReadLE(4));
229 }
230 
WriteUInt32BE(int32_t value,uint32_t offset)231 void Buffer::WriteUInt32BE(int32_t value, uint32_t offset)
232 {
233     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
234     WriteBE(value, 4);
235     // 4 : write 4 bytes
236     WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
237 }
238 
ReadUInt32BE(uint32_t offset)239 uint32_t Buffer::ReadUInt32BE(uint32_t offset)
240 {
241     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
242     ReadBytes(data_, offset, 4);
243     // 4 : read 4 bytes
244     return ReadBE(4);
245 }
246 
WriteUInt32LE(int32_t value,uint32_t offset)247 void Buffer::WriteUInt32LE(int32_t value, uint32_t offset)
248 {
249     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
250     WriteLE(value, 4);
251     // 4 : write 4 bytes
252     WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
253 }
254 
ReadUInt32LE(uint32_t offset)255 uint32_t Buffer::ReadUInt32LE(uint32_t offset)
256 {
257     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
258     ReadBytes(data_, offset, 4);
259     // 4 : read 4 bytes
260     return ReadLE(4);
261 }
262 
Get(uint32_t index)263 int32_t Buffer::Get(uint32_t index)
264 {
265     uint8_t value;
266     uint32_t count = 1;
267     if (memcpy_s(&value, count, raw_ + byteOffset_ + index, count) != EOK) {
268         HILOG_FATAL("Buffer get memcpy_s failed");
269     }
270     return value;
271 }
272 
Set(uint32_t index,uint8_t value)273 void Buffer::Set(uint32_t index, uint8_t value)
274 {
275     WriteByte(value, index);
276 }
277 
ReadBytes(uint8_t * data,uint32_t offset,uint32_t length)278 void Buffer::ReadBytes(uint8_t *data, uint32_t offset, uint32_t length)
279 {
280     if (data == nullptr) {
281         return;
282     }
283     if (memcpy_s(data, length, raw_ + byteOffset_ + offset, length) != EOK) {
284         HILOG_FATAL("Buffer ReadBytes memcpy_s failed");
285     }
286 }
287 
WriteByte(uint8_t number,uint32_t offset)288 void Buffer::WriteByte(uint8_t number, uint32_t offset)
289 {
290     WriteBytes(&number, 1, raw_ + byteOffset_ + offset);
291 }
292 
WriteString(std::string value,unsigned int size)293 unsigned int Buffer::WriteString(std::string value, unsigned int size)
294 {
295     uint8_t *str = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.data()));
296     bool isWriteSuccess = WriteBytes(str, size, raw_ + byteOffset_);
297     return isWriteSuccess ? size : 0; // 0: write failed
298 }
299 
WriteString(string value,unsigned int offset,unsigned int size)300 unsigned int Buffer::WriteString(string value, unsigned int offset, unsigned int size)
301 {
302     const char *data = value.c_str();
303     uint8_t *str = reinterpret_cast<uint8_t *>(const_cast<char *>(data));
304     bool isWriteSuccess = WriteBytes(str, size, raw_ + byteOffset_ + offset);
305     return isWriteSuccess ? size : 0; // 0: write failed
306 }
307 
WriteStringLoop(string value,unsigned int offset,unsigned int end,unsigned int length)308 void Buffer::WriteStringLoop(string value, unsigned int offset, unsigned int end, unsigned int length)
309 {
310     if (end - offset <= 0) {
311         return;
312     }
313     const char *data = value.c_str();
314     unsigned int loop = length > end - offset ? end - offset : length;
315 
316     uint8_t *str = reinterpret_cast<uint8_t *>(const_cast<char *>(data));
317     while (offset < end) {
318         if (loop + offset > end) {
319             WriteBytes(str, end - offset, raw_ + byteOffset_ + offset);
320         } else {
321             WriteBytes(str, loop, raw_ + byteOffset_ + offset);
322         }
323         offset += loop;
324     }
325 }
326 
Utf16StrToStr(std::u16string value)327 std::string Buffer::Utf16StrToStr(std::u16string value)
328 {
329     string str = "";
330     char16_t *data = const_cast<char16_t *>(reinterpret_cast<const char16_t *>(value.data()));
331     for (unsigned int i = 0; i < value.length(); i++) {
332         char16_t c = data[i];
333         char high = (char)((c >> 8) & 0x00FF);
334         char low = (char)(c & 0x00FF);
335         str.push_back(low);
336         str.push_back(high);
337     }
338     return str;
339 }
340 
WriteString(std::u16string value,unsigned int offset,unsigned int length)341 unsigned int Buffer::WriteString(std::u16string value, unsigned int offset, unsigned int length)
342 {
343     string str = Utf16StrToStr(value);
344     return this->WriteString(str, offset, length);
345 }
346 
WriteStringLoop(std::u16string value,unsigned int offset,unsigned int end)347 void Buffer::WriteStringLoop(std::u16string value, unsigned int offset, unsigned int end)
348 {
349     string str = Utf16StrToStr(value);
350     // 2 : utf16 is 2 times of length of ascii
351     this->WriteStringLoop(str, offset, end, value.length() * 2);
352 }
353 
WriteBytes(uint8_t * src,unsigned int size,uint8_t * dest)354 bool Buffer::WriteBytes(uint8_t *src, unsigned int size, uint8_t *dest)
355 {
356     if (src == nullptr || dest == nullptr) {
357         return false;
358     }
359     if (memcpy_s(dest, size, src, size) != EOK) {
360         HILOG_FATAL("Buffer WriteBytes memcpy_s failed");
361         return false;
362     }
363     return true;
364 }
365 
SetArray(vector<uint8_t> array,unsigned int offset)366 void Buffer::SetArray(vector<uint8_t> array, unsigned int offset)
367 {
368     unsigned int arrLen = array.size();
369     unsigned int size = arrLen <= length_ ? arrLen : length_;
370     WriteBytes(array.data(), size, raw_ + byteOffset_ + offset);
371 }
372 
FillBuffer(Buffer * buffer,unsigned int offset,unsigned int end)373 void Buffer::FillBuffer(Buffer *buffer, unsigned int offset, unsigned int end)
374 {
375     if (buffer == nullptr) {
376         return;
377     }
378     if (end - offset <= 0) {
379         return;
380     }
381     unsigned int loop = buffer->GetLength() > end - offset ? end - offset : buffer->GetLength();
382 
383     while (offset < end) {
384         WriteBytes(buffer->GetRaw() + buffer->byteOffset_, loop, raw_ + byteOffset_ + offset);
385         offset += loop;
386     }
387 }
388 
FillNumber(vector<uint8_t> numbers,unsigned int offset,unsigned int end)389 void Buffer::FillNumber(vector<uint8_t> numbers, unsigned int offset, unsigned int end)
390 {
391     if (end - offset <= 0) {
392         return;
393     }
394     unsigned int loop = numbers.size() > end - offset ? end - offset : numbers.size();
395 
396     while (offset < end) {
397         WriteBytes(numbers.data(), loop, raw_ + byteOffset_ + offset);
398         offset += loop;
399     }
400 }
401 
GetString(std::string value,EncodingType encodingType)402 std::string Buffer::GetString(std::string value, EncodingType encodingType)
403 {
404     string str = "";
405     switch (encodingType) {
406         case ASCII:
407         case LATIN1:
408             str = Utf8ToUtf16BEToANSI(value);
409             break;
410         case UTF8:
411             str = value;
412             break;
413         case BASE64:
414         case BASE64URL:
415             str = Base64Decode(value);
416             break;
417         case BINARY:
418             str = Utf8ToUtf16BEToANSI(value);
419             break;
420         default:
421             break;
422     }
423     return str;
424 }
425 
FillString(string value,unsigned int offset,unsigned int end,string encoding)426 void Buffer::FillString(string value, unsigned int offset, unsigned int end, string encoding)
427 {
428     EncodingType encodingType = GetEncodingType(encoding);
429     if (encodingType == UTF16LE) {
430         u16string u16Str = Utf8ToUtf16BE(value);
431         this->WriteStringLoop(u16Str, offset, end);
432     } else {
433         string str = GetString(value, encodingType);
434         this->WriteStringLoop(str, offset, end, str.length());
435     }
436 }
437 
WriteString(string value,unsigned int offset,unsigned int length,string encoding)438 unsigned int Buffer::WriteString(string value, unsigned int offset, unsigned int length, string encoding)
439 {
440     EncodingType encodingType = GetEncodingType(encoding);
441     unsigned int lengthWrote = 0;
442     if (encodingType == UTF16LE) {
443         u16string u16Str = Utf8ToUtf16BE(value);
444         lengthWrote = this->WriteString(u16Str, offset, length);
445     } else {
446         string str = GetString(value, encodingType);
447         lengthWrote = this->WriteString(str, offset, length);
448     }
449     return lengthWrote;
450 }
451 
ToBase64(uint32_t start,uint32_t length)452 std::string Buffer::ToBase64(uint32_t start, uint32_t length)
453 {
454     uint8_t data[length];
455     ReadBytes(data, start, length);
456     return Base64Encode(reinterpret_cast<const unsigned char*>(data), length);
457 }
458 
IndexOf(const char * data,uint32_t offset,uint32_t len)459 int Buffer::IndexOf(const char *data, uint32_t offset, uint32_t len)
460 {
461     if (data == nullptr) {
462         return -1;
463     }
464     uint8_t sData[length_ - offset];
465     ReadBytes(sData, offset, length_ - offset);
466     int index = FindIndex(sData, reinterpret_cast<uint8_t *>(const_cast<char *>(data)), length_ - offset, len);
467     return index == -1 ? index : (offset + index);
468 }
469 
LastIndexOf(const char * data,uint32_t offset,uint32_t len)470 int Buffer::LastIndexOf(const char *data, uint32_t offset, uint32_t len)
471 {
472     if (data == nullptr) {
473         return -1;
474     }
475     uint8_t sData[length_ - offset];
476     ReadBytes(sData, offset, length_ - offset);
477     return FindLastIndex(sData, reinterpret_cast<uint8_t *>(const_cast<char *>(data)), length_ - offset, len);
478 }
479 } // namespace OHOS::Buffer
480