be/src/util/variant/variant_json.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #pragma once |
19 | | |
20 | | #include <array> |
21 | | #include <cmath> |
22 | | #include <cstddef> |
23 | | #include <cstdint> |
24 | | #include <memory> |
25 | | #include <string> |
26 | | |
27 | | #include "common/status.h" |
28 | | #include "util/variant/variant_encoded_block.h" |
29 | | #include "util/variant/variant_value.h" |
30 | | |
31 | | namespace cctz { |
32 | | class time_zone; |
33 | | } |
34 | | |
35 | | namespace doris { |
36 | | |
37 | | // Formatting state supplied by the column adapter. A null time zone means UTC. |
38 | | struct VariantJsonFormatOptions { |
39 | | const cctz::time_zone* timezone = nullptr; |
40 | | }; |
41 | | |
42 | | struct JsonToVariantOptions { |
43 | | uint32_t max_json_key_length = 255; |
44 | | bool throw_on_invalid_json = false; |
45 | | bool check_duplicate_json_path = false; |
46 | | |
47 | | // Takes a value snapshot. Later changes to mutable config do not affect an encoder. |
48 | | static JsonToVariantOptions current_config(); |
49 | | }; |
50 | | |
51 | | // Reuses one JSON parser and one block builder. Each add_json() collects into a stack-only row; |
52 | | // finish_block() performs pass 2. A failed add_json() is terminal, as is a successful |
53 | | // finish_block(). try_add_json() rolls back invalid input rows and keeps collecting. |
54 | | class JsonToVariantEncoder { |
55 | | public: |
56 | | JsonToVariantEncoder(); |
57 | | explicit JsonToVariantEncoder(JsonToVariantOptions options); |
58 | | ~JsonToVariantEncoder(); |
59 | | |
60 | | JsonToVariantEncoder(const JsonToVariantEncoder&) = delete; |
61 | | JsonToVariantEncoder& operator=(const JsonToVariantEncoder&) = delete; |
62 | | JsonToVariantEncoder(JsonToVariantEncoder&&) noexcept; |
63 | | JsonToVariantEncoder& operator=(JsonToVariantEncoder&&) noexcept; |
64 | | |
65 | | void add_json(StringRef json); |
66 | | Status try_add_json(StringRef json); |
67 | | VariantEncodedBlock finish_block(); |
68 | | |
69 | | private: |
70 | | struct Impl; |
71 | | std::unique_ptr<Impl> _impl; |
72 | | }; |
73 | | |
74 | | namespace variant_json_detail { |
75 | | |
76 | | struct FormattedScalar { |
77 | | std::array<char, 128> bytes {}; |
78 | | size_t size = 0; |
79 | | }; |
80 | | |
81 | | void require_json_depth(uint32_t depth); |
82 | | void require_exact_json_value(VariantValueRef value); |
83 | | void require_valid_json_utf8(StringRef value, const char* description); |
84 | | void require_json_object_key(StringRef key, StringRef previous_key, uint32_t field_index); |
85 | | [[noreturn]] void throw_unsupported_json_primitive(VariantPrimitiveId id); |
86 | | |
87 | | FormattedScalar format_json_int(int64_t value); |
88 | | FormattedScalar format_json_float(float value); |
89 | | FormattedScalar format_json_double(double value); |
90 | | FormattedScalar format_json_decimal(VariantDecimal value); |
91 | | FormattedScalar format_json_date(int32_t days_since_epoch); |
92 | | FormattedScalar format_json_timestamp(int64_t value, uint8_t fractional_digits, bool utc_adjusted, |
93 | | const cctz::time_zone* timezone); |
94 | | FormattedScalar format_json_time_micros(int64_t value); |
95 | | FormattedScalar format_json_uuid(const std::array<uint8_t, 16>& value); |
96 | | |
97 | | template <typename Writer, size_t N> |
98 | 701 | void write_literal(Writer& out, const char (&value)[N]) { |
99 | 701 | out.write(value, N - 1); |
100 | 701 | } _ZN5doris19variant_json_detail13write_literalINS_14BufferWritableELm2EEEvRT_RAT0__Kc Line | Count | Source | 98 | 170 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 170 | out.write(value, N - 1); | 100 | 170 | } |
_ZN5doris19variant_json_detail13write_literalINS_14BufferWritableELm5EEEvRT_RAT0__Kc Line | Count | Source | 98 | 18 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 18 | out.write(value, N - 1); | 100 | 18 | } |
_ZN5doris19variant_json_detail13write_literalINS_14BufferWritableELm6EEEvRT_RAT0__Kc Line | Count | Source | 98 | 6 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 6 | out.write(value, N - 1); | 100 | 6 | } |
_ZN5doris19variant_json_detail13write_literalINS_14BufferWritableELm11EEEvRT_RAT0__Kc Line | Count | Source | 98 | 6 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 6 | out.write(value, N - 1); | 100 | 6 | } |
_ZN5doris19variant_json_detail13write_literalINS_14BufferWritableELm12EEEvRT_RAT0__Kc Line | Count | Source | 98 | 6 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 6 | out.write(value, N - 1); | 100 | 6 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal14CountingWriterELm2EEEvRT_RAT0__Kc Line | Count | Source | 98 | 261 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 261 | out.write(value, N - 1); | 100 | 261 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal14CountingWriterELm5EEEvRT_RAT0__Kc Line | Count | Source | 98 | 33 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 33 | out.write(value, N - 1); | 100 | 33 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal14CountingWriterELm6EEEvRT_RAT0__Kc Line | Count | Source | 98 | 14 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 14 | out.write(value, N - 1); | 100 | 14 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal14CountingWriterELm11EEEvRT_RAT0__Kc Line | Count | Source | 98 | 14 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 14 | out.write(value, N - 1); | 100 | 14 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal14CountingWriterELm12EEEvRT_RAT0__Kc Line | Count | Source | 98 | 14 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 14 | out.write(value, N - 1); | 100 | 14 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal11FixedWriterELm2EEEvRT_RAT0__Kc Line | Count | Source | 98 | 121 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 121 | out.write(value, N - 1); | 100 | 121 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal11FixedWriterELm5EEEvRT_RAT0__Kc Line | Count | Source | 98 | 14 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 14 | out.write(value, N - 1); | 100 | 14 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal11FixedWriterELm6EEEvRT_RAT0__Kc Line | Count | Source | 98 | 8 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 8 | out.write(value, N - 1); | 100 | 8 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal11FixedWriterELm11EEEvRT_RAT0__Kc Line | Count | Source | 98 | 8 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 8 | out.write(value, N - 1); | 100 | 8 | } |
_ZN5doris19variant_json_detail13write_literalINS_35data_type_variant_v2_serde_internal11FixedWriterELm12EEEvRT_RAT0__Kc Line | Count | Source | 98 | 8 | void write_literal(Writer& out, const char (&value)[N]) { | 99 | 8 | out.write(value, N - 1); | 100 | 8 | } |
|
101 | | |
102 | | template <typename Writer> |
103 | 151 | void write_scalar(Writer& out, const FormattedScalar& value) { |
104 | 151 | out.write(value.bytes.data(), value.size); |
105 | 151 | } _ZN5doris19variant_json_detail12write_scalarINS_14BufferWritableEEEvRT_RKNS0_15FormattedScalarE Line | Count | Source | 103 | 41 | void write_scalar(Writer& out, const FormattedScalar& value) { | 104 | 41 | out.write(value.bytes.data(), value.size); | 105 | 41 | } |
_ZN5doris19variant_json_detail12write_scalarINS_35data_type_variant_v2_serde_internal14CountingWriterEEEvRT_RKNS0_15FormattedScalarE Line | Count | Source | 103 | 73 | void write_scalar(Writer& out, const FormattedScalar& value) { | 104 | 73 | out.write(value.bytes.data(), value.size); | 105 | 73 | } |
_ZN5doris19variant_json_detail12write_scalarINS_35data_type_variant_v2_serde_internal11FixedWriterEEEvRT_RKNS0_15FormattedScalarE Line | Count | Source | 103 | 37 | void write_scalar(Writer& out, const FormattedScalar& value) { | 104 | 37 | out.write(value.bytes.data(), value.size); | 105 | 37 | } |
|
106 | | |
107 | | template <typename Writer> |
108 | 62 | void write_quoted_scalar(Writer& out, const FormattedScalar& value) { |
109 | 62 | write_literal(out, "\""); |
110 | 62 | write_scalar(out, value); |
111 | 62 | write_literal(out, "\""); |
112 | 62 | } _ZN5doris19variant_json_detail19write_quoted_scalarINS_14BufferWritableEEEvRT_RKNS0_15FormattedScalarE Line | Count | Source | 108 | 14 | void write_quoted_scalar(Writer& out, const FormattedScalar& value) { | 109 | 14 | write_literal(out, "\""); | 110 | 14 | write_scalar(out, value); | 111 | 14 | write_literal(out, "\""); | 112 | 14 | } |
_ZN5doris19variant_json_detail19write_quoted_scalarINS_35data_type_variant_v2_serde_internal14CountingWriterEEEvRT_RKNS0_15FormattedScalarE Line | Count | Source | 108 | 30 | void write_quoted_scalar(Writer& out, const FormattedScalar& value) { | 109 | 30 | write_literal(out, "\""); | 110 | 30 | write_scalar(out, value); | 111 | 30 | write_literal(out, "\""); | 112 | 30 | } |
_ZN5doris19variant_json_detail19write_quoted_scalarINS_35data_type_variant_v2_serde_internal11FixedWriterEEEvRT_RKNS0_15FormattedScalarE Line | Count | Source | 108 | 18 | void write_quoted_scalar(Writer& out, const FormattedScalar& value) { | 109 | 18 | write_literal(out, "\""); | 110 | 18 | write_scalar(out, value); | 111 | 18 | write_literal(out, "\""); | 112 | 18 | } |
|
113 | | |
114 | | template <typename Writer> |
115 | 127 | void write_escaped_json_string(Writer& out, StringRef value) { |
116 | 127 | write_literal(out, "\""); |
117 | 127 | size_t plain_begin = 0; |
118 | 127 | size_t index = 0; |
119 | 722 | while (index < value.size) { |
120 | 595 | const auto byte = static_cast<uint8_t>(value.data[index]); |
121 | 595 | const char* escaped = nullptr; |
122 | 595 | size_t escaped_size = 0; |
123 | 595 | size_t consumed = 1; |
124 | 595 | switch (byte) { |
125 | 90 | case '"': |
126 | 90 | escaped = "\\\""; |
127 | 90 | escaped_size = 2; |
128 | 90 | break; |
129 | 2 | case '\\': |
130 | 2 | escaped = "\\\\"; |
131 | 2 | escaped_size = 2; |
132 | 2 | break; |
133 | 0 | case '\b': |
134 | 0 | escaped = "\\b"; |
135 | 0 | escaped_size = 2; |
136 | 0 | break; |
137 | 0 | case '\f': |
138 | 0 | escaped = "\\f"; |
139 | 0 | escaped_size = 2; |
140 | 0 | break; |
141 | 30 | case '\n': |
142 | 30 | escaped = "\\n"; |
143 | 30 | escaped_size = 2; |
144 | 30 | break; |
145 | 0 | case '\r': |
146 | 0 | escaped = "\\r"; |
147 | 0 | escaped_size = 2; |
148 | 0 | break; |
149 | 0 | case '\t': |
150 | 0 | escaped = "\\t"; |
151 | 0 | escaped_size = 2; |
152 | 0 | break; |
153 | 473 | default: |
154 | 473 | if (byte < 0x20) { |
155 | 0 | static constexpr char HEX[] = "0123456789ABCDEF"; |
156 | 0 | char unicode_escape[] = {'\\', 'u', '0', '0', HEX[byte >> 4], HEX[byte & 0x0F]}; |
157 | 0 | if (index != plain_begin) { |
158 | 0 | out.write(value.data + plain_begin, index - plain_begin); |
159 | 0 | } |
160 | 0 | out.write(unicode_escape, sizeof(unicode_escape)); |
161 | 0 | ++index; |
162 | 0 | plain_begin = index; |
163 | 0 | continue; |
164 | 0 | } |
165 | 473 | if (index + 2 < value.size && byte == 0xE2 && |
166 | 473 | static_cast<uint8_t>(value.data[index + 1]) == 0x80 && |
167 | 473 | (static_cast<uint8_t>(value.data[index + 2]) == 0xA8 || |
168 | 0 | static_cast<uint8_t>(value.data[index + 2]) == 0xA9)) { |
169 | 0 | escaped = |
170 | 0 | static_cast<uint8_t>(value.data[index + 2]) == 0xA8 ? "\\u2028" : "\\u2029"; |
171 | 0 | escaped_size = 6; |
172 | 0 | consumed = 3; |
173 | 0 | } |
174 | 473 | break; |
175 | 595 | } |
176 | 595 | if (escaped == nullptr) { |
177 | 473 | ++index; |
178 | 473 | continue; |
179 | 473 | } |
180 | 122 | if (index != plain_begin) { |
181 | 94 | out.write(value.data + plain_begin, index - plain_begin); |
182 | 94 | } |
183 | 122 | out.write(escaped, escaped_size); |
184 | 122 | index += consumed; |
185 | 122 | plain_begin = index; |
186 | 122 | } |
187 | 127 | if (plain_begin != value.size) { |
188 | 99 | out.write(value.data + plain_begin, value.size - plain_begin); |
189 | 99 | } |
190 | 127 | write_literal(out, "\""); |
191 | 127 | } _ZN5doris19variant_json_detail25write_escaped_json_stringINS_14BufferWritableEEEvRT_NS_9StringRefE Line | Count | Source | 115 | 37 | void write_escaped_json_string(Writer& out, StringRef value) { | 116 | 37 | write_literal(out, "\""); | 117 | 37 | size_t plain_begin = 0; | 118 | 37 | size_t index = 0; | 119 | 195 | while (index < value.size) { | 120 | 158 | const auto byte = static_cast<uint8_t>(value.data[index]); | 121 | 158 | const char* escaped = nullptr; | 122 | 158 | size_t escaped_size = 0; | 123 | 158 | size_t consumed = 1; | 124 | 158 | switch (byte) { | 125 | 21 | case '"': | 126 | 21 | escaped = "\\\""; | 127 | 21 | escaped_size = 2; | 128 | 21 | break; | 129 | 1 | case '\\': | 130 | 1 | escaped = "\\\\"; | 131 | 1 | escaped_size = 2; | 132 | 1 | break; | 133 | 0 | case '\b': | 134 | 0 | escaped = "\\b"; | 135 | 0 | escaped_size = 2; | 136 | 0 | break; | 137 | 0 | case '\f': | 138 | 0 | escaped = "\\f"; | 139 | 0 | escaped_size = 2; | 140 | 0 | break; | 141 | 7 | case '\n': | 142 | 7 | escaped = "\\n"; | 143 | 7 | escaped_size = 2; | 144 | 7 | break; | 145 | 0 | case '\r': | 146 | 0 | escaped = "\\r"; | 147 | 0 | escaped_size = 2; | 148 | 0 | break; | 149 | 0 | case '\t': | 150 | 0 | escaped = "\\t"; | 151 | 0 | escaped_size = 2; | 152 | 0 | break; | 153 | 129 | default: | 154 | 129 | if (byte < 0x20) { | 155 | 0 | static constexpr char HEX[] = "0123456789ABCDEF"; | 156 | 0 | char unicode_escape[] = {'\\', 'u', '0', '0', HEX[byte >> 4], HEX[byte & 0x0F]}; | 157 | 0 | if (index != plain_begin) { | 158 | 0 | out.write(value.data + plain_begin, index - plain_begin); | 159 | 0 | } | 160 | 0 | out.write(unicode_escape, sizeof(unicode_escape)); | 161 | 0 | ++index; | 162 | 0 | plain_begin = index; | 163 | 0 | continue; | 164 | 0 | } | 165 | 129 | if (index + 2 < value.size && byte == 0xE2 && | 166 | 129 | static_cast<uint8_t>(value.data[index + 1]) == 0x80 && | 167 | 129 | (static_cast<uint8_t>(value.data[index + 2]) == 0xA8 || | 168 | 0 | static_cast<uint8_t>(value.data[index + 2]) == 0xA9)) { | 169 | 0 | escaped = | 170 | 0 | static_cast<uint8_t>(value.data[index + 2]) == 0xA8 ? "\\u2028" : "\\u2029"; | 171 | 0 | escaped_size = 6; | 172 | 0 | consumed = 3; | 173 | 0 | } | 174 | 129 | break; | 175 | 158 | } | 176 | 158 | if (escaped == nullptr) { | 177 | 129 | ++index; | 178 | 129 | continue; | 179 | 129 | } | 180 | 29 | if (index != plain_begin) { | 181 | 23 | out.write(value.data + plain_begin, index - plain_begin); | 182 | 23 | } | 183 | 29 | out.write(escaped, escaped_size); | 184 | 29 | index += consumed; | 185 | 29 | plain_begin = index; | 186 | 29 | } | 187 | 37 | if (plain_begin != value.size) { | 188 | 31 | out.write(value.data + plain_begin, value.size - plain_begin); | 189 | 31 | } | 190 | 37 | write_literal(out, "\""); | 191 | 37 | } |
_ZN5doris19variant_json_detail25write_escaped_json_stringINS_35data_type_variant_v2_serde_internal14CountingWriterEEEvRT_NS_9StringRefE Line | Count | Source | 115 | 61 | void write_escaped_json_string(Writer& out, StringRef value) { | 116 | 61 | write_literal(out, "\""); | 117 | 61 | size_t plain_begin = 0; | 118 | 61 | size_t index = 0; | 119 | 356 | while (index < value.size) { | 120 | 295 | const auto byte = static_cast<uint8_t>(value.data[index]); | 121 | 295 | const char* escaped = nullptr; | 122 | 295 | size_t escaped_size = 0; | 123 | 295 | size_t consumed = 1; | 124 | 295 | switch (byte) { | 125 | 45 | case '"': | 126 | 45 | escaped = "\\\""; | 127 | 45 | escaped_size = 2; | 128 | 45 | break; | 129 | 1 | case '\\': | 130 | 1 | escaped = "\\\\"; | 131 | 1 | escaped_size = 2; | 132 | 1 | break; | 133 | 0 | case '\b': | 134 | 0 | escaped = "\\b"; | 135 | 0 | escaped_size = 2; | 136 | 0 | break; | 137 | 0 | case '\f': | 138 | 0 | escaped = "\\f"; | 139 | 0 | escaped_size = 2; | 140 | 0 | break; | 141 | 15 | case '\n': | 142 | 15 | escaped = "\\n"; | 143 | 15 | escaped_size = 2; | 144 | 15 | break; | 145 | 0 | case '\r': | 146 | 0 | escaped = "\\r"; | 147 | 0 | escaped_size = 2; | 148 | 0 | break; | 149 | 0 | case '\t': | 150 | 0 | escaped = "\\t"; | 151 | 0 | escaped_size = 2; | 152 | 0 | break; | 153 | 234 | default: | 154 | 234 | if (byte < 0x20) { | 155 | 0 | static constexpr char HEX[] = "0123456789ABCDEF"; | 156 | 0 | char unicode_escape[] = {'\\', 'u', '0', '0', HEX[byte >> 4], HEX[byte & 0x0F]}; | 157 | 0 | if (index != plain_begin) { | 158 | 0 | out.write(value.data + plain_begin, index - plain_begin); | 159 | 0 | } | 160 | 0 | out.write(unicode_escape, sizeof(unicode_escape)); | 161 | 0 | ++index; | 162 | 0 | plain_begin = index; | 163 | 0 | continue; | 164 | 0 | } | 165 | 234 | if (index + 2 < value.size && byte == 0xE2 && | 166 | 234 | static_cast<uint8_t>(value.data[index + 1]) == 0x80 && | 167 | 234 | (static_cast<uint8_t>(value.data[index + 2]) == 0xA8 || | 168 | 0 | static_cast<uint8_t>(value.data[index + 2]) == 0xA9)) { | 169 | 0 | escaped = | 170 | 0 | static_cast<uint8_t>(value.data[index + 2]) == 0xA8 ? "\\u2028" : "\\u2029"; | 171 | 0 | escaped_size = 6; | 172 | 0 | consumed = 3; | 173 | 0 | } | 174 | 234 | break; | 175 | 295 | } | 176 | 295 | if (escaped == nullptr) { | 177 | 234 | ++index; | 178 | 234 | continue; | 179 | 234 | } | 180 | 61 | if (index != plain_begin) { | 181 | 47 | out.write(value.data + plain_begin, index - plain_begin); | 182 | 47 | } | 183 | 61 | out.write(escaped, escaped_size); | 184 | 61 | index += consumed; | 185 | 61 | plain_begin = index; | 186 | 61 | } | 187 | 61 | if (plain_begin != value.size) { | 188 | 47 | out.write(value.data + plain_begin, value.size - plain_begin); | 189 | 47 | } | 190 | 61 | write_literal(out, "\""); | 191 | 61 | } |
_ZN5doris19variant_json_detail25write_escaped_json_stringINS_35data_type_variant_v2_serde_internal11FixedWriterEEEvRT_NS_9StringRefE Line | Count | Source | 115 | 29 | void write_escaped_json_string(Writer& out, StringRef value) { | 116 | 29 | write_literal(out, "\""); | 117 | 29 | size_t plain_begin = 0; | 118 | 29 | size_t index = 0; | 119 | 171 | while (index < value.size) { | 120 | 142 | const auto byte = static_cast<uint8_t>(value.data[index]); | 121 | 142 | const char* escaped = nullptr; | 122 | 142 | size_t escaped_size = 0; | 123 | 142 | size_t consumed = 1; | 124 | 142 | switch (byte) { | 125 | 24 | case '"': | 126 | 24 | escaped = "\\\""; | 127 | 24 | escaped_size = 2; | 128 | 24 | break; | 129 | 0 | case '\\': | 130 | 0 | escaped = "\\\\"; | 131 | 0 | escaped_size = 2; | 132 | 0 | break; | 133 | 0 | case '\b': | 134 | 0 | escaped = "\\b"; | 135 | 0 | escaped_size = 2; | 136 | 0 | break; | 137 | 0 | case '\f': | 138 | 0 | escaped = "\\f"; | 139 | 0 | escaped_size = 2; | 140 | 0 | break; | 141 | 8 | case '\n': | 142 | 8 | escaped = "\\n"; | 143 | 8 | escaped_size = 2; | 144 | 8 | break; | 145 | 0 | case '\r': | 146 | 0 | escaped = "\\r"; | 147 | 0 | escaped_size = 2; | 148 | 0 | break; | 149 | 0 | case '\t': | 150 | 0 | escaped = "\\t"; | 151 | 0 | escaped_size = 2; | 152 | 0 | break; | 153 | 110 | default: | 154 | 110 | if (byte < 0x20) { | 155 | 0 | static constexpr char HEX[] = "0123456789ABCDEF"; | 156 | 0 | char unicode_escape[] = {'\\', 'u', '0', '0', HEX[byte >> 4], HEX[byte & 0x0F]}; | 157 | 0 | if (index != plain_begin) { | 158 | 0 | out.write(value.data + plain_begin, index - plain_begin); | 159 | 0 | } | 160 | 0 | out.write(unicode_escape, sizeof(unicode_escape)); | 161 | 0 | ++index; | 162 | 0 | plain_begin = index; | 163 | 0 | continue; | 164 | 0 | } | 165 | 110 | if (index + 2 < value.size && byte == 0xE2 && | 166 | 110 | static_cast<uint8_t>(value.data[index + 1]) == 0x80 && | 167 | 110 | (static_cast<uint8_t>(value.data[index + 2]) == 0xA8 || | 168 | 0 | static_cast<uint8_t>(value.data[index + 2]) == 0xA9)) { | 169 | 0 | escaped = | 170 | 0 | static_cast<uint8_t>(value.data[index + 2]) == 0xA8 ? "\\u2028" : "\\u2029"; | 171 | 0 | escaped_size = 6; | 172 | 0 | consumed = 3; | 173 | 0 | } | 174 | 110 | break; | 175 | 142 | } | 176 | 142 | if (escaped == nullptr) { | 177 | 110 | ++index; | 178 | 110 | continue; | 179 | 110 | } | 180 | 32 | if (index != plain_begin) { | 181 | 24 | out.write(value.data + plain_begin, index - plain_begin); | 182 | 24 | } | 183 | 32 | out.write(escaped, escaped_size); | 184 | 32 | index += consumed; | 185 | 32 | plain_begin = index; | 186 | 32 | } | 187 | 29 | if (plain_begin != value.size) { | 188 | 21 | out.write(value.data + plain_begin, value.size - plain_begin); | 189 | 21 | } | 190 | 29 | write_literal(out, "\""); | 191 | 29 | } |
|
192 | | |
193 | | template <typename Writer> |
194 | 103 | void write_json_string(Writer& out, StringRef value, const char* description) { |
195 | 103 | require_valid_json_utf8(value, description); |
196 | 103 | write_escaped_json_string(out, value); |
197 | 103 | } _ZN5doris19variant_json_detail17write_json_stringINS_14BufferWritableEEEvRT_NS_9StringRefEPKc Line | Count | Source | 194 | 26 | void write_json_string(Writer& out, StringRef value, const char* description) { | 195 | 26 | require_valid_json_utf8(value, description); | 196 | 26 | write_escaped_json_string(out, value); | 197 | 26 | } |
_ZN5doris19variant_json_detail17write_json_stringINS_35data_type_variant_v2_serde_internal14CountingWriterEEEvRT_NS_9StringRefEPKc Line | Count | Source | 194 | 51 | void write_json_string(Writer& out, StringRef value, const char* description) { | 195 | 51 | require_valid_json_utf8(value, description); | 196 | 51 | write_escaped_json_string(out, value); | 197 | 51 | } |
_ZN5doris19variant_json_detail17write_json_stringINS_35data_type_variant_v2_serde_internal11FixedWriterEEEvRT_NS_9StringRefEPKc Line | Count | Source | 194 | 26 | void write_json_string(Writer& out, StringRef value, const char* description) { | 195 | 26 | require_valid_json_utf8(value, description); | 196 | 26 | write_escaped_json_string(out, value); | 197 | 26 | } |
|
198 | | |
199 | | template <typename Writer> |
200 | 1 | void write_json_binary(Writer& out, StringRef value) { |
201 | 1 | static constexpr char BASE64[] = |
202 | 1 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
203 | 1 | write_literal(out, "\""); |
204 | 1 | std::array<char, 1024> encoded {}; |
205 | 1 | size_t encoded_size = 0; |
206 | 1 | size_t index = 0; |
207 | 1 | const auto flush = [&]() { |
208 | 1 | if (encoded_size != 0) { |
209 | 1 | out.write(encoded.data(), encoded_size); |
210 | 1 | encoded_size = 0; |
211 | 1 | } |
212 | 1 | }; _ZZN5doris19variant_json_detail17write_json_binaryINS_14BufferWritableEEEvRT_NS_9StringRefEENKUlvE_clEv Line | Count | Source | 207 | 1 | const auto flush = [&]() { | 208 | 1 | if (encoded_size != 0) { | 209 | 1 | out.write(encoded.data(), encoded_size); | 210 | 1 | encoded_size = 0; | 211 | 1 | } | 212 | 1 | }; |
Unexecuted instantiation: _ZZN5doris19variant_json_detail17write_json_binaryINS_35data_type_variant_v2_serde_internal14CountingWriterEEEvRT_NS_9StringRefEENKUlvE_clEv Unexecuted instantiation: _ZZN5doris19variant_json_detail17write_json_binaryINS_35data_type_variant_v2_serde_internal11FixedWriterEEEvRT_NS_9StringRefEENKUlvE_clEv |
213 | 1 | while (index + 3 <= value.size) { |
214 | 0 | if (encoded.size() - encoded_size < 4) { |
215 | 0 | flush(); |
216 | 0 | } |
217 | 0 | const auto first = static_cast<uint8_t>(value.data[index]); |
218 | 0 | const auto second = static_cast<uint8_t>(value.data[index + 1]); |
219 | 0 | const auto third = static_cast<uint8_t>(value.data[index + 2]); |
220 | 0 | encoded[encoded_size++] = BASE64[first >> 2]; |
221 | 0 | encoded[encoded_size++] = BASE64[((first & 0x03) << 4) | (second >> 4)]; |
222 | 0 | encoded[encoded_size++] = BASE64[((second & 0x0F) << 2) | (third >> 6)]; |
223 | 0 | encoded[encoded_size++] = BASE64[third & 0x3F]; |
224 | 0 | index += 3; |
225 | 0 | } |
226 | 1 | if (index != value.size) { |
227 | 1 | if (encoded.size() - encoded_size < 4) { |
228 | 0 | flush(); |
229 | 0 | } |
230 | 1 | const auto first = static_cast<uint8_t>(value.data[index]); |
231 | 1 | encoded[encoded_size++] = BASE64[first >> 2]; |
232 | 1 | if (index + 1 == value.size) { |
233 | 0 | encoded[encoded_size++] = BASE64[(first & 0x03) << 4]; |
234 | 0 | encoded[encoded_size++] = '='; |
235 | 0 | encoded[encoded_size++] = '='; |
236 | 1 | } else { |
237 | 1 | const auto second = static_cast<uint8_t>(value.data[index + 1]); |
238 | 1 | encoded[encoded_size++] = BASE64[((first & 0x03) << 4) | (second >> 4)]; |
239 | 1 | encoded[encoded_size++] = BASE64[(second & 0x0F) << 2]; |
240 | 1 | encoded[encoded_size++] = '='; |
241 | 1 | } |
242 | 1 | } |
243 | 1 | flush(); |
244 | 1 | write_literal(out, "\""); |
245 | 1 | } _ZN5doris19variant_json_detail17write_json_binaryINS_14BufferWritableEEEvRT_NS_9StringRefE Line | Count | Source | 200 | 1 | void write_json_binary(Writer& out, StringRef value) { | 201 | 1 | static constexpr char BASE64[] = | 202 | 1 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 203 | 1 | write_literal(out, "\""); | 204 | 1 | std::array<char, 1024> encoded {}; | 205 | 1 | size_t encoded_size = 0; | 206 | 1 | size_t index = 0; | 207 | 1 | const auto flush = [&]() { | 208 | 1 | if (encoded_size != 0) { | 209 | 1 | out.write(encoded.data(), encoded_size); | 210 | 1 | encoded_size = 0; | 211 | 1 | } | 212 | 1 | }; | 213 | 1 | while (index + 3 <= value.size) { | 214 | 0 | if (encoded.size() - encoded_size < 4) { | 215 | 0 | flush(); | 216 | 0 | } | 217 | 0 | const auto first = static_cast<uint8_t>(value.data[index]); | 218 | 0 | const auto second = static_cast<uint8_t>(value.data[index + 1]); | 219 | 0 | const auto third = static_cast<uint8_t>(value.data[index + 2]); | 220 | 0 | encoded[encoded_size++] = BASE64[first >> 2]; | 221 | 0 | encoded[encoded_size++] = BASE64[((first & 0x03) << 4) | (second >> 4)]; | 222 | 0 | encoded[encoded_size++] = BASE64[((second & 0x0F) << 2) | (third >> 6)]; | 223 | 0 | encoded[encoded_size++] = BASE64[third & 0x3F]; | 224 | 0 | index += 3; | 225 | 0 | } | 226 | 1 | if (index != value.size) { | 227 | 1 | if (encoded.size() - encoded_size < 4) { | 228 | 0 | flush(); | 229 | 0 | } | 230 | 1 | const auto first = static_cast<uint8_t>(value.data[index]); | 231 | 1 | encoded[encoded_size++] = BASE64[first >> 2]; | 232 | 1 | if (index + 1 == value.size) { | 233 | 0 | encoded[encoded_size++] = BASE64[(first & 0x03) << 4]; | 234 | 0 | encoded[encoded_size++] = '='; | 235 | 0 | encoded[encoded_size++] = '='; | 236 | 1 | } else { | 237 | 1 | const auto second = static_cast<uint8_t>(value.data[index + 1]); | 238 | 1 | encoded[encoded_size++] = BASE64[((first & 0x03) << 4) | (second >> 4)]; | 239 | 1 | encoded[encoded_size++] = BASE64[(second & 0x0F) << 2]; | 240 | 1 | encoded[encoded_size++] = '='; | 241 | 1 | } | 242 | 1 | } | 243 | 1 | flush(); | 244 | 1 | write_literal(out, "\""); | 245 | 1 | } |
Unexecuted instantiation: _ZN5doris19variant_json_detail17write_json_binaryINS_35data_type_variant_v2_serde_internal14CountingWriterEEEvRT_NS_9StringRefE Unexecuted instantiation: _ZN5doris19variant_json_detail17write_json_binaryINS_35data_type_variant_v2_serde_internal11FixedWriterEEEvRT_NS_9StringRefE |
246 | | |
247 | | template <typename Writer> |
248 | | class Printer { |
249 | | public: |
250 | 390 | Printer(Writer& out, const VariantJsonFormatOptions& options) : _out(out), _options(options) {}_ZN5doris19variant_json_detail7PrinterINS_14BufferWritableEEC2ERS2_RKNS_24VariantJsonFormatOptionsE Line | Count | Source | 250 | 99 | Printer(Writer& out, const VariantJsonFormatOptions& options) : _out(out), _options(options) {} |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal14CountingWriterEEC2ERS3_RKNS_24VariantJsonFormatOptionsE Line | Count | Source | 250 | 193 | Printer(Writer& out, const VariantJsonFormatOptions& options) : _out(out), _options(options) {} |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal11FixedWriterEEC2ERS3_RKNS_24VariantJsonFormatOptionsE Line | Count | Source | 250 | 98 | Printer(Writer& out, const VariantJsonFormatOptions& options) : _out(out), _options(options) {} |
|
251 | | |
252 | 462 | void write(VariantValueRef value, uint32_t depth) { |
253 | 462 | require_json_depth(depth); |
254 | 462 | switch (value.basic_type()) { |
255 | 103 | case VariantBasicType::SHORT_STRING: |
256 | 103 | write_json_string(_out, value.get_string(), "string"); |
257 | 103 | return; |
258 | 301 | case VariantBasicType::PRIMITIVE: |
259 | 301 | write_primitive(value); |
260 | 301 | return; |
261 | 27 | case VariantBasicType::OBJECT: |
262 | 27 | write_object(value, depth); |
263 | 27 | return; |
264 | 31 | case VariantBasicType::ARRAY: |
265 | 31 | write_array(value, depth); |
266 | 31 | return; |
267 | 462 | } |
268 | 462 | } _ZN5doris19variant_json_detail7PrinterINS_14BufferWritableEE5writeENS_15VariantValueRefEj Line | Count | Source | 252 | 126 | void write(VariantValueRef value, uint32_t depth) { | 253 | 126 | require_json_depth(depth); | 254 | 126 | switch (value.basic_type()) { | 255 | 26 | case VariantBasicType::SHORT_STRING: | 256 | 26 | write_json_string(_out, value.get_string(), "string"); | 257 | 26 | return; | 258 | 78 | case VariantBasicType::PRIMITIVE: | 259 | 78 | write_primitive(value); | 260 | 78 | return; | 261 | 12 | case VariantBasicType::OBJECT: | 262 | 12 | write_object(value, depth); | 263 | 12 | return; | 264 | 10 | case VariantBasicType::ARRAY: | 265 | 10 | write_array(value, depth); | 266 | 10 | return; | 267 | 126 | } | 268 | 126 | } |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal14CountingWriterEE5writeENS_15VariantValueRefEj Line | Count | Source | 252 | 226 | void write(VariantValueRef value, uint32_t depth) { | 253 | 226 | require_json_depth(depth); | 254 | 226 | switch (value.basic_type()) { | 255 | 51 | case VariantBasicType::SHORT_STRING: | 256 | 51 | write_json_string(_out, value.get_string(), "string"); | 257 | 51 | return; | 258 | 148 | case VariantBasicType::PRIMITIVE: | 259 | 148 | write_primitive(value); | 260 | 148 | return; | 261 | 12 | case VariantBasicType::OBJECT: | 262 | 12 | write_object(value, depth); | 263 | 12 | return; | 264 | 15 | case VariantBasicType::ARRAY: | 265 | 15 | write_array(value, depth); | 266 | 15 | return; | 267 | 226 | } | 268 | 226 | } |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal11FixedWriterEE5writeENS_15VariantValueRefEj Line | Count | Source | 252 | 110 | void write(VariantValueRef value, uint32_t depth) { | 253 | 110 | require_json_depth(depth); | 254 | 110 | switch (value.basic_type()) { | 255 | 26 | case VariantBasicType::SHORT_STRING: | 256 | 26 | write_json_string(_out, value.get_string(), "string"); | 257 | 26 | return; | 258 | 75 | case VariantBasicType::PRIMITIVE: | 259 | 75 | write_primitive(value); | 260 | 75 | return; | 261 | 3 | case VariantBasicType::OBJECT: | 262 | 3 | write_object(value, depth); | 263 | 3 | return; | 264 | 6 | case VariantBasicType::ARRAY: | 265 | 6 | write_array(value, depth); | 266 | 6 | return; | 267 | 110 | } | 268 | 110 | } |
|
269 | | |
270 | | private: |
271 | 301 | void write_primitive(VariantValueRef value) { |
272 | 301 | const VariantPrimitiveId id = value.primitive_id(); |
273 | 301 | switch (id) { |
274 | 64 | case VariantPrimitiveId::NULL_VALUE: |
275 | 64 | write_literal(_out, "null"); |
276 | 64 | return; |
277 | 1 | case VariantPrimitiveId::TRUE_VALUE: |
278 | 1 | write_literal(_out, "true"); |
279 | 1 | return; |
280 | 0 | case VariantPrimitiveId::FALSE_VALUE: |
281 | 0 | write_literal(_out, "false"); |
282 | 0 | return; |
283 | 33 | case VariantPrimitiveId::INT8: |
284 | 33 | case VariantPrimitiveId::INT16: |
285 | 33 | case VariantPrimitiveId::INT32: |
286 | 33 | case VariantPrimitiveId::INT64: |
287 | 33 | write_scalar(_out, format_json_int(value.get_int())); |
288 | 33 | return; |
289 | 140 | case VariantPrimitiveId::DOUBLE: { |
290 | 140 | const double number = value.get_double(); |
291 | 140 | if (!std::isfinite(number)) { |
292 | 84 | write_non_finite(number); |
293 | 84 | return; |
294 | 84 | } |
295 | 56 | write_scalar(_out, format_json_double(number)); |
296 | 56 | return; |
297 | 140 | } |
298 | 0 | case VariantPrimitiveId::DECIMAL4: |
299 | 0 | case VariantPrimitiveId::DECIMAL8: |
300 | 0 | case VariantPrimitiveId::DECIMAL16: |
301 | 0 | write_scalar(_out, format_json_decimal(value.get_decimal())); |
302 | 0 | return; |
303 | 32 | case VariantPrimitiveId::DATE: |
304 | 32 | write_quoted_scalar(_out, format_json_date(value.get_date())); |
305 | 32 | return; |
306 | 0 | case VariantPrimitiveId::TIMESTAMP_MICROS: |
307 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_micros(), 6, true, |
308 | 0 | _options.timezone)); |
309 | 0 | return; |
310 | 28 | case VariantPrimitiveId::TIMESTAMP_NTZ_MICROS: |
311 | 28 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_ntz_micros(), 6, |
312 | 28 | false, nullptr)); |
313 | 28 | return; |
314 | 0 | case VariantPrimitiveId::FLOAT: { |
315 | 0 | const float number = value.get_float(); |
316 | 0 | if (!std::isfinite(number)) { |
317 | 0 | write_non_finite(number); |
318 | 0 | return; |
319 | 0 | } |
320 | 0 | write_scalar(_out, format_json_float(number)); |
321 | 0 | return; |
322 | 0 | } |
323 | 1 | case VariantPrimitiveId::BINARY: |
324 | 1 | write_json_binary(_out, value.get_binary()); |
325 | 1 | return; |
326 | 0 | case VariantPrimitiveId::STRING: |
327 | 0 | write_json_string(_out, value.get_string(), "string"); |
328 | 0 | return; |
329 | 1 | case VariantPrimitiveId::TIME_NTZ_MICROS: |
330 | 1 | write_quoted_scalar(_out, format_json_time_micros(value.get_time_ntz_micros())); |
331 | 1 | return; |
332 | 0 | case VariantPrimitiveId::TIMESTAMP_NANOS: |
333 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_nanos(), 9, true, |
334 | 0 | _options.timezone)); |
335 | 0 | return; |
336 | 0 | case VariantPrimitiveId::TIMESTAMP_NTZ_NANOS: |
337 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_ntz_nanos(), 9, |
338 | 0 | false, nullptr)); |
339 | 0 | return; |
340 | 1 | case VariantPrimitiveId::UUID: |
341 | 1 | write_quoted_scalar(_out, format_json_uuid(value.get_uuid())); |
342 | 1 | return; |
343 | 301 | } |
344 | 0 | throw_unsupported_json_primitive(id); |
345 | 0 | } _ZN5doris19variant_json_detail7PrinterINS_14BufferWritableEE15write_primitiveENS_15VariantValueRefE Line | Count | Source | 271 | 78 | void write_primitive(VariantValueRef value) { | 272 | 78 | const VariantPrimitiveId id = value.primitive_id(); | 273 | 78 | switch (id) { | 274 | 17 | case VariantPrimitiveId::NULL_VALUE: | 275 | 17 | write_literal(_out, "null"); | 276 | 17 | return; | 277 | 1 | case VariantPrimitiveId::TRUE_VALUE: | 278 | 1 | write_literal(_out, "true"); | 279 | 1 | return; | 280 | 0 | case VariantPrimitiveId::FALSE_VALUE: | 281 | 0 | write_literal(_out, "false"); | 282 | 0 | return; | 283 | 15 | case VariantPrimitiveId::INT8: | 284 | 15 | case VariantPrimitiveId::INT16: | 285 | 15 | case VariantPrimitiveId::INT32: | 286 | 15 | case VariantPrimitiveId::INT64: | 287 | 15 | write_scalar(_out, format_json_int(value.get_int())); | 288 | 15 | return; | 289 | 30 | case VariantPrimitiveId::DOUBLE: { | 290 | 30 | const double number = value.get_double(); | 291 | 30 | if (!std::isfinite(number)) { | 292 | 18 | write_non_finite(number); | 293 | 18 | return; | 294 | 18 | } | 295 | 12 | write_scalar(_out, format_json_double(number)); | 296 | 12 | return; | 297 | 30 | } | 298 | 0 | case VariantPrimitiveId::DECIMAL4: | 299 | 0 | case VariantPrimitiveId::DECIMAL8: | 300 | 0 | case VariantPrimitiveId::DECIMAL16: | 301 | 0 | write_scalar(_out, format_json_decimal(value.get_decimal())); | 302 | 0 | return; | 303 | 6 | case VariantPrimitiveId::DATE: | 304 | 6 | write_quoted_scalar(_out, format_json_date(value.get_date())); | 305 | 6 | return; | 306 | 0 | case VariantPrimitiveId::TIMESTAMP_MICROS: | 307 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_micros(), 6, true, | 308 | 0 | _options.timezone)); | 309 | 0 | return; | 310 | 6 | case VariantPrimitiveId::TIMESTAMP_NTZ_MICROS: | 311 | 6 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_ntz_micros(), 6, | 312 | 6 | false, nullptr)); | 313 | 6 | return; | 314 | 0 | case VariantPrimitiveId::FLOAT: { | 315 | 0 | const float number = value.get_float(); | 316 | 0 | if (!std::isfinite(number)) { | 317 | 0 | write_non_finite(number); | 318 | 0 | return; | 319 | 0 | } | 320 | 0 | write_scalar(_out, format_json_float(number)); | 321 | 0 | return; | 322 | 0 | } | 323 | 1 | case VariantPrimitiveId::BINARY: | 324 | 1 | write_json_binary(_out, value.get_binary()); | 325 | 1 | return; | 326 | 0 | case VariantPrimitiveId::STRING: | 327 | 0 | write_json_string(_out, value.get_string(), "string"); | 328 | 0 | return; | 329 | 1 | case VariantPrimitiveId::TIME_NTZ_MICROS: | 330 | 1 | write_quoted_scalar(_out, format_json_time_micros(value.get_time_ntz_micros())); | 331 | 1 | return; | 332 | 0 | case VariantPrimitiveId::TIMESTAMP_NANOS: | 333 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_nanos(), 9, true, | 334 | 0 | _options.timezone)); | 335 | 0 | return; | 336 | 0 | case VariantPrimitiveId::TIMESTAMP_NTZ_NANOS: | 337 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_ntz_nanos(), 9, | 338 | 0 | false, nullptr)); | 339 | 0 | return; | 340 | 1 | case VariantPrimitiveId::UUID: | 341 | 1 | write_quoted_scalar(_out, format_json_uuid(value.get_uuid())); | 342 | 1 | return; | 343 | 78 | } | 344 | 0 | throw_unsupported_json_primitive(id); | 345 | 0 | } |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal14CountingWriterEE15write_primitiveENS_15VariantValueRefE Line | Count | Source | 271 | 148 | void write_primitive(VariantValueRef value) { | 272 | 148 | const VariantPrimitiveId id = value.primitive_id(); | 273 | 148 | switch (id) { | 274 | 33 | case VariantPrimitiveId::NULL_VALUE: | 275 | 33 | write_literal(_out, "null"); | 276 | 33 | return; | 277 | 0 | case VariantPrimitiveId::TRUE_VALUE: | 278 | 0 | write_literal(_out, "true"); | 279 | 0 | return; | 280 | 0 | case VariantPrimitiveId::FALSE_VALUE: | 281 | 0 | write_literal(_out, "false"); | 282 | 0 | return; | 283 | 15 | case VariantPrimitiveId::INT8: | 284 | 15 | case VariantPrimitiveId::INT16: | 285 | 15 | case VariantPrimitiveId::INT32: | 286 | 15 | case VariantPrimitiveId::INT64: | 287 | 15 | write_scalar(_out, format_json_int(value.get_int())); | 288 | 15 | return; | 289 | 70 | case VariantPrimitiveId::DOUBLE: { | 290 | 70 | const double number = value.get_double(); | 291 | 70 | if (!std::isfinite(number)) { | 292 | 42 | write_non_finite(number); | 293 | 42 | return; | 294 | 42 | } | 295 | 28 | write_scalar(_out, format_json_double(number)); | 296 | 28 | return; | 297 | 70 | } | 298 | 0 | case VariantPrimitiveId::DECIMAL4: | 299 | 0 | case VariantPrimitiveId::DECIMAL8: | 300 | 0 | case VariantPrimitiveId::DECIMAL16: | 301 | 0 | write_scalar(_out, format_json_decimal(value.get_decimal())); | 302 | 0 | return; | 303 | 16 | case VariantPrimitiveId::DATE: | 304 | 16 | write_quoted_scalar(_out, format_json_date(value.get_date())); | 305 | 16 | return; | 306 | 0 | case VariantPrimitiveId::TIMESTAMP_MICROS: | 307 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_micros(), 6, true, | 308 | 0 | _options.timezone)); | 309 | 0 | return; | 310 | 14 | case VariantPrimitiveId::TIMESTAMP_NTZ_MICROS: | 311 | 14 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_ntz_micros(), 6, | 312 | 14 | false, nullptr)); | 313 | 14 | return; | 314 | 0 | case VariantPrimitiveId::FLOAT: { | 315 | 0 | const float number = value.get_float(); | 316 | 0 | if (!std::isfinite(number)) { | 317 | 0 | write_non_finite(number); | 318 | 0 | return; | 319 | 0 | } | 320 | 0 | write_scalar(_out, format_json_float(number)); | 321 | 0 | return; | 322 | 0 | } | 323 | 0 | case VariantPrimitiveId::BINARY: | 324 | 0 | write_json_binary(_out, value.get_binary()); | 325 | 0 | return; | 326 | 0 | case VariantPrimitiveId::STRING: | 327 | 0 | write_json_string(_out, value.get_string(), "string"); | 328 | 0 | return; | 329 | 0 | case VariantPrimitiveId::TIME_NTZ_MICROS: | 330 | 0 | write_quoted_scalar(_out, format_json_time_micros(value.get_time_ntz_micros())); | 331 | 0 | return; | 332 | 0 | case VariantPrimitiveId::TIMESTAMP_NANOS: | 333 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_nanos(), 9, true, | 334 | 0 | _options.timezone)); | 335 | 0 | return; | 336 | 0 | case VariantPrimitiveId::TIMESTAMP_NTZ_NANOS: | 337 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_ntz_nanos(), 9, | 338 | 0 | false, nullptr)); | 339 | 0 | return; | 340 | 0 | case VariantPrimitiveId::UUID: | 341 | 0 | write_quoted_scalar(_out, format_json_uuid(value.get_uuid())); | 342 | 0 | return; | 343 | 148 | } | 344 | 0 | throw_unsupported_json_primitive(id); | 345 | 0 | } |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal11FixedWriterEE15write_primitiveENS_15VariantValueRefE Line | Count | Source | 271 | 75 | void write_primitive(VariantValueRef value) { | 272 | 75 | const VariantPrimitiveId id = value.primitive_id(); | 273 | 75 | switch (id) { | 274 | 14 | case VariantPrimitiveId::NULL_VALUE: | 275 | 14 | write_literal(_out, "null"); | 276 | 14 | return; | 277 | 0 | case VariantPrimitiveId::TRUE_VALUE: | 278 | 0 | write_literal(_out, "true"); | 279 | 0 | return; | 280 | 0 | case VariantPrimitiveId::FALSE_VALUE: | 281 | 0 | write_literal(_out, "false"); | 282 | 0 | return; | 283 | 3 | case VariantPrimitiveId::INT8: | 284 | 3 | case VariantPrimitiveId::INT16: | 285 | 3 | case VariantPrimitiveId::INT32: | 286 | 3 | case VariantPrimitiveId::INT64: | 287 | 3 | write_scalar(_out, format_json_int(value.get_int())); | 288 | 3 | return; | 289 | 40 | case VariantPrimitiveId::DOUBLE: { | 290 | 40 | const double number = value.get_double(); | 291 | 40 | if (!std::isfinite(number)) { | 292 | 24 | write_non_finite(number); | 293 | 24 | return; | 294 | 24 | } | 295 | 16 | write_scalar(_out, format_json_double(number)); | 296 | 16 | return; | 297 | 40 | } | 298 | 0 | case VariantPrimitiveId::DECIMAL4: | 299 | 0 | case VariantPrimitiveId::DECIMAL8: | 300 | 0 | case VariantPrimitiveId::DECIMAL16: | 301 | 0 | write_scalar(_out, format_json_decimal(value.get_decimal())); | 302 | 0 | return; | 303 | 10 | case VariantPrimitiveId::DATE: | 304 | 10 | write_quoted_scalar(_out, format_json_date(value.get_date())); | 305 | 10 | return; | 306 | 0 | case VariantPrimitiveId::TIMESTAMP_MICROS: | 307 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_micros(), 6, true, | 308 | 0 | _options.timezone)); | 309 | 0 | return; | 310 | 8 | case VariantPrimitiveId::TIMESTAMP_NTZ_MICROS: | 311 | 8 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_ntz_micros(), 6, | 312 | 8 | false, nullptr)); | 313 | 8 | return; | 314 | 0 | case VariantPrimitiveId::FLOAT: { | 315 | 0 | const float number = value.get_float(); | 316 | 0 | if (!std::isfinite(number)) { | 317 | 0 | write_non_finite(number); | 318 | 0 | return; | 319 | 0 | } | 320 | 0 | write_scalar(_out, format_json_float(number)); | 321 | 0 | return; | 322 | 0 | } | 323 | 0 | case VariantPrimitiveId::BINARY: | 324 | 0 | write_json_binary(_out, value.get_binary()); | 325 | 0 | return; | 326 | 0 | case VariantPrimitiveId::STRING: | 327 | 0 | write_json_string(_out, value.get_string(), "string"); | 328 | 0 | return; | 329 | 0 | case VariantPrimitiveId::TIME_NTZ_MICROS: | 330 | 0 | write_quoted_scalar(_out, format_json_time_micros(value.get_time_ntz_micros())); | 331 | 0 | return; | 332 | 0 | case VariantPrimitiveId::TIMESTAMP_NANOS: | 333 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_nanos(), 9, true, | 334 | 0 | _options.timezone)); | 335 | 0 | return; | 336 | 0 | case VariantPrimitiveId::TIMESTAMP_NTZ_NANOS: | 337 | 0 | write_quoted_scalar(_out, format_json_timestamp(value.get_timestamp_ntz_nanos(), 9, | 338 | 0 | false, nullptr)); | 339 | 0 | return; | 340 | 0 | case VariantPrimitiveId::UUID: | 341 | 0 | write_quoted_scalar(_out, format_json_uuid(value.get_uuid())); | 342 | 0 | return; | 343 | 75 | } | 344 | 0 | throw_unsupported_json_primitive(id); | 345 | 0 | } |
|
346 | | |
347 | | template <typename Number> |
348 | 84 | void write_non_finite(Number value) { |
349 | 84 | if (std::isnan(value)) { |
350 | 28 | write_literal(_out, "\"NaN\""); |
351 | 56 | } else if (value > 0) { |
352 | 28 | write_literal(_out, "\"Infinity\""); |
353 | 28 | } else { |
354 | 28 | write_literal(_out, "\"-Infinity\""); |
355 | 28 | } |
356 | 84 | } _ZN5doris19variant_json_detail7PrinterINS_14BufferWritableEE16write_non_finiteIdEEvT_ Line | Count | Source | 348 | 18 | void write_non_finite(Number value) { | 349 | 18 | if (std::isnan(value)) { | 350 | 6 | write_literal(_out, "\"NaN\""); | 351 | 12 | } else if (value > 0) { | 352 | 6 | write_literal(_out, "\"Infinity\""); | 353 | 6 | } else { | 354 | 6 | write_literal(_out, "\"-Infinity\""); | 355 | 6 | } | 356 | 18 | } |
Unexecuted instantiation: _ZN5doris19variant_json_detail7PrinterINS_14BufferWritableEE16write_non_finiteIfEEvT_ _ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal14CountingWriterEE16write_non_finiteIdEEvT_ Line | Count | Source | 348 | 42 | void write_non_finite(Number value) { | 349 | 42 | if (std::isnan(value)) { | 350 | 14 | write_literal(_out, "\"NaN\""); | 351 | 28 | } else if (value > 0) { | 352 | 14 | write_literal(_out, "\"Infinity\""); | 353 | 14 | } else { | 354 | 14 | write_literal(_out, "\"-Infinity\""); | 355 | 14 | } | 356 | 42 | } |
Unexecuted instantiation: _ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal14CountingWriterEE16write_non_finiteIfEEvT_ _ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal11FixedWriterEE16write_non_finiteIdEEvT_ Line | Count | Source | 348 | 24 | void write_non_finite(Number value) { | 349 | 24 | if (std::isnan(value)) { | 350 | 8 | write_literal(_out, "\"NaN\""); | 351 | 16 | } else if (value > 0) { | 352 | 8 | write_literal(_out, "\"Infinity\""); | 353 | 8 | } else { | 354 | 8 | write_literal(_out, "\"-Infinity\""); | 355 | 8 | } | 356 | 24 | } |
Unexecuted instantiation: _ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal11FixedWriterEE16write_non_finiteIfEEvT_ |
357 | | |
358 | 27 | void write_object(VariantValueRef value, uint32_t depth) { |
359 | 27 | write_literal(_out, "{"); |
360 | 27 | const uint32_t count = value.num_elements(); |
361 | 27 | StringRef previous_key; |
362 | 51 | for (uint32_t index = 0; index < count; ++index) { |
363 | 24 | if (index != 0) { |
364 | 1 | write_literal(_out, ","); |
365 | 1 | } |
366 | 24 | uint32_t field_id = 0; |
367 | 24 | VariantValueRef child = value.object_value_at(index, &field_id); |
368 | 24 | const StringRef key = value.metadata.key_at(field_id); |
369 | 24 | require_json_object_key(key, previous_key, index); |
370 | 24 | write_escaped_json_string(_out, key); |
371 | 24 | write_literal(_out, ":"); |
372 | 24 | write(child, depth + 1); |
373 | 24 | previous_key = key; |
374 | 24 | } |
375 | 27 | write_literal(_out, "}"); |
376 | 27 | } _ZN5doris19variant_json_detail7PrinterINS_14BufferWritableEE12write_objectENS_15VariantValueRefEj Line | Count | Source | 358 | 12 | void write_object(VariantValueRef value, uint32_t depth) { | 359 | 12 | write_literal(_out, "{"); | 360 | 12 | const uint32_t count = value.num_elements(); | 361 | 12 | StringRef previous_key; | 362 | 23 | for (uint32_t index = 0; index < count; ++index) { | 363 | 11 | if (index != 0) { | 364 | 1 | write_literal(_out, ","); | 365 | 1 | } | 366 | 11 | uint32_t field_id = 0; | 367 | 11 | VariantValueRef child = value.object_value_at(index, &field_id); | 368 | 11 | const StringRef key = value.metadata.key_at(field_id); | 369 | 11 | require_json_object_key(key, previous_key, index); | 370 | 11 | write_escaped_json_string(_out, key); | 371 | 11 | write_literal(_out, ":"); | 372 | 11 | write(child, depth + 1); | 373 | 11 | previous_key = key; | 374 | 11 | } | 375 | 12 | write_literal(_out, "}"); | 376 | 12 | } |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal14CountingWriterEE12write_objectENS_15VariantValueRefEj Line | Count | Source | 358 | 12 | void write_object(VariantValueRef value, uint32_t depth) { | 359 | 12 | write_literal(_out, "{"); | 360 | 12 | const uint32_t count = value.num_elements(); | 361 | 12 | StringRef previous_key; | 362 | 22 | for (uint32_t index = 0; index < count; ++index) { | 363 | 10 | if (index != 0) { | 364 | 0 | write_literal(_out, ","); | 365 | 0 | } | 366 | 10 | uint32_t field_id = 0; | 367 | 10 | VariantValueRef child = value.object_value_at(index, &field_id); | 368 | 10 | const StringRef key = value.metadata.key_at(field_id); | 369 | 10 | require_json_object_key(key, previous_key, index); | 370 | 10 | write_escaped_json_string(_out, key); | 371 | 10 | write_literal(_out, ":"); | 372 | 10 | write(child, depth + 1); | 373 | 10 | previous_key = key; | 374 | 10 | } | 375 | 12 | write_literal(_out, "}"); | 376 | 12 | } |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal11FixedWriterEE12write_objectENS_15VariantValueRefEj Line | Count | Source | 358 | 3 | void write_object(VariantValueRef value, uint32_t depth) { | 359 | 3 | write_literal(_out, "{"); | 360 | 3 | const uint32_t count = value.num_elements(); | 361 | 3 | StringRef previous_key; | 362 | 6 | for (uint32_t index = 0; index < count; ++index) { | 363 | 3 | if (index != 0) { | 364 | 0 | write_literal(_out, ","); | 365 | 0 | } | 366 | 3 | uint32_t field_id = 0; | 367 | 3 | VariantValueRef child = value.object_value_at(index, &field_id); | 368 | 3 | const StringRef key = value.metadata.key_at(field_id); | 369 | 3 | require_json_object_key(key, previous_key, index); | 370 | 3 | write_escaped_json_string(_out, key); | 371 | 3 | write_literal(_out, ":"); | 372 | 3 | write(child, depth + 1); | 373 | 3 | previous_key = key; | 374 | 3 | } | 375 | 3 | write_literal(_out, "}"); | 376 | 3 | } |
|
377 | | |
378 | 31 | void write_array(VariantValueRef value, uint32_t depth) { |
379 | 31 | write_literal(_out, "["); |
380 | 31 | const uint32_t count = value.num_elements(); |
381 | 79 | for (uint32_t index = 0; index < count; ++index) { |
382 | 48 | if (index != 0) { |
383 | 31 | write_literal(_out, ","); |
384 | 31 | } |
385 | 48 | write(value.array_at(index), depth + 1); |
386 | 48 | } |
387 | 31 | write_literal(_out, "]"); |
388 | 31 | } _ZN5doris19variant_json_detail7PrinterINS_14BufferWritableEE11write_arrayENS_15VariantValueRefEj Line | Count | Source | 378 | 10 | void write_array(VariantValueRef value, uint32_t depth) { | 379 | 10 | write_literal(_out, "["); | 380 | 10 | const uint32_t count = value.num_elements(); | 381 | 26 | for (uint32_t index = 0; index < count; ++index) { | 382 | 16 | if (index != 0) { | 383 | 10 | write_literal(_out, ","); | 384 | 10 | } | 385 | 16 | write(value.array_at(index), depth + 1); | 386 | 16 | } | 387 | 10 | write_literal(_out, "]"); | 388 | 10 | } |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal14CountingWriterEE11write_arrayENS_15VariantValueRefEj Line | Count | Source | 378 | 15 | void write_array(VariantValueRef value, uint32_t depth) { | 379 | 15 | write_literal(_out, "["); | 380 | 15 | const uint32_t count = value.num_elements(); | 381 | 38 | for (uint32_t index = 0; index < count; ++index) { | 382 | 23 | if (index != 0) { | 383 | 15 | write_literal(_out, ","); | 384 | 15 | } | 385 | 23 | write(value.array_at(index), depth + 1); | 386 | 23 | } | 387 | 15 | write_literal(_out, "]"); | 388 | 15 | } |
_ZN5doris19variant_json_detail7PrinterINS_35data_type_variant_v2_serde_internal11FixedWriterEE11write_arrayENS_15VariantValueRefEj Line | Count | Source | 378 | 6 | void write_array(VariantValueRef value, uint32_t depth) { | 379 | 6 | write_literal(_out, "["); | 380 | 6 | const uint32_t count = value.num_elements(); | 381 | 15 | for (uint32_t index = 0; index < count; ++index) { | 382 | 9 | if (index != 0) { | 383 | 6 | write_literal(_out, ","); | 384 | 6 | } | 385 | 9 | write(value.array_at(index), depth + 1); | 386 | 9 | } | 387 | 6 | write_literal(_out, "]"); | 388 | 6 | } |
|
389 | | |
390 | | Writer& _out; |
391 | | const VariantJsonFormatOptions& _options; |
392 | | }; |
393 | | |
394 | | } // namespace variant_json_detail |
395 | | |
396 | | // Writer is statically dispatched and only needs write(const char*, size_t). |
397 | | template <typename Writer> |
398 | | void to_json(VariantValueRef value, Writer& out, |
399 | 390 | const VariantJsonFormatOptions& options = VariantJsonFormatOptions {}) { |
400 | 390 | variant_json_detail::require_exact_json_value(value); |
401 | 390 | variant_json_detail::Printer<Writer>(out, options).write(value, 0); |
402 | 390 | } _ZN5doris7to_jsonINS_14BufferWritableEEEvNS_15VariantValueRefERT_RKNS_24VariantJsonFormatOptionsE Line | Count | Source | 399 | 99 | const VariantJsonFormatOptions& options = VariantJsonFormatOptions {}) { | 400 | 99 | variant_json_detail::require_exact_json_value(value); | 401 | 99 | variant_json_detail::Printer<Writer>(out, options).write(value, 0); | 402 | 99 | } |
_ZN5doris7to_jsonINS_35data_type_variant_v2_serde_internal14CountingWriterEEEvNS_15VariantValueRefERT_RKNS_24VariantJsonFormatOptionsE Line | Count | Source | 399 | 193 | const VariantJsonFormatOptions& options = VariantJsonFormatOptions {}) { | 400 | 193 | variant_json_detail::require_exact_json_value(value); | 401 | 193 | variant_json_detail::Printer<Writer>(out, options).write(value, 0); | 402 | 193 | } |
_ZN5doris7to_jsonINS_35data_type_variant_v2_serde_internal11FixedWriterEEEvNS_15VariantValueRefERT_RKNS_24VariantJsonFormatOptionsE Line | Count | Source | 399 | 98 | const VariantJsonFormatOptions& options = VariantJsonFormatOptions {}) { | 400 | 98 | variant_json_detail::require_exact_json_value(value); | 401 | 98 | variant_json_detail::Printer<Writer>(out, options).write(value, 0); | 402 | 98 | } |
|
403 | | |
404 | | } // namespace doris |