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 #include "libpandabase/utils/span.h" 23 24 namespace panda::ecmascript::base { 25 constexpr int HEX_DIGIT_MASK = 0xF; 26 constexpr int HEX_SHIFT_THREE = 12; 27 constexpr int HEX_SHIFT_TWO = 8; 28 constexpr int HEX_SHIFT_ONE = 4; 29 constexpr uint8_t CODE_SPACE = 0x20; 30 #if !ENABLE_NEXT_OPTIMIZATION 31 constexpr uint8_t ZERO_FIRST = 0xc0; // \u0000 => c0 80 32 constexpr uint8_t ALONE_SURROGATE_3B_FIRST = 0xed; 33 constexpr uint8_t ALONE_SURROGATE_3B_SECOND_START = 0xa0; 34 constexpr uint8_t ALONE_SURROGATE_3B_SECOND_END = 0xbf; 35 constexpr uint8_t ALONE_SURROGATE_3B_THIRD_START = 0x80; 36 constexpr uint8_t ALONE_SURROGATE_3B_THIRD_END = 0xbf; 37 #endif 38 39 class JsonHelper { 40 public: 41 enum class TransformType : uint32_t { 42 SENDABLE = 1, 43 NORMAL = 2, 44 BIGINT = 3 45 }; 46 47 enum class BigIntMode : uint8_t { 48 DEFAULT, 49 PARSE_AS_BIGINT, 50 ALWAYS_PARSE_AS_BIGINT 51 }; 52 53 enum class ParseReturnType : uint8_t { 54 OBJECT, 55 MAP 56 }; 57 58 struct ParseOptions { 59 BigIntMode bigIntMode = BigIntMode::DEFAULT; 60 ParseReturnType returnType = ParseReturnType::OBJECT; 61 62 ParseOptions() = default; ParseOptionsParseOptions63 ParseOptions(BigIntMode bigIntMode, ParseReturnType returnType) 64 { 65 this->bigIntMode = bigIntMode; 66 this->returnType = returnType; 67 } 68 }; 69 IsTypeSupportBigInt(TransformType type)70 static inline bool IsTypeSupportBigInt(TransformType type) 71 { 72 return type == TransformType::SENDABLE || type == TransformType::BIGINT; 73 } 74 75 template <typename T> AppendUnicodeEscape(uint32_t ch,T & output)76 static inline void AppendUnicodeEscape(uint32_t ch, T& output) 77 { 78 static constexpr char HEX_DIGIT[] = "0123456789abcdef"; 79 AppendString(output, "\\u"); 80 AppendChar(output, HEX_DIGIT[(ch >> HEX_SHIFT_THREE) & HEX_DIGIT_MASK]); 81 AppendChar(output, HEX_DIGIT[(ch >> HEX_SHIFT_TWO) & HEX_DIGIT_MASK]); 82 AppendChar(output, HEX_DIGIT[(ch >> HEX_SHIFT_ONE) & HEX_DIGIT_MASK]); 83 AppendChar(output, HEX_DIGIT[ch & HEX_DIGIT_MASK]); 84 } 85 86 #if ENABLE_NEXT_OPTIMIZATION 87 static bool IsFastValueToQuotedString(const Span<const uint8_t> &sp); 88 #else 89 static bool IsFastValueToQuotedString(const CString &str); 90 #endif 91 92 // String values are wrapped in QUOTATION MARK (") code units. The code units " and \ are escaped with \ prefixes. 93 // Control characters code units are replaced with escape sequences \uHHHH, or with the shorter forms, 94 // \b (BACKSPACE), \f (FORM FEED), \n (LINE FEED), \r (CARRIAGE RETURN), \t (CHARACTER TABULATION). 95 #if ENABLE_NEXT_OPTIMIZATION 96 static void AppendQuotedValueToC16String(const Span<const uint16_t> &sp, uint32_t &index, C16String &output); 97 template <typename SrcType, typename DstType> 98 static void AppendValueToQuotedString(const Span<const SrcType> &sp, DstType &output); 99 #else 100 static void AppendValueToQuotedString(const CString& str, CString& output); 101 #endif 102 CompareKey(const std::pair<JSHandle<JSTaggedValue>,PropertyAttributes> & a,const std::pair<JSHandle<JSTaggedValue>,PropertyAttributes> & b)103 static inline bool CompareKey(const std::pair<JSHandle<JSTaggedValue>, PropertyAttributes> &a, 104 const std::pair<JSHandle<JSTaggedValue>, PropertyAttributes> &b) 105 { 106 return a.second.GetDictionaryOrder() < b.second.GetDictionaryOrder(); 107 } 108 CompareNumber(const JSHandle<JSTaggedValue> & a,const JSHandle<JSTaggedValue> & b)109 static inline bool CompareNumber(const JSHandle<JSTaggedValue> &a, const JSHandle<JSTaggedValue> &b) 110 { 111 return a->GetNumber() < b->GetNumber(); 112 } 113 }; 114 115 } // namespace panda::ecmascript::base 116 117 #endif // ECMASCRIPT_BASE_UTF_JSON_H