1/*
2 * Copyright (c) 2023 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#ifndef ECMASCRIPT_BASE_JSON_HELPER_H
17#define ECMASCRIPT_BASE_JSON_HELPER_H
18
19#include "ecmascript/js_handle.h"
20#include "ecmascript/mem/c_string.h"
21#include "ecmascript/property_attributes.h"
22
23namespace panda::ecmascript::base {
24constexpr int HEX_DIGIT_MASK = 0xF;
25constexpr int HEX_SHIFT_THREE = 12;
26constexpr int HEX_SHIFT_TWO = 8;
27constexpr int HEX_SHIFT_ONE = 4;
28
29class JsonHelper {
30public:
31    enum class TransformType : uint32_t {
32        SENDABLE = 1,
33        NORMAL = 2,
34        BIGINT = 3
35    };
36
37    enum class BigIntMode : uint8_t {
38        DEFAULT,
39        PARSE_AS_BIGINT,
40        ALWAYS_PARSE_AS_BIGINT
41    };
42
43    enum class ParseReturnType : uint8_t {
44        OBJECT,
45        MAP
46    };
47
48    struct ParseOptions {
49        BigIntMode bigIntMode = BigIntMode::DEFAULT;
50        ParseReturnType returnType = ParseReturnType::OBJECT;
51
52        ParseOptions() = default;
53        ParseOptions(BigIntMode bigIntMode, ParseReturnType returnType)
54        {
55            this->bigIntMode = bigIntMode;
56            this->returnType = returnType;
57        }
58    };
59
60    static inline bool IsTypeSupportBigInt(TransformType type)
61    {
62        return type == TransformType::SENDABLE || type == TransformType::BIGINT;
63    }
64
65    static inline void AppendUnicodeEscape(int ch, CString& output)
66    {
67        static constexpr char HEX_DIGIT[] = "0123456789abcdef";
68        output += "\\u";
69        output += HEX_DIGIT[(ch >> HEX_SHIFT_THREE) & HEX_DIGIT_MASK];
70        output += HEX_DIGIT[(ch >> HEX_SHIFT_TWO) & HEX_DIGIT_MASK];
71        output += HEX_DIGIT[(ch >> HEX_SHIFT_ONE) & HEX_DIGIT_MASK];
72        output += HEX_DIGIT[ch & HEX_DIGIT_MASK];
73    }
74
75    static bool IsFastValueToQuotedString(const CString& str);
76    static void AppendValueToQuotedString(const CString& str, CString& output);
77
78    static inline bool CompareKey(const std::pair<JSHandle<JSTaggedValue>, PropertyAttributes> &a,
79                                  const std::pair<JSHandle<JSTaggedValue>, PropertyAttributes> &b)
80    {
81        return a.second.GetDictionaryOrder() < b.second.GetDictionaryOrder();
82    }
83
84    static inline bool CompareNumber(const JSHandle<JSTaggedValue> &a, const JSHandle<JSTaggedValue> &b)
85    {
86        return a->GetNumber() < b->GetNumber();
87    }
88};
89
90}  // namespace panda::ecmascript::base
91
92#endif  // ECMASCRIPT_BASE_UTF_JSON_H