• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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