Skip to content

Commit 8ae88f2

Browse files
committed
Use JSONWriter in print_args implementation
1 parent 5af7055 commit 8ae88f2

File tree

8 files changed

+117
-99
lines changed

8 files changed

+117
-99
lines changed

Android.bp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2753,6 +2753,7 @@ cc_test {
27532753
":perfetto_src_trace_processor_util_gzip",
27542754
":perfetto_src_trace_processor_util_interned_message_view",
27552755
":perfetto_src_trace_processor_util_json_parser",
2756+
":perfetto_src_trace_processor_util_json_writer",
27562757
":perfetto_src_trace_processor_util_profile_builder",
27572758
":perfetto_src_trace_processor_util_profiler_util",
27582759
":perfetto_src_trace_processor_util_proto_profiler",
@@ -18369,6 +18370,7 @@ cc_library_static {
1836918370
":perfetto_src_trace_processor_util_gzip",
1837018371
":perfetto_src_trace_processor_util_interned_message_view",
1837118372
":perfetto_src_trace_processor_util_json_parser",
18373+
":perfetto_src_trace_processor_util_json_writer",
1837218374
":perfetto_src_trace_processor_util_profile_builder",
1837318375
":perfetto_src_trace_processor_util_profiler_util",
1837418376
":perfetto_src_trace_processor_util_proto_profiler",
@@ -18704,6 +18706,7 @@ cc_binary {
1870418706
":perfetto_src_trace_processor_util_gzip",
1870518707
":perfetto_src_trace_processor_util_interned_message_view",
1870618708
":perfetto_src_trace_processor_util_json_parser",
18709+
":perfetto_src_trace_processor_util_json_writer",
1870718710
":perfetto_src_trace_processor_util_profile_builder",
1870818711
":perfetto_src_trace_processor_util_profiler_util",
1870918712
":perfetto_src_trace_processor_util_proto_profiler",
@@ -19151,6 +19154,7 @@ cc_binary_host {
1915119154
":perfetto_src_trace_processor_util_gzip",
1915219155
":perfetto_src_trace_processor_util_interned_message_view",
1915319156
":perfetto_src_trace_processor_util_json_parser",
19157+
":perfetto_src_trace_processor_util_json_writer",
1915419158
":perfetto_src_trace_processor_util_profile_builder",
1915519159
":perfetto_src_trace_processor_util_profiler_util",
1915619160
":perfetto_src_trace_processor_util_proto_profiler",

BUILD

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ perfetto_cc_library(
416416
":src_trace_processor_util_gzip",
417417
":src_trace_processor_util_interned_message_view",
418418
":src_trace_processor_util_json_parser",
419+
":src_trace_processor_util_json_writer",
419420
":src_trace_processor_util_profile_builder",
420421
":src_trace_processor_util_profiler_util",
421422
":src_trace_processor_util_proto_profiler",
@@ -3760,6 +3761,15 @@ perfetto_filegroup(
37603761
],
37613762
)
37623763

3764+
# GN target: //src/trace_processor/util:json_writer
3765+
perfetto_filegroup(
3766+
name = "src_trace_processor_util_json_writer",
3767+
srcs = [
3768+
"src/trace_processor/util/json_writer.cc",
3769+
"src/trace_processor/util/json_writer.h",
3770+
],
3771+
)
3772+
37633773
# GN target: //src/trace_processor/util:profile_builder
37643774
perfetto_filegroup(
37653775
name = "src_trace_processor_util_profile_builder",
@@ -7552,6 +7562,7 @@ perfetto_cc_library(
75527562
":src_trace_processor_util_gzip",
75537563
":src_trace_processor_util_interned_message_view",
75547564
":src_trace_processor_util_json_parser",
7565+
":src_trace_processor_util_json_writer",
75557566
":src_trace_processor_util_profile_builder",
75567567
":src_trace_processor_util_profiler_util",
75577568
":src_trace_processor_util_proto_profiler",
@@ -7764,6 +7775,7 @@ perfetto_cc_binary(
77647775
":src_trace_processor_util_gzip",
77657776
":src_trace_processor_util_interned_message_view",
77667777
":src_trace_processor_util_json_parser",
7778+
":src_trace_processor_util_json_writer",
77677779
":src_trace_processor_util_profile_builder",
77687780
":src_trace_processor_util_profiler_util",
77697781
":src_trace_processor_util_proto_profiler",
@@ -7962,6 +7974,7 @@ perfetto_cc_binary(
79627974
":src_trace_processor_util_gzip",
79637975
":src_trace_processor_util_interned_message_view",
79647976
":src_trace_processor_util_json_parser",
7977+
":src_trace_processor_util_json_writer",
79657978
":src_trace_processor_util_profile_builder",
79667979
":src_trace_processor_util_profiler_util",
79677980
":src_trace_processor_util_proto_profiler",

src/trace_processor/perfetto_sql/intrinsics/functions/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ source_set("functions") {
8585
"../../../types",
8686
"../../../util:args_utils",
8787
"../../../util:glob",
88+
"../../../util:json_writer",
8889
"../../../util:profile_builder",
8990
"../../../util:regex",
9091
"../../../util:sql_argument",

src/trace_processor/perfetto_sql/intrinsics/functions/args.cc

Lines changed: 93 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -14,109 +14,104 @@
1414

1515
#include "src/trace_processor/perfetto_sql/intrinsics/functions/args.h"
1616

17-
#include "perfetto/ext/base/dynamic_string_writer.h"
17+
#include "perfetto/ext/base/string_utils.h"
1818
#include "src/trace_processor/sqlite/bindings/sqlite_result.h"
1919
#include "src/trace_processor/sqlite/bindings/sqlite_type.h"
2020
#include "src/trace_processor/util/args_utils.h"
21+
#include "src/trace_processor/util/json_writer.h"
2122

2223
namespace perfetto::trace_processor {
2324
namespace {
24-
// We care about the argument order, so we can't use jsoncpp here.
25-
void WriteAsJson(const ArgNode& node,
26-
const TraceStorage* storage,
27-
base::DynamicStringWriter& writer) {
28-
switch (node.GetType()) {
29-
case ArgNode::Type::kPrimitive: {
30-
Variadic v = node.GetPrimitiveValue();
31-
switch (v.type) {
32-
case Variadic::Type::kNull:
33-
writer.AppendLiteral("null");
34-
break;
35-
case Variadic::Type::kBool:
36-
writer.AppendString(v.bool_value ? "true" : "false");
37-
break;
38-
case Variadic::Type::kInt:
39-
writer.AppendInt(v.int_value);
40-
break;
41-
case Variadic::Type::kUint:
42-
writer.AppendUnsignedInt(v.uint_value);
43-
break;
44-
case Variadic::Type::kReal:
45-
if (std::isnan(v.real_value)) {
46-
writer.AppendLiteral("\"NaN\"");
47-
} else if (std::isinf(v.real_value) && v.real_value > 0) {
48-
writer.AppendLiteral("\"Infinity\"");
49-
} else if (std::isinf(v.real_value) && v.real_value < 0) {
50-
writer.AppendLiteral("\"-Infinity\"");
51-
} else {
52-
writer.AppendDouble(v.real_value);
53-
}
54-
break;
55-
case Variadic::Type::kString:
56-
writer.AppendChar('"');
57-
for (const char* p = storage->GetString(v.string_value).c_str(); *p;
58-
p++) {
59-
unsigned char c = static_cast<unsigned char>(*p);
60-
if (*p == '"') {
61-
writer.AppendLiteral("\\\"");
62-
} else if (*p == '\\') {
63-
writer.AppendLiteral("\\\\");
64-
} else if (*p == '\n') {
65-
writer.AppendLiteral("\\n");
66-
} else if (*p == '\r') {
67-
writer.AppendLiteral("\\r");
68-
} else if (*p == '\t') {
69-
writer.AppendLiteral("\\t");
70-
} else if (c < 0x20) {
71-
// Escape all control characters below 0x20 in \uXXXX format
72-
writer.AppendLiteral("\\u00");
73-
writer.AppendChar("0123456789abcdef"[c >> 4]);
74-
writer.AppendChar("0123456789abcdef"[c & 0xf]);
75-
} else {
76-
writer.AppendChar(*p);
77-
}
78-
}
79-
writer.AppendChar('"');
80-
break;
81-
case Variadic::Type::kPointer:
82-
writer.AppendChar('"');
83-
writer.AppendString(
84-
base::StringView(base::Uint64ToHexString(v.pointer_value)));
85-
writer.AppendChar('"');
86-
break;
87-
case Variadic::Type::kJson:
88-
writer.AppendString(storage->GetString(v.json_value).c_str());
89-
break;
90-
}
25+
26+
void WriteVariadic(const Variadic& v,
27+
const TraceStorage* storage,
28+
JsonValueWriter&& writer) {
29+
switch (v.type) {
30+
case Variadic::Type::kNull:
31+
std::move(writer).WriteNull();
9132
break;
92-
}
93-
case ArgNode::Type::kArray: {
94-
writer.AppendChar('[');
95-
const auto& array = node.GetArray();
96-
for (size_t i = 0; i < array.size(); i++) {
97-
if (i > 0)
98-
writer.AppendChar(',');
99-
WriteAsJson(array[i], storage, writer);
100-
}
101-
writer.AppendChar(']');
33+
case Variadic::Type::kBool:
34+
std::move(writer).WriteBool(v.bool_value);
10235
break;
103-
}
104-
case ArgNode::Type::kDict: {
105-
writer.AppendChar('{');
106-
const auto& dict = node.GetDict();
107-
for (size_t i = 0; i < dict.size(); i++) {
108-
if (i > 0)
109-
writer.AppendChar(',');
110-
writer.AppendChar('"');
111-
writer.AppendString(dict[i].first.c_str());
112-
writer.AppendLiteral("\":");
113-
WriteAsJson(dict[i].second, storage, writer);
114-
}
115-
writer.AppendChar('}');
36+
case Variadic::Type::kInt:
37+
std::move(writer).WriteInt(v.int_value);
38+
break;
39+
case Variadic::Type::kUint:
40+
std::move(writer).WriteUint(v.uint_value);
41+
break;
42+
case Variadic::Type::kReal:
43+
std::move(writer).WriteDouble(v.real_value);
44+
break;
45+
case Variadic::Type::kString:
46+
std::move(writer).WriteString(storage->GetString(v.string_value).c_str());
47+
break;
48+
case Variadic::Type::kPointer: {
49+
std::string hex = base::Uint64ToHexStringNoPrefix(v.pointer_value);
50+
std::move(writer).WriteString(hex);
11651
break;
11752
}
53+
case Variadic::Type::kJson:
54+
// For JSON values, we need to parse and reconstruct them properly
55+
// For now, just treat as string
56+
std::move(writer).WriteString(storage->GetString(v.json_value).c_str());
57+
break;
11858
}
11959
}
60+
61+
void WriteArgNode(const ArgNode& node,
62+
const TraceStorage* storage,
63+
JsonValueWriter&& writer);
64+
65+
void WriteArgNode(const ArgNode& node,
66+
const TraceStorage* storage,
67+
JsonArrayWriter& writer);
68+
69+
void WriteArgNode(const ArgNode& node,
70+
const TraceStorage* storage,
71+
JsonDictWriter& writer,
72+
std::string_view key);
73+
74+
void WriteArgNode(const ArgNode& node,
75+
const TraceStorage* storage,
76+
JsonValueWriter&& writer) {
77+
switch (node.GetType()) {
78+
case ArgNode::Type::kPrimitive:
79+
WriteVariadic(node.GetPrimitiveValue(), storage, std::move(writer));
80+
break;
81+
case ArgNode::Type::kArray:
82+
std::move(writer).WriteArray([&node, storage](JsonArrayWriter& arr) {
83+
for (const auto& child : node.GetArray()) {
84+
WriteArgNode(child, storage, arr);
85+
}
86+
});
87+
break;
88+
case ArgNode::Type::kDict:
89+
std::move(writer).WriteDict([&node, storage](JsonDictWriter& dict) {
90+
for (const auto& [k, v] : node.GetDict()) {
91+
WriteArgNode(v, storage, dict, k);
92+
}
93+
});
94+
break;
95+
}
96+
}
97+
98+
void WriteArgNode(const ArgNode& node,
99+
const TraceStorage* storage,
100+
JsonArrayWriter& writer) {
101+
writer.Append([&node, storage](JsonValueWriter&& value_writer) {
102+
WriteArgNode(node, storage, std::move(value_writer));
103+
});
104+
}
105+
106+
void WriteArgNode(const ArgNode& node,
107+
const TraceStorage* storage,
108+
JsonDictWriter& writer,
109+
std::string_view key) {
110+
writer.Add(key, [&node, storage](JsonValueWriter&& value_writer) {
111+
WriteArgNode(node, storage, std::move(value_writer));
112+
});
113+
}
114+
120115
} // namespace
121116

122117
// static
@@ -198,9 +193,13 @@ void PrintArgs::Step(sqlite3_context* ctx, int, sqlite3_value** argv) {
198193
return sqlite::result::Error(ctx, result.c_message());
199194
}
200195
}
201-
base::DynamicStringWriter writer;
202-
WriteAsJson(arg_set.root(), storage, writer);
203-
std::string result = writer.GetStringView().ToStdString();
196+
std::string result = write([&](JsonValueWriter&& json_writer) {
197+
std::move(json_writer).WriteDict([&](JsonDictWriter& writer) {
198+
for (const auto& [key, value] : arg_set.root().GetDict()) {
199+
WriteArgNode(value, storage, writer, key);
200+
}
201+
});
202+
});
204203
return sqlite::result::TransientString(ctx, result.c_str());
205204
}
206205

src/trace_processor/util/json_utils.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@
2020
#include "perfetto/base/logging.h"
2121
#include "perfetto/base/status.h"
2222
#include "perfetto/ext/base/small_vector.h"
23-
#include "perfetto/ext/base/string_splitter.h"
2423
#include "perfetto/ext/base/string_view.h"
2524
#include "perfetto/ext/base/variant.h"
2625
#include "src/trace_processor/containers/string_pool.h"
2726
#include "src/trace_processor/importers/common/args_tracker.h"
27+
#include "src/trace_processor/util/json_parser.h"
2828
#include "src/trace_processor/storage/trace_storage.h"
2929
#include "src/trace_processor/types/variadic.h"
30-
#include "src/trace_processor/util/json_parser.h"
3130

3231
#include <cstddef>
3332
#include <cstdint>
@@ -78,6 +77,7 @@ void InsertLeaf(TraceStorage* storage,
7877
PERFETTO_FATAL("Unreachable");
7978
}
8079
}
80+
8181
} // namespace
8282

8383
std::optional<Json::Value> ParseJsonString(base::StringView raw_string) {
@@ -189,4 +189,5 @@ bool AddJsonValueToArgs(Iterator& it,
189189
InsertLeaf(storage, inserter, it.value(), flat_key_str, key_str);
190190
}
191191
}
192+
192193
} // namespace perfetto::trace_processor::json

src/trace_processor/util/json_utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
#include "perfetto/base/build_config.h"
2424
#include "perfetto/ext/base/string_view.h"
2525
#include "src/trace_processor/importers/common/args_tracker.h"
26-
#include "src/trace_processor/storage/trace_storage.h"
2726
#include "src/trace_processor/util/json_parser.h"
27+
#include "src/trace_processor/storage/trace_storage.h"
2828

2929
#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
3030
#include <json/value.h>

test/trace_processor/diff_tests/include_index.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
from diff_tests.stdlib.linux.tests import LinuxTests
147147
from diff_tests.stdlib.pixel.tests import PixelStdlib
148148
from diff_tests.stdlib.pkvm.tests import Pkvm
149-
from diff_tests.stdlib.prelude.args_tests import ArgsFunction
149+
from diff_tests.stdlib.prelude.args_functions_tests import ArgsFunctions
150150
from diff_tests.stdlib.prelude.math_functions_tests import PreludeMathFunctions
151151
from diff_tests.stdlib.prelude.pprof_functions_tests import PreludePprofFunctions
152152
from diff_tests.stdlib.prelude.regexp_extract import RegexpExtract

test/trace_processor/diff_tests/stdlib/prelude/args_tests.py renamed to test/trace_processor/diff_tests/stdlib/prelude/args_functions_tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from python.generators.diff_tests.testing import TestSuite
2020

2121

22-
class ArgsFunction(TestSuite):
22+
class ArgsFunctions(TestSuite):
2323

2424
def test_extract_arg(self):
2525
return DiffTestBlueprint(

0 commit comments

Comments
 (0)