1 /* 2 * Copyright (c) 2025 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 PANDA_PLUGINS_ETS_RUNTIME_JSON_HELPER 17 #define PANDA_PLUGINS_ETS_RUNTIME_JSON_HELPER 18 19 #include "types/ets_string.h" 20 21 namespace ark::ets::intrinsics::helpers { 22 class JSONStringifier { 23 public: 24 explicit JSONStringifier() = default; 25 26 EtsString *Stringify(EtsHandle<EtsObject> &value); 27 28 private: IsHighSurrogate(uint16_t ch)29 static inline bool IsHighSurrogate(uint16_t ch) 30 { 31 return ch >= utf::DECODE_LEAD_LOW && ch <= utf::DECODE_LEAD_HIGH; 32 } 33 IsLowSurrogate(uint16_t ch)34 static inline bool IsLowSurrogate(uint16_t ch) 35 { 36 return ch >= utf::DECODE_TRAIL_LOW && ch <= utf::DECODE_TRAIL_HIGH; 37 } 38 AppendUnicodeEscape(uint32_t ch)39 inline void AppendUnicodeEscape(uint32_t ch) 40 { 41 buffer_ += "\\u"; 42 buffer_ += HEX_DIGIT[(ch >> HEX_SHIFT_THREE) & HEX_DIGIT_MASK]; 43 buffer_ += HEX_DIGIT[(ch >> HEX_SHIFT_TWO) & HEX_DIGIT_MASK]; 44 buffer_ += HEX_DIGIT[(ch >> HEX_SHIFT_ONE) & HEX_DIGIT_MASK]; 45 buffer_ += HEX_DIGIT[ch & HEX_DIGIT_MASK]; 46 } 47 48 private: 49 bool AppendJSONString(EtsHandle<EtsObject> &value, bool hasContent); 50 void AppendJSONPrimitive(const PandaString &value, bool hasContent); 51 void AppendJSONPointPrimitive(const PandaString &value, bool hasContent); 52 53 bool SerializeFields(EtsHandle<EtsObject> &value); 54 55 // handling of types 56 bool SerializeJSONObject(EtsHandle<EtsObject> &value); 57 bool SerializeJSONObjectArray(EtsHandle<EtsObject> &value); 58 59 void AppendUtf16ToQuotedString(const Span<const uint16_t> &sp); 60 void AppendUtf8ToQuotedString(const Span<const uint8_t> &sp); 61 uint32_t AppendUtf8Character(const Span<const uint8_t> &sp, uint32_t index); 62 void DealUtf16Character(uint16_t ch0, uint16_t ch1); 63 bool SerializeJSONString(EtsHandle<EtsObject> &value); 64 bool DealSpecialCharacter(uint8_t ch); 65 66 bool SerializeJSONBoxedBoolean(EtsHandle<EtsObject> &value); 67 bool SerializeJSONBoxedDouble(EtsHandle<EtsObject> &value); 68 bool SerializeJSONBoxedFloat(EtsHandle<EtsObject> &value); 69 bool SerializeJSONBoxedLong(EtsHandle<EtsObject> &value); 70 71 template <typename T> 72 bool SerializeJSONBoxedPrimitiveNoCache(EtsHandle<EtsObject> &value); 73 74 bool SerializeEmptyObject(); 75 bool SerializeJSONNullValue(); 76 bool SerializeJSONRecord(EtsHandle<EtsObject> &value); 77 78 bool PushValue(EtsHandle<EtsObject> &value); 79 80 PandaString ResolveDisplayName(const EtsField *field); 81 82 bool SerializeObject(EtsHandle<EtsObject> &value); 83 bool HandleField(EtsHandle<EtsObject> &obj, EtsField *field, bool &hasContent, 84 PandaUnorderedSet<PandaString> &keys); 85 bool HandleRecordKey(EtsHandle<EtsObject> &key); 86 template <typename T> 87 PandaString HandleNumeric(EtsHandle<EtsObject> &value); 88 89 bool CheckUnsupportedAnnotation(EtsField *field); 90 91 private: 92 PandaString buffer_; 93 PandaString key_; 94 PandaUnorderedSet<uint32_t> path_; 95 96 const bool modify_ = false; 97 static constexpr uint8_t CODE_SPACE = 0x20; 98 static constexpr unsigned HEX_DIGIT_MASK = 0xF; 99 static constexpr unsigned HEX_SHIFT_THREE = 12; 100 static constexpr unsigned HEX_SHIFT_TWO = 8; 101 static constexpr unsigned HEX_SHIFT_ONE = 4; 102 103 // NOLINTNEXTLINE(modernize-avoid-c-arrays) 104 static constexpr char HEX_DIGIT[] = "0123456789abcdef"; 105 }; 106 } // namespace ark::ets::intrinsics::helpers 107 #endif // PANDA_PLUGINS_ETS_RUNTIME_JSON_HELPER 108