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 "ecmascript/mem/c_string.h"
17 
18 #include <cmath>
19 #include <cstdlib>
20 
21 #include "ecmascript/ecma_string-inl.h"
22 #include "ecmascript/js_symbol.h"
23 
24 namespace panda::ecmascript {
CStringToL(const CString &str)25 long CStringToL(const CString &str)
26 {
27     char *endPtr = nullptr;
28     int64_t result = std::strtol(str.c_str(), &endPtr, BASE);
29     ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not long int");
30     return result;
31 }
32 
CStringToLL(const CString &str)33 int64_t CStringToLL(const CString &str)
34 {
35     char *endPtr = nullptr;
36     int64_t result = std::strtoll(str.c_str(), &endPtr, BASE);
37     ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not long long int");
38     return result;
39 }
40 
CStringToULL(const CString &str)41 uint64_t CStringToULL(const CString &str)
42 {
43     char *endPtr = nullptr;
44     uint64_t result = std::strtoull(str.c_str(), &endPtr, BASE);
45     ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not unsigned long long int");
46     return result;
47 }
48 
CStringToF(const CString &str)49 float CStringToF(const CString &str)
50 {
51     char *endPtr = nullptr;
52     float result = std::strtof(str.c_str(), &endPtr);
53     ASSERT(result != HUGE_VALF && "CString argument is not float");
54     ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not float");
55     return result;
56 }
57 
CStringToD(const CString &str)58 double CStringToD(const CString &str)
59 {
60     char *endPtr = nullptr;
61     double result = std::strtod(str.c_str(), &endPtr);
62     ASSERT(result != HUGE_VALF && "CString argument is not double");
63     ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not double");
64     return result;
65 }
66 
67 template<class T>
ConvertToString(T sp)68 CString ConvertToString(T sp)
69 {
70     CString res;
71     res.reserve(sp.size());
72 
73     // Also support ascii that great than 127, so using unsigned char here
74     constexpr size_t maxChar = std::numeric_limits<unsigned char>::max();
75 
76     for (const auto &c : sp) {
77         if (c > maxChar) {
78             return "";
79         }
80         res.push_back(c);
81     }
82 
83     return res;
84 }
85 
86 // NB! the following function need additional mem allocation, don't use when unnecessary!
ConvertToString(const std::string &str)87 CString ConvertToString(const std::string &str)
88 {
89     CString res;
90     res.reserve(str.size());
91     for (auto c : str) {
92         res.push_back(c);
93     }
94     return res;
95 }
96 
ConvertToString(const EcmaString *s, StringConvertedUsage usage, bool cesu8)97 CString ConvertToString(const EcmaString *s, StringConvertedUsage usage, bool cesu8)
98 {
99     if (s == nullptr) {
100         return CString("");
101     }
102     return EcmaStringAccessor(const_cast<EcmaString *>(s)).ToCString(usage, cesu8);
103 }
104 
ConvertToString(JSTaggedValue key)105 CString ConvertToString(JSTaggedValue key)
106 {
107     ASSERT(key.IsStringOrSymbol());
108     if (key.IsString()) {
109         return ConvertToString(EcmaString::ConstCast(key.GetTaggedObject()));
110     }
111 
112     ecmascript::JSTaggedValue desc = JSSymbol::Cast(key.GetTaggedObject())->GetDescription();
113     if (desc.IsUndefined()) {
114         return CString("Symbol()");
115     }
116 
117     return ConvertToString(EcmaString::ConstCast(desc.GetTaggedObject()));
118 }
119 
ConvertToStdString(const CString &str)120 std::string ConvertToStdString(const CString &str)
121 {
122     std::string res;
123     res.reserve(str.size());
124     for (auto c : str) {
125         res.push_back(c);
126     }
127     return res;
128 }
129 }  // namespace panda::ecmascript
130