• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "ark_native_string.h"
17 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
18 #include "ohos/init_data.h"
19 #else
20 #include "unicode/putil.h"
21 #endif
22 #include "securec.h"
23 #include "unicode/ucnv.h"
24 #include "utils/log.h"
25 
26 using panda::StringRef;
27 using panda::ObjectRef;
ArkNativeString(ArkNativeEngine * engine,const char * value,size_t length)28 ArkNativeString::ArkNativeString(ArkNativeEngine* engine, const char* value, size_t length)
29     : ArkNativeString(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
30 {
31     auto vm = engine->GetEcmaVm();
32     LocalScope scope(vm);
33     Local<StringRef> object = StringRef::NewFromUtf8(vm, value, length);
34     value_ = Global<StringRef>(vm, object);
35 }
ArkNativeString(ArkNativeEngine * engine,Local<JSValueRef> value)36 ArkNativeString::ArkNativeString(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeValue(engine, value) {}
37 
~ArkNativeString()38 ArkNativeString::~ArkNativeString() {}
39 
GetInterface(int interfaceId)40 void* ArkNativeString::GetInterface(int interfaceId)
41 {
42     return (NativeString::INTERFACE_ID == interfaceId) ? (NativeString*)this : nullptr;
43 }
44 
GetCString(char * buffer,size_t size,size_t * length)45 void ArkNativeString::GetCString(char* buffer, size_t size, size_t* length)
46 {
47     if (length == nullptr) {
48         return;
49     }
50     auto vm = engine_->GetEcmaVm();
51     LocalScope scope(vm);
52     Global<StringRef> val = value_;
53     if (buffer == nullptr) {
54         *length = val->Utf8Length() - 1;
55     } else if (size != 0) {
56         int copied = val->WriteUtf8(buffer, size - 1) - 1;
57         buffer[copied] = '\0';
58         *length = copied;
59     } else {
60         *length = 0;
61     }
62 }
63 
GetCString16(char16_t * buffer,size_t size,size_t * length)64 void ArkNativeString::GetCString16(char16_t* buffer, size_t size, size_t* length) {}
65 
GetLength()66 size_t ArkNativeString::GetLength()
67 {
68     auto vm = engine_->GetEcmaVm();
69     LocalScope scope(vm);
70     Global<StringRef> value = value_;
71     return value->Utf8Length() - 1;
72 }
73 
EncodeWriteUtf8(char * buffer,size_t bufferSize,int32_t * nchars)74 size_t ArkNativeString::EncodeWriteUtf8(char* buffer, size_t bufferSize, int32_t* nchars)
75 {
76     if (buffer == nullptr || nchars == nullptr) {
77         HILOG_ERROR("buffer is null or nchars is null");
78         return 0;
79     }
80 
81     auto vm = engine_->GetEcmaVm();
82     LocalScope scope(vm);
83     Global<StringRef> val = value_;
84     int32_t length = val->Length();
85 
86     int32_t pos = 0;
87     int32_t writableSize = static_cast<int32_t>(bufferSize);
88     int32_t i = 0;
89     Local<ObjectRef> strObj = Local<ObjectRef>(val.ToLocal(vm));
90     for (; i < length; i++) {
91         Local<StringRef> str = Local<StringRef>(strObj->Get(vm, i));
92         int32_t len = str->Utf8Length() - 1;
93         if (len > writableSize) {
94             break;
95         }
96 
97         str->WriteUtf8((buffer + pos), writableSize);
98         writableSize -= len;
99         pos += len;
100     }
101 
102     *nchars = i;
103     HILOG_DEBUG("EncodeWriteUtf8 the result of buffer: %{public}s", buffer);
104     return pos;
105 }
106 
EncodeWriteChinese(std::string & buffer,const char * encoding)107 void ArkNativeString::EncodeWriteChinese(std::string& buffer, const char* encoding)
108 {
109     if (encoding == nullptr) {
110         HILOG_ERROR("encoding is nullptr");
111         return;
112     }
113     auto vm = engine_->GetEcmaVm();
114     LocalScope scope(vm);
115     Global<StringRef> val = value_;
116     int32_t length = val->Length();
117     Local<ObjectRef> strObj = Local<ObjectRef>(val.ToLocal(vm));
118 
119     int32_t pos = 0;
120     const int32_t writableSize = 22; // 22 : encode max bytes of the ucnv_convent function;
121 
122     std::string tempBuf = "";
123     tempBuf.resize(writableSize + 1);
124 
125     UErrorCode ErrorCode = U_ZERO_ERROR;
126     const char* encFrom = "utf8";
127     for (int32_t i = 0; i < length; i++) {
128         Local<StringRef> str = Local<StringRef>(strObj->Get(vm, i));
129         int32_t len = str->Utf8Length() - 1;
130         if ((pos + len) >= writableSize) {
131             char outBuf[writableSize] = {0};
132             ucnv_convert(encoding, encFrom, outBuf, writableSize, tempBuf.c_str(), pos, &ErrorCode);
133             if (ErrorCode != U_ZERO_ERROR) {
134                 HILOG_ERROR("ucnv_convert is failed : ErrorCode = %{public}d", static_cast<int32_t>(ErrorCode));
135                 return;
136             }
137             buffer += outBuf;
138             tempBuf.clear();
139             pos = 0;
140         }
141         str->WriteUtf8((tempBuf.data() + pos), writableSize);
142         pos += len;
143     }
144     if (pos > 0) {
145         char outBuf[writableSize] = {0};
146         ucnv_convert(encoding, encFrom, outBuf, writableSize, tempBuf.c_str(), pos, &ErrorCode);
147         if (ErrorCode != U_ZERO_ERROR) {
148             HILOG_ERROR("ucnv_convert is failed : ErrorCode = %{public}d", static_cast<int32_t>(ErrorCode));
149             return;
150         }
151         buffer += outBuf;
152     }
153 }
154