Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
372612cd
Commit
372612cd
authored
Aug 15, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Mostly done with anonymous unions.
parent
248b149a
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
410 additions
and
96 deletions
+410
-96
bootstrap-test.ekam-rule
c++/src/capnp/bootstrap-test.ekam-rule
+2
-0
capnpc-c++.c++
c++/src/capnp/compiler/capnpc-c++.c++
+25
-14
grammar.capnp.c++
c++/src/capnp/compiler/grammar.capnp.c++
+30
-30
dynamic-test.c++
c++/src/capnp/dynamic-test.c++
+69
-9
dynamic.c++
c++/src/capnp/dynamic.c++
+74
-10
dynamic.h
c++/src/capnp/dynamic.h
+3
-0
encoding-test.c++
c++/src/capnp/encoding-test.c++
+3
-2
generated-header-support.h
c++/src/capnp/generated-header-support.h
+3
-7
schema-loader-test.c++
c++/src/capnp/schema-loader-test.c++
+34
-0
schema-loader.c++
c++/src/capnp/schema-loader.c++
+14
-10
schema-test.c++
c++/src/capnp/schema-test.c++
+11
-0
schema.c++
c++/src/capnp/schema.c++
+78
-7
schema.h
c++/src/capnp/schema.h
+6
-0
stringify-test.c++
c++/src/capnp/stringify-test.c++
+28
-0
stringify.c++
c++/src/capnp/stringify.c++
+10
-3
test.capnp
c++/src/capnp/test.capnp
+4
-4
common.h
c++/src/kj/common.h
+4
-0
debug.h
c++/src/kj/debug.h
+12
-0
No files found.
c++/src/capnp/bootstrap-test.ekam-rule
View file @
372612cd
...
@@ -73,3 +73,5 @@ for file in $INPUTS; do
...
@@ -73,3 +73,5 @@ for file in $INPUTS; do
diff
-u
$srcfile
tmp/capnp/bootstrap-test-tmp/
$file
.
$ext
>
&2
diff
-u
$srcfile
tmp/capnp/bootstrap-test-tmp/
$file
.
$ext
>
&2
done
done
done
done
echo
passed
c++/src/capnp/compiler/capnpc-c++.c++
View file @
372612cd
...
@@ -119,7 +119,7 @@ void enumerateDeps(schema::Node::Reader node, std::set<uint64_t>& deps) {
...
@@ -119,7 +119,7 @@ void enumerateDeps(schema::Node::Reader node, std::set<uint64_t>& deps) {
struct
OrderByName
{
struct
OrderByName
{
template
<
typename
T
>
template
<
typename
T
>
inline
bool
operator
()(
const
T
&
a
,
const
T
&
b
)
const
{
inline
bool
operator
()(
const
T
&
a
,
const
T
&
b
)
const
{
return
a
.
getProto
().
getName
()
<
b
.
getProto
().
getName
();
return
a
.
member
.
getProto
().
getName
()
<
b
.
member
.
getProto
().
getName
();
}
}
};
};
...
@@ -135,11 +135,12 @@ void makeSubMemberInfoTable(const StructSchema::Member& member,
...
@@ -135,11 +135,12 @@ void makeSubMemberInfoTable(const StructSchema::Member& member,
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
// Only create a sub-table if the union is named.
// Only create a sub-table if the union is named.
if
(
member
.
getProto
().
getName
().
size
()
>
0
)
{
if
(
member
.
getProto
().
getName
().
size
()
>
0
)
{
makeMemberInfoTable
(
1
+
member
.
getIndex
(),
member
.
asUnion
().
getMembers
(),
info
);
makeMemberInfoTable
(
1
+
member
.
getProto
().
getOrdinal
(),
member
.
asUnion
().
getMembers
(),
info
);
}
}
break
;
break
;
case
schema
:
:
StructNode
::
Member
::
Body
::
GROUP_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
GROUP_MEMBER
:
makeMemberInfoTable
(
1
+
member
.
get
Index
(),
member
.
asGroup
().
getMembers
(),
info
);
makeMemberInfoTable
(
1
+
member
.
get
Proto
().
getOrdinal
(),
member
.
asGroup
().
getMembers
(),
info
);
break
;
break
;
}
}
}
}
...
@@ -148,29 +149,40 @@ void makeSubMemberInfoTable(const EnumSchema::Enumerant& member,
...
@@ -148,29 +149,40 @@ void makeSubMemberInfoTable(const EnumSchema::Enumerant& member,
void
makeSubMemberInfoTable
(
const
InterfaceSchema
::
Method
&
member
,
void
makeSubMemberInfoTable
(
const
InterfaceSchema
::
Method
&
member
,
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
)
{}
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
)
{}
template
<
typename
Member
>
struct
MemberAndIndex
{
Member
member
;
uint
index
;
MemberAndIndex
(
Member
member
)
:
member
(
member
),
index
(
member
.
getIndex
())
{}
MemberAndIndex
(
Member
member
,
uint
index
)
:
member
(
member
),
index
(
index
)
{}
};
void
enumerateScope
(
const
StructSchema
::
MemberList
&
members
,
void
enumerateScope
(
const
StructSchema
::
MemberList
&
members
,
kj
::
Vector
<
StructSchema
::
Member
>&
vec
)
{
kj
::
Vector
<
MemberAndIndex
<
StructSchema
::
Member
>>&
vec
,
uint
offset
=
0
)
{
// Given a member list, flatten all members of the scope into one vector. This basically means
// Given a member list, flatten all members of the scope into one vector. This basically means
// copying all the members to the vector, except that unnamed unions are flattened.
// copying all the members to the vector, except that unnamed unions are flattened, with their
// members' indexes being offset by the size of the parent scope.
for
(
auto
member
:
members
)
{
for
(
auto
member
:
members
)
{
vec
.
add
(
member
);
vec
.
add
(
member
,
member
.
getIndex
()
+
offset
);
if
(
member
.
getProto
().
getName
().
size
()
==
0
)
{
if
(
member
.
getProto
().
getName
().
size
()
==
0
)
{
// Flatten unnamed union.
// Flatten unnamed union.
enumerateScope
(
member
.
asUnion
().
getMembers
(),
vec
);
enumerateScope
(
member
.
asUnion
().
getMembers
(),
vec
,
offset
+
members
.
size
()
);
}
}
}
}
}
}
void
enumerateScope
(
const
EnumSchema
::
EnumerantList
&
members
,
void
enumerateScope
(
const
EnumSchema
::
EnumerantList
&
members
,
kj
::
Vector
<
EnumSchema
::
Enumerant
>&
vec
)
{
kj
::
Vector
<
MemberAndIndex
<
EnumSchema
::
Enumerant
>
>&
vec
)
{
for
(
auto
member
:
members
)
{
for
(
auto
member
:
members
)
{
vec
.
add
(
member
);
vec
.
add
(
member
);
}
}
}
}
void
enumerateScope
(
const
InterfaceSchema
::
MethodList
&
members
,
void
enumerateScope
(
const
InterfaceSchema
::
MethodList
&
members
,
kj
::
Vector
<
InterfaceSchema
::
Method
>&
vec
)
{
kj
::
Vector
<
MemberAndIndex
<
InterfaceSchema
::
Method
>
>&
vec
)
{
for
(
auto
member
:
members
)
{
for
(
auto
member
:
members
)
{
vec
.
add
(
member
);
vec
.
add
(
member
);
}
}
...
@@ -179,16 +191,15 @@ void enumerateScope(const InterfaceSchema::MethodList& members,
...
@@ -179,16 +191,15 @@ void enumerateScope(const InterfaceSchema::MethodList& members,
template
<
typename
MemberList
>
template
<
typename
MemberList
>
void
makeMemberInfoTable
(
uint
parent
,
MemberList
&&
members
,
void
makeMemberInfoTable
(
uint
parent
,
MemberList
&&
members
,
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
)
{
kj
::
Vector
<
capnp
::
_
::
RawSchema
::
MemberInfo
>&
info
)
{
kj
::
Vector
<
kj
::
Decay
<
decltype
(
members
[
0
])
>>
sortedMembers
(
members
.
size
());
kj
::
Vector
<
MemberAndIndex
<
decltype
(
members
[
0
])
>>
sorted
(
members
.
size
());
enumerateScope
(
members
,
sorted
Members
);
enumerateScope
(
members
,
sorted
);
auto
sorted
=
KJ_MAP
(
members
,
m
)
{
return
m
;
};
std
::
sort
(
sorted
.
begin
(),
sorted
.
end
(),
OrderByName
());
std
::
sort
(
sorted
.
begin
(),
sorted
.
end
(),
OrderByName
());
for
(
auto
&
member
:
sorted
)
{
for
(
auto
&
member
:
sorted
)
{
info
.
add
(
capnp
::
_
::
RawSchema
::
MemberInfo
{
info
.
add
(
capnp
::
_
::
RawSchema
::
MemberInfo
{
kj
::
implicitCast
<
uint16_t
>
(
parent
),
kj
::
implicitCast
<
uint16_t
>
(
parent
),
kj
::
implicitCast
<
uint16_t
>
(
member
.
getIndex
()
)
kj
::
implicitCast
<
uint16_t
>
(
member
.
index
)
});
});
}
}
for
(
auto
member
:
members
)
{
for
(
auto
member
:
members
)
{
...
@@ -1063,7 +1074,7 @@ private:
...
@@ -1063,7 +1074,7 @@ private:
"};
\n
"
"};
\n
"
"static const ::capnp::_::RawSchema::MemberInfo m_"
,
hexId
,
"[] = {
\n
"
,
"static const ::capnp::_::RawSchema::MemberInfo m_"
,
hexId
,
"[] = {
\n
"
,
KJ_MAP
(
memberInfos
,
info
)
{
KJ_MAP
(
memberInfos
,
info
)
{
return
kj
::
strTree
(
" { "
,
info
.
unionIndex
,
", "
,
info
.
index
,
" },
\n
"
);
return
kj
::
strTree
(
" { "
,
info
.
scopeOrdinal
,
", "
,
info
.
index
,
" },
\n
"
);
},
},
"};
\n
"
"};
\n
"
"const ::capnp::_::RawSchema s_"
,
hexId
,
" = {
\n
"
"const ::capnp::_::RawSchema s_"
,
hexId
,
" = {
\n
"
...
...
c++/src/capnp/compiler/grammar.capnp.c++
View file @
372612cd
...
@@ -1435,36 +1435,36 @@ static const ::capnp::_::RawSchema::MemberInfo m_96efe787c17e83bb[] = {
...
@@ -1435,36 +1435,36 @@ static const ::capnp::_::RawSchema::MemberInfo m_96efe787c17e83bb[] = {
{
2
,
2
},
{
2
,
2
},
{
2
,
1
},
{
2
,
1
},
{
2
,
0
},
{
2
,
0
},
{
4
,
9
},
{
7
,
9
},
{
4
,
15
},
{
7
,
15
},
{
4
,
27
},
{
7
,
27
},
{
4
,
24
},
{
7
,
24
},
{
4
,
25
},
{
7
,
25
},
{
4
,
17
},
{
7
,
17
},
{
4
,
18
},
{
7
,
18
},
{
4
,
19
},
{
7
,
19
},
{
4
,
16
},
{
7
,
16
},
{
4
,
28
},
{
7
,
28
},
{
4
,
29
},
{
7
,
29
},
{
4
,
26
},
{
7
,
26
},
{
4
,
21
},
{
7
,
21
},
{
4
,
22
},
{
7
,
22
},
{
4
,
23
},
{
7
,
23
},
{
4
,
20
},
{
7
,
20
},
{
4
,
14
},
{
7
,
14
},
{
4
,
1
},
{
7
,
1
},
{
4
,
2
},
{
7
,
2
},
{
4
,
3
},
{
7
,
3
},
{
4
,
5
},
{
7
,
5
},
{
4
,
13
},
{
7
,
13
},
{
4
,
12
},
{
7
,
12
},
{
4
,
7
},
{
7
,
7
},
{
4
,
8
},
{
7
,
8
},
{
4
,
11
},
{
7
,
11
},
{
4
,
10
},
{
7
,
10
},
{
4
,
4
},
{
7
,
4
},
{
4
,
6
},
{
7
,
6
},
{
4
,
0
},
{
7
,
0
},
};
};
const
::
capnp
::
_
::
RawSchema
s_96efe787c17e83bb
=
{
const
::
capnp
::
_
::
RawSchema
s_96efe787c17e83bb
=
{
0x96efe787c17e83bb
,
b_96efe787c17e83bb
.
words
,
664
,
d_96efe787c17e83bb
,
m_96efe787c17e83bb
,
0x96efe787c17e83bb
,
b_96efe787c17e83bb
.
words
,
664
,
d_96efe787c17e83bb
,
m_96efe787c17e83bb
,
...
...
c++/src/capnp/dynamic-test.c++
View file @
372612cd
...
@@ -293,6 +293,14 @@ TEST(DynamicApi, UnionsRead) {
...
@@ -293,6 +293,14 @@ TEST(DynamicApi, UnionsRead) {
}
}
}
}
#if KJ_NO_EXCEPTIONS
#undef EXPECT_ANY_THROW
#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".")
#define EXPECT_NONFATAL_FAILURE(code) code
#else
#define EXPECT_NONFATAL_FAILURE EXPECT_ANY_THROW
#endif
TEST
(
DynamicApi
,
UnionsWrite
)
{
TEST
(
DynamicApi
,
UnionsWrite
)
{
MallocMessageBuilder
builder
;
MallocMessageBuilder
builder
;
auto
root
=
builder
.
initRoot
<
DynamicStruct
>
(
Schema
::
from
<
TestUnion
>
());
auto
root
=
builder
.
initRoot
<
DynamicStruct
>
(
Schema
::
from
<
TestUnion
>
());
...
@@ -314,29 +322,81 @@ TEST(DynamicApi, UnionsWrite) {
...
@@ -314,29 +322,81 @@ TEST(DynamicApi, UnionsWrite) {
ASSERT_EQ
(
TestUnion
::
Union3
::
U3F0S64
,
reader
.
getUnion3
().
which
());
ASSERT_EQ
(
TestUnion
::
Union3
::
U3F0S64
,
reader
.
getUnion3
().
which
());
EXPECT_EQ
(
1234567890123456789ll
,
reader
.
getUnion3
().
getU3f0s64
());
EXPECT_EQ
(
1234567890123456789ll
,
reader
.
getUnion3
().
getU3f0s64
());
// Can't access union members by name from the root.
EXPECT_ANY_THROW
(
root
.
get
(
"u0f1s32"
));
EXPECT_ANY_THROW
(
root
.
set
(
"u0f1s32"
,
1234567
));
// But can access them by member pointer.
auto
member
=
root
.
get
(
"union0"
).
as
<
DynamicUnion
>
().
getSchema
().
getMemberByName
(
"u0f1s32"
);
EXPECT_EQ
(
1234567
,
root
.
get
(
member
).
as
<
int
>
());
auto
member2
=
root
.
get
(
"union0"
).
as
<
DynamicUnion
>
().
getSchema
().
getMemberByName
(
"u0f1sp"
);
root
.
set
(
member2
,
"foo"
);
EXPECT_EQ
(
"foo"
,
reader
.
getUnion0
().
getU0f1sp
());
}
}
#if KJ_NO_EXCEPTIONS
TEST
(
DynamicApi
,
UnnamedUnion
)
{
#undef EXPECT_ANY_THROW
MallocMessageBuilder
builder
;
// All exceptions should be non-fatal, so when exceptions are disabled the code should return.
StructSchema
schema
=
Schema
::
from
<
test
::
TestUnnamedUnion
>
();
#define EXPECT_ANY_THROW(code) code
auto
root
=
builder
.
initRoot
<
DynamicStruct
>
(
schema
);
#endif
DynamicUnion
::
Builder
unionBuilder
=
root
.
get
(
KJ_ASSERT_NONNULL
(
schema
.
getUnnamedUnion
())).
as
<
DynamicUnion
>
();
EXPECT_EQ
(
schema
.
getMemberByName
(
"foo"
),
KJ_ASSERT_NONNULL
(
unionBuilder
.
which
()));
root
.
set
(
"bar"
,
321
);
EXPECT_EQ
(
schema
.
getMemberByName
(
"bar"
),
KJ_ASSERT_NONNULL
(
unionBuilder
.
which
()));
EXPECT_EQ
(
321u
,
root
.
get
(
"bar"
).
as
<
uint
>
());
EXPECT_EQ
(
321u
,
root
.
asReader
().
get
(
"bar"
).
as
<
uint
>
());
EXPECT_EQ
(
321u
,
unionBuilder
.
get
().
as
<
uint
>
());
EXPECT_EQ
(
321u
,
unionBuilder
.
asReader
().
get
().
as
<
uint
>
());
EXPECT_ANY_THROW
(
root
.
get
(
"foo"
));
EXPECT_ANY_THROW
(
root
.
asReader
().
get
(
"foo"
));
root
.
set
(
"foo"
,
123
);
EXPECT_EQ
(
schema
.
getMemberByName
(
"foo"
),
KJ_ASSERT_NONNULL
(
unionBuilder
.
which
()));
EXPECT_EQ
(
123u
,
root
.
get
(
"foo"
).
as
<
uint
>
());
EXPECT_EQ
(
123u
,
root
.
asReader
().
get
(
"foo"
).
as
<
uint
>
());
EXPECT_EQ
(
123u
,
unionBuilder
.
get
().
as
<
uint
>
());
EXPECT_EQ
(
123u
,
unionBuilder
.
asReader
().
get
().
as
<
uint
>
());
EXPECT_ANY_THROW
(
root
.
get
(
"bar"
));
EXPECT_ANY_THROW
(
root
.
asReader
().
get
(
"bar"
));
unionBuilder
.
set
(
"bar"
,
321
);
EXPECT_EQ
(
schema
.
getMemberByName
(
"bar"
),
KJ_ASSERT_NONNULL
(
unionBuilder
.
which
()));
EXPECT_EQ
(
321u
,
root
.
get
(
"bar"
).
as
<
uint
>
());
EXPECT_EQ
(
321u
,
root
.
asReader
().
get
(
"bar"
).
as
<
uint
>
());
EXPECT_EQ
(
321u
,
unionBuilder
.
get
().
as
<
uint
>
());
EXPECT_EQ
(
321u
,
unionBuilder
.
asReader
().
get
().
as
<
uint
>
());
EXPECT_ANY_THROW
(
root
.
get
(
"foo"
));
EXPECT_ANY_THROW
(
root
.
asReader
().
get
(
"foo"
));
unionBuilder
.
set
(
"foo"
,
123
);
EXPECT_EQ
(
schema
.
getMemberByName
(
"foo"
),
KJ_ASSERT_NONNULL
(
unionBuilder
.
which
()));
EXPECT_EQ
(
123u
,
root
.
get
(
"foo"
).
as
<
uint
>
());
EXPECT_EQ
(
123u
,
root
.
asReader
().
get
(
"foo"
).
as
<
uint
>
());
EXPECT_EQ
(
123u
,
unionBuilder
.
get
().
as
<
uint
>
());
EXPECT_EQ
(
123u
,
unionBuilder
.
asReader
().
get
().
as
<
uint
>
());
EXPECT_ANY_THROW
(
root
.
get
(
"bar"
));
EXPECT_ANY_THROW
(
root
.
asReader
().
get
(
"bar"
));
}
TEST
(
DynamicApi
,
ConversionFailures
)
{
TEST
(
DynamicApi
,
ConversionFailures
)
{
MallocMessageBuilder
builder
;
MallocMessageBuilder
builder
;
auto
root
=
builder
.
initRoot
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
());
auto
root
=
builder
.
initRoot
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
());
root
.
set
(
"int8Field"
,
123
);
root
.
set
(
"int8Field"
,
123
);
EXPECT_
ANY_THROW
(
root
.
set
(
"int8Field"
,
1234
));
EXPECT_
NONFATAL_FAILURE
(
root
.
set
(
"int8Field"
,
1234
));
root
.
set
(
"uInt32Field"
,
1
);
root
.
set
(
"uInt32Field"
,
1
);
EXPECT_
ANY_THROW
(
root
.
set
(
"uInt32Field"
,
-
1
));
EXPECT_
NONFATAL_FAILURE
(
root
.
set
(
"uInt32Field"
,
-
1
));
root
.
set
(
"int16Field"
,
5
);
root
.
set
(
"int16Field"
,
5
);
EXPECT_
ANY_THROW
(
root
.
set
(
"int16Field"
,
0.5
));
EXPECT_
NONFATAL_FAILURE
(
root
.
set
(
"int16Field"
,
0.5
));
root
.
set
(
"boolField"
,
true
);
root
.
set
(
"boolField"
,
true
);
EXPECT_
ANY_THROW
(
root
.
set
(
"boolField"
,
1
));
EXPECT_
NONFATAL_FAILURE
(
root
.
set
(
"boolField"
,
1
));
}
}
TEST
(
DynamicApi
,
LateUnion
)
{
TEST
(
DynamicApi
,
LateUnion
)
{
...
...
c++/src/capnp/dynamic.c++
View file @
372612cd
...
@@ -172,7 +172,7 @@ DynamicValue::Reader DynamicUnion::Reader::get() const {
...
@@ -172,7 +172,7 @@ DynamicValue::Reader DynamicUnion::Reader::get() const {
KJ_IF_MAYBE
(
w
,
which
())
{
KJ_IF_MAYBE
(
w
,
which
())
{
return
DynamicValue
::
Reader
(
DynamicStruct
::
Reader
::
getImpl
(
reader
,
*
w
));
return
DynamicValue
::
Reader
(
DynamicStruct
::
Reader
::
getImpl
(
reader
,
*
w
));
}
else
{
}
else
{
return
nullptr
;
KJ_FAIL_REQUIRE
(
"DynamicUnion get() cannot be called if which() returns nullptr."
)
;
}
}
}
}
...
@@ -180,7 +180,7 @@ DynamicValue::Builder DynamicUnion::Builder::get() {
...
@@ -180,7 +180,7 @@ DynamicValue::Builder DynamicUnion::Builder::get() {
KJ_IF_MAYBE
(
w
,
which
())
{
KJ_IF_MAYBE
(
w
,
which
())
{
return
DynamicValue
::
Builder
(
DynamicStruct
::
Builder
::
getImpl
(
builder
,
*
w
));
return
DynamicValue
::
Builder
(
DynamicStruct
::
Builder
::
getImpl
(
builder
,
*
w
));
}
else
{
}
else
{
return
nullptr
;
KJ_FAIL_REQUIRE
(
"DynamicUnion get() cannot be called if which() returns nullptr."
)
;
}
}
}
}
...
@@ -284,18 +284,61 @@ void DynamicUnion::Builder::setObjectDiscriminant(StructSchema::Member member) {
...
@@ -284,18 +284,61 @@ void DynamicUnion::Builder::setObjectDiscriminant(StructSchema::Member member) {
// =======================================================================================
// =======================================================================================
void
DynamicStruct
::
Builder
::
verifySetInUnion
(
StructSchema
::
Member
member
)
{
// If a union member, verify that it is set.
KJ_IF_MAYBE
(
containingUnion
,
member
.
getContainingUnion
())
{
uint16_t
discrim
=
builder
.
getDataField
<
uint16_t
>
(
containingUnion
->
getProto
().
getBody
().
getUnionMember
().
getDiscriminantOffset
()
*
ELEMENTS
);
KJ_REQUIRE
(
member
.
getIndex
()
==
discrim
,
"Tried to get() a union member which is not currently initialized."
,
member
.
getProto
().
getName
(),
containingUnion
->
getProto
().
getName
(),
member
.
getContainingStruct
().
getProto
().
getDisplayName
());
}
}
void
DynamicStruct
::
Builder
::
setInUnion
(
StructSchema
::
Member
member
)
{
// If a union member, set the discriminant to match.
KJ_IF_MAYBE
(
containingUnion
,
member
.
getContainingUnion
())
{
builder
.
setDataField
<
uint16_t
>
(
containingUnion
->
getProto
().
getBody
().
getUnionMember
().
getDiscriminantOffset
()
*
ELEMENTS
,
member
.
getIndex
());
}
}
DynamicValue
::
Reader
DynamicStruct
::
Reader
::
get
(
StructSchema
::
Member
member
)
const
{
DynamicValue
::
Reader
DynamicStruct
::
Reader
::
get
(
StructSchema
::
Member
member
)
const
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
// If a union member, verify that it is set.
KJ_IF_MAYBE
(
containingUnion
,
member
.
getContainingUnion
())
{
uint16_t
discrim
=
reader
.
getDataField
<
uint16_t
>
(
containingUnion
->
getProto
().
getBody
().
getUnionMember
().
getDiscriminantOffset
()
*
ELEMENTS
);
KJ_REQUIRE
(
member
.
getIndex
()
==
discrim
,
"Tried to get() a union member which is not currently initialized."
,
member
.
getProto
().
getName
(),
containingUnion
->
getProto
().
getName
(),
member
.
getContainingStruct
().
getProto
().
getDisplayName
());
}
return
getImpl
(
reader
,
member
);
return
getImpl
(
reader
,
member
);
}
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
get
(
StructSchema
::
Member
member
)
{
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
get
(
StructSchema
::
Member
member
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
verifySetInUnion
(
member
);
return
getImpl
(
builder
,
member
);
return
getImpl
(
builder
,
member
);
}
}
bool
DynamicStruct
::
Reader
::
has
(
StructSchema
::
Member
member
)
const
{
bool
DynamicStruct
::
Reader
::
has
(
StructSchema
::
Member
member
)
const
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
// Check union member.
KJ_IF_MAYBE
(
containingUnion
,
member
.
getContainingUnion
())
{
uint16_t
discrim
=
reader
.
getDataField
<
uint16_t
>
(
containingUnion
->
getProto
().
getBody
().
getUnionMember
().
getDiscriminantOffset
()
*
ELEMENTS
);
if
(
discrim
!=
member
.
getIndex
())
{
return
false
;
}
}
auto
body
=
member
.
getProto
().
getBody
();
auto
body
=
member
.
getProto
().
getBody
();
switch
(
body
.
which
())
{
switch
(
body
.
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
{
...
@@ -362,6 +405,15 @@ bool DynamicStruct::Reader::has(StructSchema::Member member) const {
...
@@ -362,6 +405,15 @@ bool DynamicStruct::Reader::has(StructSchema::Member member) const {
bool
DynamicStruct
::
Builder
::
has
(
StructSchema
::
Member
member
)
{
bool
DynamicStruct
::
Builder
::
has
(
StructSchema
::
Member
member
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
// Check union member.
KJ_IF_MAYBE
(
containingUnion
,
member
.
getContainingUnion
())
{
uint16_t
discrim
=
builder
.
getDataField
<
uint16_t
>
(
containingUnion
->
getProto
().
getBody
().
getUnionMember
().
getDiscriminantOffset
()
*
ELEMENTS
);
if
(
discrim
!=
member
.
getIndex
())
{
return
false
;
}
}
auto
body
=
member
.
getProto
().
getBody
();
auto
body
=
member
.
getProto
().
getBody
();
switch
(
body
.
which
())
{
switch
(
body
.
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
{
...
@@ -428,21 +480,25 @@ bool DynamicStruct::Builder::has(StructSchema::Member member) {
...
@@ -428,21 +480,25 @@ bool DynamicStruct::Builder::has(StructSchema::Member member) {
void
DynamicStruct
::
Builder
::
set
(
StructSchema
::
Member
member
,
const
DynamicValue
::
Reader
&
value
)
{
void
DynamicStruct
::
Builder
::
set
(
StructSchema
::
Member
member
,
const
DynamicValue
::
Reader
&
value
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
setInUnion
(
member
);
return
setImpl
(
builder
,
member
,
value
);
return
setImpl
(
builder
,
member
,
value
);
}
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
init
(
StructSchema
::
Member
member
)
{
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
init
(
StructSchema
::
Member
member
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
setInUnion
(
member
);
return
initImpl
(
builder
,
member
);
return
initImpl
(
builder
,
member
);
}
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
init
(
StructSchema
::
Member
member
,
uint
size
)
{
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
init
(
StructSchema
::
Member
member
,
uint
size
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
"`member` is not a member of this struct."
);
setInUnion
(
member
);
return
initImpl
(
builder
,
member
,
size
);
return
initImpl
(
builder
,
member
,
size
);
}
}
DynamicStruct
::
Builder
DynamicStruct
::
Builder
::
getObject
(
DynamicStruct
::
Builder
DynamicStruct
::
Builder
::
getObject
(
StructSchema
::
Member
member
,
StructSchema
type
)
{
StructSchema
::
Member
member
,
StructSchema
type
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
verifySetInUnion
(
member
);
switch
(
member
.
getProto
().
getBody
().
which
())
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
...
@@ -462,6 +518,7 @@ DynamicStruct::Builder DynamicStruct::Builder::getObject(
...
@@ -462,6 +518,7 @@ DynamicStruct::Builder DynamicStruct::Builder::getObject(
DynamicList
::
Builder
DynamicStruct
::
Builder
::
getObject
(
DynamicList
::
Builder
DynamicStruct
::
Builder
::
getObject
(
StructSchema
::
Member
member
,
ListSchema
type
)
{
StructSchema
::
Member
member
,
ListSchema
type
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
verifySetInUnion
(
member
);
switch
(
member
.
getProto
().
getBody
().
which
())
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
...
@@ -480,6 +537,7 @@ DynamicList::Builder DynamicStruct::Builder::getObject(
...
@@ -480,6 +537,7 @@ DynamicList::Builder DynamicStruct::Builder::getObject(
}
}
Text
::
Builder
DynamicStruct
::
Builder
::
getObjectAsText
(
StructSchema
::
Member
member
)
{
Text
::
Builder
DynamicStruct
::
Builder
::
getObjectAsText
(
StructSchema
::
Member
member
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
verifySetInUnion
(
member
);
switch
(
member
.
getProto
().
getBody
().
which
())
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
...
@@ -498,6 +556,7 @@ Text::Builder DynamicStruct::Builder::getObjectAsText(StructSchema::Member membe
...
@@ -498,6 +556,7 @@ Text::Builder DynamicStruct::Builder::getObjectAsText(StructSchema::Member membe
}
}
Data
::
Builder
DynamicStruct
::
Builder
::
getObjectAsData
(
StructSchema
::
Member
member
)
{
Data
::
Builder
DynamicStruct
::
Builder
::
getObjectAsData
(
StructSchema
::
Member
member
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
verifySetInUnion
(
member
);
switch
(
member
.
getProto
().
getBody
().
which
())
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
...
@@ -518,6 +577,7 @@ Data::Builder DynamicStruct::Builder::getObjectAsData(StructSchema::Member membe
...
@@ -518,6 +577,7 @@ Data::Builder DynamicStruct::Builder::getObjectAsData(StructSchema::Member membe
DynamicStruct
::
Builder
DynamicStruct
::
Builder
::
initObject
(
DynamicStruct
::
Builder
DynamicStruct
::
Builder
::
initObject
(
StructSchema
::
Member
member
,
StructSchema
type
)
{
StructSchema
::
Member
member
,
StructSchema
type
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
setInUnion
(
member
);
switch
(
member
.
getProto
().
getBody
().
which
())
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
...
@@ -537,6 +597,7 @@ DynamicStruct::Builder DynamicStruct::Builder::initObject(
...
@@ -537,6 +597,7 @@ DynamicStruct::Builder DynamicStruct::Builder::initObject(
DynamicList
::
Builder
DynamicStruct
::
Builder
::
initObject
(
DynamicList
::
Builder
DynamicStruct
::
Builder
::
initObject
(
StructSchema
::
Member
member
,
ListSchema
type
,
uint
size
)
{
StructSchema
::
Member
member
,
ListSchema
type
,
uint
size
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
setInUnion
(
member
);
switch
(
member
.
getProto
().
getBody
().
which
())
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
...
@@ -555,6 +616,7 @@ DynamicList::Builder DynamicStruct::Builder::initObject(
...
@@ -555,6 +616,7 @@ DynamicList::Builder DynamicStruct::Builder::initObject(
}
}
Text
::
Builder
DynamicStruct
::
Builder
::
initObjectAsText
(
StructSchema
::
Member
member
,
uint
size
)
{
Text
::
Builder
DynamicStruct
::
Builder
::
initObjectAsText
(
StructSchema
::
Member
member
,
uint
size
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
setInUnion
(
member
);
switch
(
member
.
getProto
().
getBody
().
which
())
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
...
@@ -573,6 +635,7 @@ Text::Builder DynamicStruct::Builder::initObjectAsText(StructSchema::Member memb
...
@@ -573,6 +635,7 @@ Text::Builder DynamicStruct::Builder::initObjectAsText(StructSchema::Member memb
}
}
Data
::
Builder
DynamicStruct
::
Builder
::
initObjectAsData
(
StructSchema
::
Member
member
,
uint
size
)
{
Data
::
Builder
DynamicStruct
::
Builder
::
initObjectAsData
(
StructSchema
::
Member
member
,
uint
size
)
{
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
KJ_REQUIRE
(
member
.
getContainingStruct
()
==
schema
,
"`member` is not a member of this struct."
);
setInUnion
(
member
);
switch
(
member
.
getProto
().
getBody
().
which
())
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
KJ_FAIL_REQUIRE
(
"Expected an Object."
);
...
@@ -591,10 +654,10 @@ Data::Builder DynamicStruct::Builder::initObjectAsData(StructSchema::Member memb
...
@@ -591,10 +654,10 @@ Data::Builder DynamicStruct::Builder::initObjectAsData(StructSchema::Member memb
}
}
DynamicValue
::
Reader
DynamicStruct
::
Reader
::
get
(
kj
::
StringPtr
name
)
const
{
DynamicValue
::
Reader
DynamicStruct
::
Reader
::
get
(
kj
::
StringPtr
name
)
const
{
return
get
Impl
(
reader
,
schema
.
getMemberByName
(
name
));
return
get
(
schema
.
getMemberByName
(
name
));
}
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
get
(
kj
::
StringPtr
name
)
{
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
get
(
kj
::
StringPtr
name
)
{
return
get
Impl
(
builder
,
schema
.
getMemberByName
(
name
));
return
get
(
schema
.
getMemberByName
(
name
));
}
}
bool
DynamicStruct
::
Reader
::
has
(
kj
::
StringPtr
name
)
const
{
bool
DynamicStruct
::
Reader
::
has
(
kj
::
StringPtr
name
)
const
{
return
has
(
schema
.
getMemberByName
(
name
));
return
has
(
schema
.
getMemberByName
(
name
));
...
@@ -603,17 +666,17 @@ bool DynamicStruct::Builder::has(kj::StringPtr name) {
...
@@ -603,17 +666,17 @@ bool DynamicStruct::Builder::has(kj::StringPtr name) {
return
has
(
schema
.
getMemberByName
(
name
));
return
has
(
schema
.
getMemberByName
(
name
));
}
}
void
DynamicStruct
::
Builder
::
set
(
kj
::
StringPtr
name
,
const
DynamicValue
::
Reader
&
value
)
{
void
DynamicStruct
::
Builder
::
set
(
kj
::
StringPtr
name
,
const
DynamicValue
::
Reader
&
value
)
{
set
Impl
(
builder
,
schema
.
getMemberByName
(
name
),
value
);
set
(
schema
.
getMemberByName
(
name
),
value
);
}
}
void
DynamicStruct
::
Builder
::
set
(
kj
::
StringPtr
name
,
void
DynamicStruct
::
Builder
::
set
(
kj
::
StringPtr
name
,
std
::
initializer_list
<
DynamicValue
::
Reader
>
value
)
{
std
::
initializer_list
<
DynamicValue
::
Reader
>
value
)
{
init
(
name
,
value
.
size
()).
as
<
DynamicList
>
().
copyFrom
(
value
);
init
(
name
,
value
.
size
()).
as
<
DynamicList
>
().
copyFrom
(
value
);
}
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
init
(
kj
::
StringPtr
name
)
{
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
init
(
kj
::
StringPtr
name
)
{
return
init
Impl
(
builder
,
schema
.
getMemberByName
(
name
));
return
init
(
schema
.
getMemberByName
(
name
));
}
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
init
(
kj
::
StringPtr
name
,
uint
size
)
{
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
init
(
kj
::
StringPtr
name
,
uint
size
)
{
return
init
Impl
(
builder
,
schema
.
getMemberByName
(
name
),
size
);
return
init
(
schema
.
getMemberByName
(
name
),
size
);
}
}
DynamicStruct
::
Builder
DynamicStruct
::
Builder
::
getObject
(
DynamicStruct
::
Builder
DynamicStruct
::
Builder
::
getObject
(
kj
::
StringPtr
name
,
StructSchema
type
)
{
kj
::
StringPtr
name
,
StructSchema
type
)
{
...
@@ -645,12 +708,13 @@ Data::Builder DynamicStruct::Builder::initObjectAsData(kj::StringPtr name, uint
...
@@ -645,12 +708,13 @@ Data::Builder DynamicStruct::Builder::initObjectAsData(kj::StringPtr name, uint
DynamicValue
::
Reader
DynamicStruct
::
Reader
::
getImpl
(
DynamicValue
::
Reader
DynamicStruct
::
Reader
::
getImpl
(
_
::
StructReader
reader
,
StructSchema
::
Member
member
)
{
_
::
StructReader
reader
,
StructSchema
::
Member
member
)
{
switch
(
member
.
getProto
().
getBody
().
which
())
{
auto
proto
=
member
.
getProto
();
switch
(
proto
.
getBody
().
which
())
{
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
case
schema
:
:
StructNode
::
Member
::
Body
::
UNION_MEMBER
:
return
DynamicUnion
::
Reader
(
member
.
asUnion
(),
reader
);
return
DynamicUnion
::
Reader
(
member
.
asUnion
(),
reader
);
case
schema
:
:
StructNode
::
Member
::
Body
::
FIELD_MEMBER
:
{
case
schema
:
:
StructNode
::
Member
::
Body
::
FIELD_MEMBER
:
{
auto
field
=
member
.
getProto
()
.
getBody
().
getFieldMember
();
auto
field
=
proto
.
getBody
().
getFieldMember
();
auto
type
=
field
.
getType
().
getBody
();
auto
type
=
field
.
getType
().
getBody
();
auto
dval
=
field
.
getDefaultValue
().
getBody
();
auto
dval
=
field
.
getDefaultValue
().
getBody
();
...
@@ -731,7 +795,7 @@ DynamicValue::Reader DynamicStruct::Reader::getImpl(
...
@@ -731,7 +795,7 @@ DynamicValue::Reader DynamicStruct::Reader::getImpl(
}
}
}
}
KJ_FAIL_ASSERT
(
"switch() missing case."
,
(
uint
)
member
.
getProto
()
.
getBody
().
which
());
KJ_FAIL_ASSERT
(
"switch() missing case."
,
(
uint
)
proto
.
getBody
().
which
());
return
nullptr
;
return
nullptr
;
}
}
...
...
c++/src/capnp/dynamic.h
View file @
372612cd
...
@@ -380,6 +380,9 @@ private:
...
@@ -380,6 +380,9 @@ private:
inline
Builder
(
StructSchema
schema
,
_
::
StructBuilder
builder
)
inline
Builder
(
StructSchema
schema
,
_
::
StructBuilder
builder
)
:
schema
(
schema
),
builder
(
builder
)
{}
:
schema
(
schema
),
builder
(
builder
)
{}
void
verifySetInUnion
(
StructSchema
::
Member
member
);
void
setInUnion
(
StructSchema
::
Member
member
);
static
DynamicValue
::
Builder
getImpl
(
static
DynamicValue
::
Builder
getImpl
(
_
::
StructBuilder
builder
,
StructSchema
::
Member
member
);
_
::
StructBuilder
builder
,
StructSchema
::
Member
member
);
static
DynamicStruct
::
Builder
getObjectImpl
(
static
DynamicStruct
::
Builder
getObjectImpl
(
...
...
c++/src/capnp/encoding-test.c++
View file @
372612cd
...
@@ -398,7 +398,7 @@ TEST(Encoding, UnionDefault) {
...
@@ -398,7 +398,7 @@ TEST(Encoding, UnionDefault) {
TEST
(
Encoding
,
UnnamedUnion
)
{
TEST
(
Encoding
,
UnnamedUnion
)
{
MallocMessageBuilder
builder
;
MallocMessageBuilder
builder
;
auto
root
=
builder
.
ge
tRoot
<
test
::
TestUnnamedUnion
>
();
auto
root
=
builder
.
ini
tRoot
<
test
::
TestUnnamedUnion
>
();
EXPECT_EQ
(
test
::
TestUnnamedUnion
::
FOO
,
root
.
which
());
EXPECT_EQ
(
test
::
TestUnnamedUnion
::
FOO
,
root
.
which
());
root
.
setBar
(
321
);
root
.
setBar
(
321
);
...
@@ -417,7 +417,8 @@ TEST(Encoding, UnnamedUnion) {
...
@@ -417,7 +417,8 @@ TEST(Encoding, UnnamedUnion) {
EXPECT_DEBUG_ANY_THROW
(
root
.
getBar
());
EXPECT_DEBUG_ANY_THROW
(
root
.
getBar
());
EXPECT_DEBUG_ANY_THROW
(
root
.
asReader
().
getBar
());
EXPECT_DEBUG_ANY_THROW
(
root
.
asReader
().
getBar
());
KJ_IF_MAYBE
(
u
,
Schema
::
from
<
test
::
TestUnnamedUnion
>
().
getUnnamedUnion
())
{
StructSchema
schema
=
Schema
::
from
<
test
::
TestUnnamedUnion
>
();
KJ_IF_MAYBE
(
u
,
schema
.
getUnnamedUnion
())
{
// The discriminant is allocated between allocating the first and second members.
// The discriminant is allocated between allocating the first and second members.
EXPECT_EQ
(
1
,
u
->
getProto
().
getBody
().
getUnionMember
().
getDiscriminantOffset
());
EXPECT_EQ
(
1
,
u
->
getProto
().
getBody
().
getUnionMember
().
getDiscriminantOffset
());
EXPECT_EQ
(
0
,
u
->
getMemberByName
(
"foo"
).
getProto
().
getBody
().
getFieldMember
().
getOffset
());
EXPECT_EQ
(
0
,
u
->
getMemberByName
(
"foo"
).
getProto
().
getBody
().
getFieldMember
().
getOffset
());
...
...
c++/src/capnp/generated-header-support.h
View file @
372612cd
...
@@ -164,13 +164,9 @@ struct RawSchema {
...
@@ -164,13 +164,9 @@ struct RawSchema {
// TODO(someday): Make this a hashtable.
// TODO(someday): Make this a hashtable.
struct
MemberInfo
{
struct
MemberInfo
{
uint16_t
unionIndex
;
uint16_t
scopeOrdinal
;
// 0 = not in a union, >0 = one plus the index of the union within the scope indicated by
// One plus the ordinal number of the parent scope of this member when looking up by name.
// scopeOrdinal.
// Zero represents the top-level scope.
// uint16_t scopeOrdinal;
// // One plus the ordinal number of the parent scope of this member when looking up by name.
// // Zero represents the top-level scope.
uint16_t
index
;
uint16_t
index
;
// Index of the member within its scope. If the index is greater than the number of elements
// Index of the member within its scope. If the index is greater than the number of elements
...
...
c++/src/capnp/schema-loader-test.c++
View file @
372612cd
...
@@ -56,6 +56,40 @@ TEST(SchemaLoader, Load) {
...
@@ -56,6 +56,40 @@ TEST(SchemaLoader, Load) {
EXPECT_EQ
(
0u
,
struct16Schema
.
getProto
().
getBody
().
getStructNode
().
getMembers
().
size
());
EXPECT_EQ
(
0u
,
struct16Schema
.
getProto
().
getBody
().
getStructNode
().
getMembers
().
size
());
}
}
TEST
(
SchemaLoader
,
LoadLateUnion
)
{
SchemaLoader
loader
;
StructSchema
schema
=
loader
.
load
(
Schema
::
from
<
test
::
TestLateUnion
>
().
getProto
()).
asStruct
();
EXPECT_EQ
(
6
,
schema
.
getMemberByName
(
"theUnion"
).
asUnion
()
.
getMemberByName
(
"grault"
).
getProto
().
getOrdinal
());
EXPECT_EQ
(
9
,
schema
.
getMemberByName
(
"anotherUnion"
).
asUnion
()
.
getMemberByName
(
"corge"
).
getProto
().
getOrdinal
());
EXPECT_TRUE
(
schema
.
findMemberByName
(
"corge"
)
==
nullptr
);
EXPECT_TRUE
(
schema
.
findMemberByName
(
"grault"
)
==
nullptr
);
}
TEST
(
SchemaLoader
,
LoadUnnamedUnion
)
{
SchemaLoader
loader
;
StructSchema
schema
=
loader
.
load
(
Schema
::
from
<
test
::
TestUnnamedUnion
>
().
getProto
()).
asStruct
();
EXPECT_TRUE
(
schema
.
findMemberByName
(
""
)
==
nullptr
);
KJ_IF_MAYBE
(
u
,
schema
.
getUnnamedUnion
())
{
EXPECT_TRUE
(
schema
.
getMemberByName
(
"foo"
)
==
u
->
getMemberByName
(
"foo"
));
EXPECT_TRUE
(
schema
.
getMemberByName
(
"bar"
)
==
u
->
getMemberByName
(
"bar"
));
EXPECT_TRUE
(
u
->
findMemberByName
(
"before"
)
==
nullptr
);
EXPECT_TRUE
(
u
->
findMemberByName
(
"after"
)
==
nullptr
);
EXPECT_TRUE
(
schema
.
findMemberByName
(
"before"
)
!=
nullptr
);
EXPECT_TRUE
(
schema
.
findMemberByName
(
"after"
)
!=
nullptr
);
}
else
{
ADD_FAILURE
()
<<
"getUnnamedUnion() should have returned non-null."
;
}
}
#if KJ_NO_EXCEPTIONS
#if KJ_NO_EXCEPTIONS
#undef EXPECT_ANY_THROW
#undef EXPECT_ANY_THROW
#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".")
#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".")
...
...
c++/src/capnp/schema-loader.c++
View file @
372612cd
...
@@ -148,7 +148,7 @@ private:
...
@@ -148,7 +148,7 @@ private:
bool
isValid
;
bool
isValid
;
std
::
map
<
uint64_t
,
_
::
RawSchema
*>
dependencies
;
std
::
map
<
uint64_t
,
_
::
RawSchema
*>
dependencies
;
// Maps (
unionIndex
, name) -> index for each member.
// Maps (
scopeOrdinal
, name) -> index for each member.
std
::
map
<
std
::
pair
<
uint
,
Text
::
Reader
>
,
uint
>
members
;
std
::
map
<
std
::
pair
<
uint
,
Text
::
Reader
>
,
uint
>
members
;
#define VALIDATE_SCHEMA(condition, ...) \
#define VALIDATE_SCHEMA(condition, ...) \
...
@@ -226,21 +226,22 @@ private:
...
@@ -226,21 +226,22 @@ private:
uint
index
=
0
;
uint
index
=
0
;
for
(
auto
member
:
members
)
{
for
(
auto
member
:
members
)
{
KJ_CONTEXT
(
"validating struct member"
,
member
.
getName
());
KJ_CONTEXT
(
"validating struct member"
,
member
.
getName
());
validate
(
member
,
sawCodeOrder
,
sawOrdinal
,
dataSizeInBits
,
pointerCount
,
0
,
index
++
);
validate
(
member
,
sawCodeOrder
,
sawOrdinal
,
dataSizeInBits
,
pointerCount
,
0
,
members
.
size
(),
index
++
);
}
}
}
}
void
validateMemberName
(
kj
::
StringPtr
name
,
uint
unionIndex
,
uint
i
ndex
)
{
void
validateMemberName
(
kj
::
StringPtr
name
,
uint
scopeOrdinal
,
uint
adjustedI
ndex
)
{
bool
isNewName
=
members
.
insert
(
std
::
make_pair
(
bool
isNewName
=
members
.
insert
(
std
::
make_pair
(
std
::
pair
<
uint
,
Text
::
Reader
>
(
unionIndex
,
name
),
i
ndex
)).
second
;
std
::
pair
<
uint
,
Text
::
Reader
>
(
scopeOrdinal
,
name
),
adjustedI
ndex
)).
second
;
VALIDATE_SCHEMA
(
isNewName
,
"duplicate name"
,
name
);
VALIDATE_SCHEMA
(
isNewName
,
"duplicate name"
,
name
);
}
}
void
validate
(
const
schema
::
StructNode
::
Member
::
Reader
&
member
,
void
validate
(
const
schema
::
StructNode
::
Member
::
Reader
&
member
,
kj
::
ArrayPtr
<
bool
>
sawCodeOrder
,
kj
::
ArrayPtr
<
bool
>
sawOrdinal
,
kj
::
ArrayPtr
<
bool
>
sawCodeOrder
,
kj
::
ArrayPtr
<
bool
>
sawOrdinal
,
uint
dataSizeInBits
,
uint
pointerCount
,
uint
dataSizeInBits
,
uint
pointerCount
,
uint
unionIndex
,
uint
i
ndex
)
{
uint
scopeOrdinal
,
uint
scopeMemberCount
,
uint
adjustedI
ndex
)
{
validateMemberName
(
member
.
getName
(),
unionIndex
,
i
ndex
);
validateMemberName
(
member
.
getName
(),
scopeOrdinal
,
adjustedI
ndex
);
VALIDATE_SCHEMA
(
member
.
getCodeOrder
()
<
sawCodeOrder
.
size
()
&&
VALIDATE_SCHEMA
(
member
.
getCodeOrder
()
<
sawCodeOrder
.
size
()
&&
!
sawCodeOrder
[
member
.
getCodeOrder
()],
!
sawCodeOrder
[
member
.
getCodeOrder
()],
"Invalid codeOrder."
);
"Invalid codeOrder."
);
...
@@ -284,14 +285,17 @@ private:
...
@@ -284,14 +285,17 @@ private:
uMember
.
getBody
().
which
()
==
schema
::
StructNode
::
Member
::
Body
::
FIELD_MEMBER
,
uMember
.
getBody
().
which
()
==
schema
::
StructNode
::
Member
::
Body
::
FIELD_MEMBER
,
"Union members must be fields."
);
"Union members must be fields."
);
uint
subUnionIndex
;
uint
subScopeOrdinal
;
uint
indexAdjustment
;
if
(
member
.
getName
().
size
()
==
0
)
{
if
(
member
.
getName
().
size
()
==
0
)
{
subUnionIndex
=
unionIndex
;
subScopeOrdinal
=
scopeOrdinal
;
indexAdjustment
=
scopeMemberCount
;
}
else
{
}
else
{
subUnionIndex
=
index
+
1
;
subScopeOrdinal
=
member
.
getOrdinal
()
+
1
;
indexAdjustment
=
0
;
}
}
validate
(
uMember
,
uSawCodeOrder
,
sawOrdinal
,
dataSizeInBits
,
pointerCount
,
validate
(
uMember
,
uSawCodeOrder
,
sawOrdinal
,
dataSizeInBits
,
pointerCount
,
sub
UnionIndex
,
subIndex
++
);
sub
ScopeOrdinal
,
uMembers
.
size
(),
subIndex
++
+
indexAdjustment
);
}
}
// Union ordinal may match the ordinal of its first member, meaning it was unspecified in
// Union ordinal may match the ordinal of its first member, meaning it was unspecified in
...
...
c++/src/capnp/schema-test.c++
View file @
372612cd
...
@@ -274,6 +274,17 @@ TEST(Schema, UnnamedUnion) {
...
@@ -274,6 +274,17 @@ TEST(Schema, UnnamedUnion) {
StructSchema
schema
=
Schema
::
from
<
test
::
TestUnnamedUnion
>
();
StructSchema
schema
=
Schema
::
from
<
test
::
TestUnnamedUnion
>
();
EXPECT_TRUE
(
schema
.
findMemberByName
(
""
)
==
nullptr
);
EXPECT_TRUE
(
schema
.
findMemberByName
(
""
)
==
nullptr
);
KJ_IF_MAYBE
(
u
,
schema
.
getUnnamedUnion
())
{
EXPECT_TRUE
(
schema
.
getMemberByName
(
"foo"
)
==
u
->
getMemberByName
(
"foo"
));
EXPECT_TRUE
(
schema
.
getMemberByName
(
"bar"
)
==
u
->
getMemberByName
(
"bar"
));
EXPECT_TRUE
(
u
->
findMemberByName
(
"before"
)
==
nullptr
);
EXPECT_TRUE
(
u
->
findMemberByName
(
"after"
)
==
nullptr
);
EXPECT_TRUE
(
schema
.
findMemberByName
(
"before"
)
!=
nullptr
);
EXPECT_TRUE
(
schema
.
findMemberByName
(
"after"
)
!=
nullptr
);
}
else
{
ADD_FAILURE
()
<<
"getUnnamedUnion() should have returned non-null."
;
}
}
}
}
// namespace
}
// namespace
...
...
c++/src/capnp/schema.c++
View file @
372612cd
...
@@ -90,20 +90,74 @@ void Schema::requireUsableAs(const _::RawSchema* expected) const {
...
@@ -90,20 +90,74 @@ void Schema::requireUsableAs(const _::RawSchema* expected) const {
namespace
{
namespace
{
inline
StructSchema
::
MemberList
getUnionMembers
(
StructSchema
::
Member
m
)
{
return
m
.
asUnion
().
getMembers
();
}
inline
EnumSchema
::
EnumerantList
getUnionMembers
(
EnumSchema
::
Enumerant
)
{
KJ_FAIL_ASSERT
(
"MemberInfo for enum nonsensically expects unnamed unions."
);
}
inline
InterfaceSchema
::
MethodList
getUnionMembers
(
InterfaceSchema
::
Method
)
{
KJ_FAIL_ASSERT
(
"MemberInfo for interface nonsensically expects unnamed unions."
);
}
template
<
typename
List
>
auto
findUnnamedMemberOfScope
(
const
_
::
RawSchema
*
raw
,
uint
scopeOrdinal
,
List
&&
list
)
->
decltype
(
list
[
0
])
{
uint
lower
=
0
;
uint
upper
=
raw
->
memberCount
;
// Since the empty string sorts before all other strings, we're looking for the first member
// that has the expected scopeOrdinal.
while
(
lower
<
upper
)
{
uint
mid
=
(
lower
+
upper
)
/
2
;
const
_
::
RawSchema
::
MemberInfo
&
member
=
raw
->
membersByName
[
mid
];
if
(
member
.
scopeOrdinal
<
scopeOrdinal
)
{
lower
=
mid
+
1
;
}
else
{
upper
=
mid
;
}
}
const
_
::
RawSchema
::
MemberInfo
&
result
=
raw
->
membersByName
[
lower
];
KJ_DASSERT
(
lower
<
raw
->
memberCount
&&
list
[
result
.
index
].
getProto
().
getName
().
size
()
==
0
,
"Expected to find an unnamed union, but didn't. MemberInfo table must be broken."
);
return
list
[
result
.
index
];
}
template
<
typename
List
>
template
<
typename
List
>
auto
findSchemaMemberByName
(
const
_
::
RawSchema
*
raw
,
kj
::
StringPtr
name
,
auto
findSchemaMemberByName
(
const
_
::
RawSchema
*
raw
,
kj
::
StringPtr
name
,
uint
unionIndex
,
List
&&
list
)
uint
scopeOrdinal
,
List
&&
list
)
->
kj
::
Maybe
<
kj
::
Decay
<
decltype
(
list
[
0
])
>
>
{
->
kj
::
Maybe
<
decltype
(
list
[
0
])
>
{
uint
lower
=
0
;
uint
lower
=
0
;
uint
upper
=
raw
->
memberCount
;
uint
upper
=
raw
->
memberCount
;
List
unnamedUnionMembers
;
while
(
lower
<
upper
)
{
while
(
lower
<
upper
)
{
uint
mid
=
(
lower
+
upper
)
/
2
;
uint
mid
=
(
lower
+
upper
)
/
2
;
const
_
::
RawSchema
::
MemberInfo
&
member
=
raw
->
membersByName
[
mid
];
const
_
::
RawSchema
::
MemberInfo
&
member
=
raw
->
membersByName
[
mid
];
if
(
member
.
unionIndex
==
unionIndex
)
{
if
(
member
.
scopeOrdinal
==
scopeOrdinal
)
{
auto
candidate
=
list
[
member
.
index
];
decltype
(
list
[
member
.
index
])
candidate
;
if
(
member
.
index
<
list
.
size
())
{
candidate
=
list
[
member
.
index
];
}
else
{
// This looks like it's a member of an unnamed union.
if
(
unnamedUnionMembers
.
size
()
==
0
)
{
// We haven't expanded the unnamed union yet. We have to find it. It should be the very
// first item with the expected ordinal.
unnamedUnionMembers
=
getUnionMembers
(
findUnnamedMemberOfScope
(
raw
,
scopeOrdinal
,
list
));
}
uint
uIndex
=
member
.
index
-
list
.
size
();
KJ_DASSERT
(
uIndex
<
unnamedUnionMembers
.
size
());
candidate
=
unnamedUnionMembers
[
uIndex
];
}
kj
::
StringPtr
candidateName
=
candidate
.
getProto
().
getName
();
kj
::
StringPtr
candidateName
=
candidate
.
getProto
().
getName
();
if
(
candidateName
==
name
)
{
if
(
candidateName
==
name
)
{
return
candidate
;
return
candidate
;
...
@@ -112,7 +166,7 @@ auto findSchemaMemberByName(const _::RawSchema* raw, kj::StringPtr name,
...
@@ -112,7 +166,7 @@ auto findSchemaMemberByName(const _::RawSchema* raw, kj::StringPtr name,
}
else
{
}
else
{
upper
=
mid
;
upper
=
mid
;
}
}
}
else
if
(
member
.
unionIndex
<
unionIndex
)
{
}
else
if
(
member
.
scopeOrdinal
<
scopeOrdinal
)
{
lower
=
mid
+
1
;
lower
=
mid
+
1
;
}
else
{
}
else
{
upper
=
mid
;
upper
=
mid
;
...
@@ -208,7 +262,24 @@ StructSchema::MemberList StructSchema::Union::getMembers() const {
...
@@ -208,7 +262,24 @@ StructSchema::MemberList StructSchema::Union::getMembers() const {
}
}
kj
::
Maybe
<
StructSchema
::
Member
>
StructSchema
::
Union
::
findMemberByName
(
kj
::
StringPtr
name
)
const
{
kj
::
Maybe
<
StructSchema
::
Member
>
StructSchema
::
Union
::
findMemberByName
(
kj
::
StringPtr
name
)
const
{
return
findSchemaMemberByName
(
parent
.
raw
,
name
,
index
+
1
,
getMembers
());
auto
proto
=
getProto
();
if
(
proto
.
getName
().
size
()
==
0
)
{
// Unnamed union, so we have to search the parent scope.
KJ_IF_MAYBE
(
result
,
getContainingStruct
().
findMemberByName
(
name
))
{
KJ_IF_MAYBE
(
containingUnion
,
result
->
getContainingUnion
())
{
KJ_ASSERT
(
*
containingUnion
==
*
this
,
"Found a member of some other union? But there can only be one unnamed union!"
);
return
*
result
;
}
else
{
// Oops, we found a member of the parent scope that is *not* also a member of the union.
return
nullptr
;
}
}
else
{
return
nullptr
;
}
}
else
{
return
findSchemaMemberByName
(
parent
.
raw
,
name
,
getProto
().
getOrdinal
()
+
1
,
getMembers
());
}
}
}
StructSchema
::
Member
StructSchema
::
Union
::
getMemberByName
(
kj
::
StringPtr
name
)
const
{
StructSchema
::
Member
StructSchema
::
Union
::
getMemberByName
(
kj
::
StringPtr
name
)
const
{
...
@@ -226,7 +297,7 @@ StructSchema::MemberList StructSchema::Group::getMembers() const {
...
@@ -226,7 +297,7 @@ StructSchema::MemberList StructSchema::Group::getMembers() const {
#if 0
#if 0
// TODO(soon): Implement correctly. Requires some changes to lookup table format.
// TODO(soon): Implement correctly. Requires some changes to lookup table format.
kj::Maybe<StructSchema::Member> StructSchema::Group::findMemberByName(kj::StringPtr name) const {
kj::Maybe<StructSchema::Member> StructSchema::Group::findMemberByName(kj::StringPtr name) const {
return findSchemaMemberByName(parent.raw, name,
index
+ 1, getMembers());
return findSchemaMemberByName(parent.raw, name,
getProto().getOrdinal()
+ 1, getMembers());
}
}
StructSchema::Member StructSchema::Group::getMemberByName(kj::StringPtr name) const {
StructSchema::Member StructSchema::Group::getMemberByName(kj::StringPtr name) const {
...
...
c++/src/capnp/schema.h
View file @
372612cd
...
@@ -254,6 +254,8 @@ private:
...
@@ -254,6 +254,8 @@ private:
class
StructSchema
::
MemberList
{
class
StructSchema
::
MemberList
{
public
:
public
:
MemberList
()
=
default
;
// empty list
inline
uint
size
()
const
{
return
list
.
size
();
}
inline
uint
size
()
const
{
return
list
.
size
();
}
inline
Member
operator
[](
uint
index
)
const
{
return
Member
(
parent
,
unionIndex
,
index
,
list
[
index
]);
}
inline
Member
operator
[](
uint
index
)
const
{
return
Member
(
parent
,
unionIndex
,
index
,
list
[
index
]);
}
...
@@ -323,6 +325,8 @@ private:
...
@@ -323,6 +325,8 @@ private:
class
EnumSchema
::
EnumerantList
{
class
EnumSchema
::
EnumerantList
{
public
:
public
:
EnumerantList
()
=
default
;
// empty list
inline
uint
size
()
const
{
return
list
.
size
();
}
inline
uint
size
()
const
{
return
list
.
size
();
}
inline
Enumerant
operator
[](
uint
index
)
const
{
return
Enumerant
(
parent
,
index
,
list
[
index
]);
}
inline
Enumerant
operator
[](
uint
index
)
const
{
return
Enumerant
(
parent
,
index
,
list
[
index
]);
}
...
@@ -391,6 +395,8 @@ private:
...
@@ -391,6 +395,8 @@ private:
class
InterfaceSchema
::
MethodList
{
class
InterfaceSchema
::
MethodList
{
public
:
public
:
MethodList
()
=
default
;
// empty list
inline
uint
size
()
const
{
return
list
.
size
();
}
inline
uint
size
()
const
{
return
list
.
size
();
}
inline
Method
operator
[](
uint
index
)
const
{
return
Method
(
parent
,
index
,
list
[
index
]);
}
inline
Method
operator
[](
uint
index
)
const
{
return
Method
(
parent
,
index
,
list
[
index
]);
}
...
...
c++/src/capnp/stringify-test.c++
View file @
372612cd
...
@@ -359,6 +359,34 @@ TEST(Stringify, Unions) {
...
@@ -359,6 +359,34 @@ TEST(Stringify, Unions) {
EXPECT_EQ
(
"u3f0s64(123456789012345678)"
,
kj
::
str
(
root
.
getUnion3
()));
EXPECT_EQ
(
"u3f0s64(123456789012345678)"
,
kj
::
str
(
root
.
getUnion3
()));
}
}
TEST
(
Stringify
,
UnnamedUnions
)
{
MallocMessageBuilder
builder
;
auto
root
=
builder
.
initRoot
<
test
::
TestUnnamedUnion
>
();
root
.
setBar
(
123
);
EXPECT_EQ
(
"(bar(123))"
,
kj
::
str
(
root
));
EXPECT_EQ
(
"(bar(123))"
,
prettyPrint
(
root
).
flatten
());
root
.
setAfter
(
"foooooooooooooooooooooooooooooooo"
);
EXPECT_EQ
(
"(bar(123), after =
\"
foooooooooooooooooooooooooooooooo
\"
)"
,
kj
::
str
(
root
));
EXPECT_EQ
(
"( bar(123),
\n
"
" after =
\"
foooooooooooooooooooooooooooooooo
\"
)"
,
prettyPrint
(
root
).
flatten
());
root
.
setBefore
(
"before"
);
EXPECT_EQ
(
"(before =
\"
before
\"
, bar(123), "
"after =
\"
foooooooooooooooooooooooooooooooo
\"
)"
,
kj
::
str
(
root
));
EXPECT_EQ
(
"( before =
\"
before
\"
,
\n
"
" bar(123),
\n
"
" after =
\"
foooooooooooooooooooooooooooooooo
\"
)"
,
prettyPrint
(
root
).
flatten
());
}
TEST
(
Stringify
,
StructUnions
)
{
TEST
(
Stringify
,
StructUnions
)
{
MallocMessageBuilder
builder
;
MallocMessageBuilder
builder
;
auto
root
=
builder
.
initRoot
<
test
::
TestStructUnion
>
();
auto
root
=
builder
.
initRoot
<
test
::
TestStructUnion
>
();
...
...
c++/src/capnp/stringify.c++
View file @
372612cd
...
@@ -197,9 +197,16 @@ static kj::StringTree print(const DynamicValue::Reader& value,
...
@@ -197,9 +197,16 @@ static kj::StringTree print(const DynamicValue::Reader& value,
kj
::
Vector
<
kj
::
StringTree
>
printedMembers
(
memberSchemas
.
size
());
kj
::
Vector
<
kj
::
StringTree
>
printedMembers
(
memberSchemas
.
size
());
for
(
auto
member
:
memberSchemas
)
{
for
(
auto
member
:
memberSchemas
)
{
if
(
structValue
.
has
(
member
))
{
if
(
structValue
.
has
(
member
))
{
printedMembers
.
add
(
kj
::
strTree
(
auto
name
=
member
.
getProto
().
getName
();
member
.
getProto
().
getName
(),
" = "
,
if
(
name
.
size
()
==
0
)
{
print
(
structValue
.
get
(
member
),
whichMemberType
(
member
),
indent
.
next
(),
PREFIXED
)));
// Unnamed union. Just print the content.
printedMembers
.
add
(
kj
::
strTree
(
print
(
structValue
.
get
(
member
),
whichMemberType
(
member
),
indent
.
next
(),
BARE
)));
}
else
{
printedMembers
.
add
(
kj
::
strTree
(
name
,
" = "
,
print
(
structValue
.
get
(
member
),
whichMemberType
(
member
),
indent
.
next
(),
PREFIXED
)));
}
}
}
}
}
...
...
c++/src/capnp/test.capnp
View file @
372612cd
...
@@ -341,8 +341,8 @@ struct TestListDefaults {
...
@@ -341,8 +341,8 @@ struct TestListDefaults {
}
}
struct TestLateUnion {
struct TestLateUnion {
# Test what happens if the unions are
the first ordinals in the struct. At one point this wa
s
# Test what happens if the unions are
not the first ordinals in the struct. At one point thi
s
# broken for the dynamic API.
#
was
broken for the dynamic API.
foo @0 :Int32;
foo @0 :Int32;
bar @1 :Text;
bar @1 :Text;
...
@@ -385,12 +385,12 @@ struct TestStructUnion {
...
@@ -385,12 +385,12 @@ struct TestStructUnion {
}
}
struct TestUnnamedUnion {
struct TestUnnamedUnion {
before @0 :
Void
;
before @0 :
Text
;
union {
union {
foo @1 :UInt16;
foo @1 :UInt16;
bar @2 :UInt32;
bar @2 :UInt32;
}
}
after @3 :
Void
;
after @3 :
Text
;
}
}
c++/src/kj/common.h
View file @
372612cd
...
@@ -600,6 +600,10 @@ inline T* readMaybe(Maybe<T&>&& maybe) { return maybe.ptr; }
...
@@ -600,6 +600,10 @@ inline T* readMaybe(Maybe<T&>&& maybe) { return maybe.ptr; }
template
<
typename
T
>
template
<
typename
T
>
inline
T
*
readMaybe
(
const
Maybe
<
T
&>&
maybe
)
{
return
maybe
.
ptr
;
}
inline
T
*
readMaybe
(
const
Maybe
<
T
&>&
maybe
)
{
return
maybe
.
ptr
;
}
template
<
typename
T
>
inline
T
*
readMaybe
(
T
*
ptr
)
{
return
ptr
;
}
// Allow KJ_IF_MAYBE to work on regular pointers.
}
// namespace _ (private)
}
// namespace _ (private)
#define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp))
#define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp))
...
...
c++/src/kj/debug.h
View file @
372612cd
...
@@ -147,6 +147,18 @@ namespace kj {
...
@@ -147,6 +147,18 @@ namespace kj {
::kj::_::Debug::ContextImpl<decltype(KJ_UNIQUE_NAME(_kjContextFunc))> \
::kj::_::Debug::ContextImpl<decltype(KJ_UNIQUE_NAME(_kjContextFunc))> \
KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc))
KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc))
#define _kJ_NONNULL(nature, value, ...) \
({ \
auto result = ::kj::_::readMaybe(value); \
if (KJ_UNLIKELY(!result)) { \
::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Nature::nature, 0, \
#value " != nullptr", #__VA_ARGS__, ##__VA_ARGS__).fatal(); \
} \
*result; \
})
#define KJ_ASSERT_NONNULL(value, ...) _kJ_NONNULL(LOCAL_BUG, value, ##__VA_ARGS__)
#define KJ_REQUIRE_NONNULL(value, ...) _kJ_NONNULL(PRECONDITION, value, ##__VA_ARGS__)
#ifdef NDEBUG
#ifdef NDEBUG
#define KJ_DLOG(...) do {} while (false)
#define KJ_DLOG(...) do {} while (false)
#define KJ_DASSERT(...) do {} while (false)
#define KJ_DASSERT(...) do {} while (false)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment