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
24namespace panda::ecmascript {
25long 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
33int64_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
41uint64_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
49float 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
58double 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
67template<class T>
68CString 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!
87CString 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
97CString 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
105CString 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
120std::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