-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcapnp-json.c++
115 lines (107 loc) · 3.15 KB
/
capnp-json.c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2013 Daniel Harrison. All Rights Reserved.
#include <capnp/dynamic.h>
#include <capnp/message.h>
#include <capnp/schema.capnp.h>
#include <capnp/schema.h>
#include <capnp/serialize-packed.h>
#include <iostream>
using ::capnp::DynamicValue;
using ::capnp::DynamicStruct;
using ::capnp::DynamicEnum;
using ::capnp::DynamicList;
using ::capnp::List;
using ::capnp::Schema;
using ::capnp::StructSchema;
using ::capnp::EnumSchema;
using ::capnp::Void;
using ::capnp::Text;
using ::capnp::MallocMessageBuilder;
using ::capnp::PackedFdMessageReader;
void dynamicPrintValue(DynamicValue::Reader value) {
// Print an arbitrary message via the dynamic API by
// iterating over the schema. Look at the handling
// of STRUCT in particular.
switch (value.getType()) {
case DynamicValue::VOID:
std::cout << "null";
break;
case DynamicValue::BOOL:
std::cout << (value.as<bool>() ? "true" : "false");
break;
case DynamicValue::INT:
std::cout << value.as<int64_t>();
break;
case DynamicValue::UINT:
std::cout << value.as<uint64_t>();
break;
case DynamicValue::FLOAT:
std::cout << value.as<double>();
break;
case DynamicValue::TEXT:
std::cout << '\"' << value.as<Text>().cStr() << '\"';
break;
case DynamicValue::LIST: {
std::cout << "[";
bool first = true;
for (auto element: value.as<DynamicList>()) {
if (first) {
first = false;
} else {
std::cout << ", ";
}
dynamicPrintValue(element);
}
std::cout << "]";
break;
}
case DynamicValue::ENUM: {
auto enumValue = value.as<DynamicEnum>();
KJ_IF_MAYBE(enumerant, enumValue.getEnumerant()) {
std::cout << "\"" << enumerant->getProto().getName().cStr() << "\"";
} else {
// Unknown enum value; output raw number.
std::cout << "\"" << enumValue.getRaw() << "\"";
}
break;
}
case DynamicValue::STRUCT: {
std::cout << "{";
auto structValue = value.as<DynamicStruct>();
bool first = true;
for (auto field: structValue.getSchema().getFields()) {
KJ_IF_MAYBE(w, structValue.which()) {
if (w->getProto().getName() != field.getProto().getName() &&
!structValue.has(field)) {
continue;
}
} else {
if (!structValue.has(field)) continue;
}
if (first) {
first = false;
} else {
std::cout << ", ";
}
std::cout << "\"" << field.getProto().getName().cStr() << "\""
<< " : ";
dynamicPrintValue(structValue.get(field));
}
std::cout << "}";
break;
}
default:
// There are other types, we aren't handling them.
std::cout << "\"?\"";
break;
}
}
void dynamicPrintMessage(int fd, StructSchema schema) {
::capnp::StreamFdMessageReader message(fd);
dynamicPrintValue(message.getRoot<DynamicStruct>(schema));
std::cout << std::endl;
}
int main(int argc, char* argv[]) {
StructSchema schema = Schema::from<::capnp::schema::CodeGeneratorRequest>();
dynamicPrintMessage(0, schema);
return 0;
}