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 30 class JsonHelper { 31 public: 32 enum class TransformType : uint32_t { 33 SENDABLE = 1, 34 NORMAL = 2, 35 BIGINT = 3 36 }; 37 38 enum class BigIntMode : uint8_t { 39 DEFAULT, 40 PARSE_AS_BIGINT, 41 ALWAYS_PARSE_AS_BIGINT 42 }; 43 44 enum class ParseReturnType : uint8_t { 45 OBJECT, 46 MAP 47 }; 48 49 struct ParseOptions { 50 BigIntMode bigIntMode = BigIntMode::DEFAULT; 51 ParseReturnType returnType = ParseReturnType::OBJECT; 52 53 ParseOptions() = default; ParseOptionsParseOptions54 ParseOptions(BigIntMode bigIntMode, ParseReturnType returnType) 55 { 56 this->bigIntMode = bigIntMode; 57 this->returnType = returnType; 58 } 59 }; 60 IsTypeSupportBigInt(TransformType type)61 static inline bool IsTypeSupportBigInt(TransformType type) 62 { 63 return type == TransformType::SENDABLE || type == TransformType::BIGINT; 64 } 65 AppendUnicodeEscape(uint32_t ch,CString & output)66 static inline void AppendUnicodeEscape(uint32_t ch, CString& output) 67 { 68 static constexpr char HEX_DIGIT[] = "0123456789abcdef"; 69 output += "\\u"; 70 output += HEX_DIGIT[(ch >> HEX_SHIFT_THREE) & HEX_DIGIT_MASK]; 71 output += HEX_DIGIT[(ch >> HEX_SHIFT_TWO) & HEX_DIGIT_MASK]; 72 output += HEX_DIGIT[(ch >> HEX_SHIFT_ONE) & HEX_DIGIT_MASK]; 73 output += HEX_DIGIT[ch & HEX_DIGIT_MASK]; 74 } 75 76 static bool IsFastValueToQuotedString(const CString& str); 77 static bool IsFastValueToQuotedString(const Span<const uint8_t>& sp); 78 79 // String values are wrapped in QUOTATION MARK (") code units. The code units " and \ are escaped with \ prefixes. 80 // Control characters code units are replaced with escape sequences \uHHHH, or with the shorter forms, 81 // \b (BACKSPACE), \f (FORM FEED), \n (LINE FEED), \r (CARRIAGE RETURN), \t (CHARACTER TABULATION). 82 static void AppendValueToQuotedString(const CString& str, CString& output); 83 static void AppendValueToQuotedString(const Span<const uint8_t>& sp, CString& output); 84 CompareKey(const std::pair<JSHandle<JSTaggedValue>,PropertyAttributes> & a,const std::pair<JSHandle<JSTaggedValue>,PropertyAttributes> & b)85 static inline bool CompareKey(const std::pair<JSHandle<JSTaggedValue>, PropertyAttributes> &a, 86 const std::pair<JSHandle<JSTaggedValue>, PropertyAttributes> &b) 87 { 88 return a.second.GetDictionaryOrder() < b.second.GetDictionaryOrder(); 89 } 90 CompareNumber(const JSHandle<JSTaggedValue> & a,const JSHandle<JSTaggedValue> & b)91 static inline bool CompareNumber(const JSHandle<JSTaggedValue> &a, const JSHandle<JSTaggedValue> &b) 92 { 93 return a->GetNumber() < b->GetNumber(); 94 } 95 }; 96 97 } // namespace panda::ecmascript::base 98 99 #endif // ECMASCRIPT_BASE_UTF_JSON_H