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
77d91c78
Commit
77d91c78
authored
Aug 22, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Zero out group on init. Important when the group is in a union.
parent
cfc10236
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
401 additions
and
6 deletions
+401
-6
capnpc-c++.c++
c++/src/capnp/compiler/capnpc-c++.c++
+220
-2
grammar.capnp.h
c++/src/capnp/compiler/grammar.capnp.h
+34
-0
lexer.capnp.h
c++/src/capnp/compiler/lexer.capnp.h
+2
-0
encoding-test.c++
c++/src/capnp/encoding-test.c++
+66
-0
layout.c++
c++/src/capnp/layout.c++
+5
-0
layout.h
c++/src/capnp/layout.h
+3
-0
schema.capnp.h
c++/src/capnp/schema.capnp.h
+29
-0
test.capnp
c++/src/capnp/test.capnp
+42
-4
No files found.
c++/src/capnp/compiler/capnpc-c++.c++
View file @
77d91c78
...
...
@@ -237,6 +237,210 @@ private:
KJ_UNREACHABLE
;
}
// -----------------------------------------------------------------
// Code to deal with "slots" -- determines what to zero out when we clear a group.
static
uint
typeSizeBits
(
schema
::
Type
::
Which
whichType
)
{
switch
(
whichType
)
{
case
schema
:
:
Type
::
BOOL
:
return
1
;
case
schema
:
:
Type
::
INT8
:
return
8
;
case
schema
:
:
Type
::
INT16
:
return
16
;
case
schema
:
:
Type
::
INT32
:
return
32
;
case
schema
:
:
Type
::
INT64
:
return
64
;
case
schema
:
:
Type
::
UINT8
:
return
8
;
case
schema
:
:
Type
::
UINT16
:
return
16
;
case
schema
:
:
Type
::
UINT32
:
return
32
;
case
schema
:
:
Type
::
UINT64
:
return
64
;
case
schema
:
:
Type
::
FLOAT32
:
return
32
;
case
schema
:
:
Type
::
FLOAT64
:
return
64
;
case
schema
:
:
Type
::
ENUM
:
return
16
;
case
schema
:
:
Type
::
VOID
:
case
schema
:
:
Type
::
TEXT
:
case
schema
:
:
Type
::
DATA
:
case
schema
:
:
Type
::
LIST
:
case
schema
:
:
Type
::
STRUCT
:
case
schema
:
:
Type
::
INTERFACE
:
case
schema
:
:
Type
::
OBJECT
:
KJ_FAIL_REQUIRE
(
"Should only be called for data types."
);
}
KJ_UNREACHABLE
;
}
enum
class
Section
{
NONE
,
DATA
,
POINTERS
};
static
Section
sectionFor
(
schema
::
Type
::
Which
whichType
)
{
switch
(
whichType
)
{
case
schema
:
:
Type
::
VOID
:
return
Section
::
NONE
;
case
schema
:
:
Type
::
BOOL
:
case
schema
:
:
Type
::
INT8
:
case
schema
:
:
Type
::
INT16
:
case
schema
:
:
Type
::
INT32
:
case
schema
:
:
Type
::
INT64
:
case
schema
:
:
Type
::
UINT8
:
case
schema
:
:
Type
::
UINT16
:
case
schema
:
:
Type
::
UINT32
:
case
schema
:
:
Type
::
UINT64
:
case
schema
:
:
Type
::
FLOAT32
:
case
schema
:
:
Type
::
FLOAT64
:
case
schema
:
:
Type
::
ENUM
:
return
Section
::
DATA
;
case
schema
:
:
Type
::
TEXT
:
case
schema
:
:
Type
::
DATA
:
case
schema
:
:
Type
::
LIST
:
case
schema
:
:
Type
::
STRUCT
:
case
schema
:
:
Type
::
INTERFACE
:
case
schema
:
:
Type
::
OBJECT
:
return
Section
::
POINTERS
;
}
KJ_UNREACHABLE
;
}
static
kj
::
StringPtr
maskType
(
schema
::
Type
::
Which
whichType
)
{
switch
(
whichType
)
{
case
schema
:
:
Type
::
BOOL
:
return
"bool"
;
case
schema
:
:
Type
::
INT8
:
return
" ::uint8_t"
;
case
schema
:
:
Type
::
INT16
:
return
" ::uint16_t"
;
case
schema
:
:
Type
::
INT32
:
return
" ::uint32_t"
;
case
schema
:
:
Type
::
INT64
:
return
" ::uint64_t"
;
case
schema
:
:
Type
::
UINT8
:
return
" ::uint8_t"
;
case
schema
:
:
Type
::
UINT16
:
return
" ::uint16_t"
;
case
schema
:
:
Type
::
UINT32
:
return
" ::uint32_t"
;
case
schema
:
:
Type
::
UINT64
:
return
" ::uint64_t"
;
case
schema
:
:
Type
::
FLOAT32
:
return
" ::uint32_t"
;
case
schema
:
:
Type
::
FLOAT64
:
return
" ::uint64_t"
;
case
schema
:
:
Type
::
ENUM
:
return
" ::uint16_t"
;
case
schema
:
:
Type
::
VOID
:
case
schema
:
:
Type
::
TEXT
:
case
schema
:
:
Type
::
DATA
:
case
schema
:
:
Type
::
LIST
:
case
schema
:
:
Type
::
STRUCT
:
case
schema
:
:
Type
::
INTERFACE
:
case
schema
:
:
Type
::
OBJECT
:
KJ_FAIL_REQUIRE
(
"Should only be called for data types."
);
}
KJ_UNREACHABLE
;
}
struct
Slot
{
schema
::
Type
::
Which
whichType
;
uint
offset
;
bool
isSupersetOf
(
Slot
other
)
const
{
auto
section
=
sectionFor
(
whichType
);
if
(
section
!=
sectionFor
(
other
.
whichType
))
return
false
;
switch
(
section
)
{
case
Section
:
:
NONE
:
return
true
;
// all voids overlap
case
Section
:
:
DATA
:
{
auto
bits
=
typeSizeBits
(
whichType
);
auto
start
=
offset
*
bits
;
auto
otherBits
=
typeSizeBits
(
other
.
whichType
);
auto
otherStart
=
other
.
offset
*
otherBits
;
return
start
<=
otherStart
&&
otherStart
+
otherBits
<=
start
+
bits
;
}
case
Section
:
:
POINTERS
:
return
offset
==
other
.
offset
;
}
KJ_UNREACHABLE
;
}
bool
operator
<
(
Slot
other
)
const
{
// Sort by section, then start position, and finally size.
auto
section
=
sectionFor
(
whichType
);
auto
otherSection
=
sectionFor
(
other
.
whichType
);
if
(
section
<
otherSection
)
{
return
true
;
}
else
if
(
section
>
otherSection
)
{
return
false
;
}
switch
(
section
)
{
case
Section
:
:
NONE
:
return
false
;
case
Section
:
:
DATA
:
{
auto
bits
=
typeSizeBits
(
whichType
);
auto
start
=
offset
*
bits
;
auto
otherBits
=
typeSizeBits
(
other
.
whichType
);
auto
otherStart
=
other
.
offset
*
otherBits
;
if
(
start
<
otherStart
)
{
return
true
;
}
else
if
(
start
>
otherStart
)
{
return
false
;
}
// Sort larger sizes before smaller.
return
bits
>
otherBits
;
}
case
Section
:
:
POINTERS
:
return
offset
<
other
.
offset
;
}
KJ_UNREACHABLE
;
}
};
void
getSlots
(
StructSchema
schema
,
kj
::
Vector
<
Slot
>&
slots
)
{
auto
structProto
=
schema
.
getProto
().
getStruct
();
if
(
structProto
.
getDiscriminantCount
()
>
0
)
{
slots
.
add
(
Slot
{
schema
::
Type
::
UINT16
,
structProto
.
getDiscriminantOffset
()
});
}
for
(
auto
field
:
schema
.
getFields
())
{
auto
proto
=
field
.
getProto
();
switch
(
proto
.
which
())
{
case
schema
:
:
Field
::
NON_GROUP
:
{
auto
nonGroup
=
proto
.
getNonGroup
();
slots
.
add
(
Slot
{
nonGroup
.
getType
().
which
(),
nonGroup
.
getOffset
()
});
break
;
}
case
schema
:
:
Field
::
GROUP
:
getSlots
(
schema
.
getDependency
(
proto
.
getGroup
()).
asStruct
(),
slots
);
break
;
}
}
}
kj
::
Array
<
Slot
>
getSortedSlots
(
StructSchema
schema
)
{
// Get a representation of all of the field locations owned by this schema, e.g. so that they
// can be zero'd out.
kj
::
Vector
<
Slot
>
slots
(
schema
.
getFields
().
size
());
getSlots
(
schema
,
slots
);
std
::
sort
(
slots
.
begin
(),
slots
.
end
());
kj
::
Vector
<
Slot
>
result
(
slots
.
size
());
// All void slots are redundant, and they sort towards the front of the list. By starting out
// with `prevSlot` = void, we will end up skipping them all, which is what we want.
Slot
prevSlot
=
{
schema
::
Type
::
VOID
,
0
};
for
(
auto
slot
:
slots
)
{
if
(
prevSlot
.
isSupersetOf
(
slot
))
{
// This slot is redundant as prevSlot is a superset of it.
continue
;
}
// Since all sizes are power-of-two, if two slots overlap at all, one must be a superset of
// the other. Since we sort slots by starting position, we know that the only way `slot`
// could be a superset of `prevSlot` is if they have the same starting position. However,
// since we sort slots with the same starting position by descending size, this is not
// possible.
KJ_DASSERT
(
!
slot
.
isSupersetOf
(
prevSlot
));
result
.
add
(
slot
);
prevSlot
=
slot
;
}
return
result
.
releaseAsArray
();
}
// -----------------------------------------------------------------
struct
DiscriminantChecks
{
...
...
@@ -293,7 +497,8 @@ private:
// Continue below.
break
;
case
schema
:
:
Field
::
GROUP
:
case
schema
:
:
Field
::
GROUP
:
{
auto
slots
=
getSortedSlots
(
schemaLoader
.
get
(
field
.
getProto
().
getGroup
()).
asStruct
());
return
FieldText
{
kj
::
strTree
(
" inline "
,
titleCase
,
"::Reader get"
,
titleCase
,
"() const;
\n
"
...
...
@@ -315,10 +520,23 @@ private:
"}
\n
"
"inline "
,
scope
,
titleCase
,
"::Builder "
,
scope
,
"Builder::init"
,
titleCase
,
"() {
\n
"
,
unionDiscrim
.
set
,
// TODO(soon): Zero out fields.
KJ_MAP
(
slots
,
slot
)
{
switch
(
sectionFor
(
slot
.
whichType
))
{
case
Section
:
:
NONE
:
return
kj
::
strTree
();
case
Section
:
:
DATA
:
return
kj
::
strTree
(
" _builder.setDataField<"
,
maskType
(
slot
.
whichType
),
">("
,
slot
.
offset
,
" * ::capnp::ELEMENTS, 0);
\n
"
);
case
Section
:
:
POINTERS
:
return
kj
::
strTree
(
" _builder.clearPointer("
,
slot
.
offset
,
" * ::capnp::POINTERS);
\n
"
);
}
},
" return "
,
scope
,
titleCase
,
"::Builder(_builder);
\n
"
"}
\n
"
)
};
}
}
auto
nonGroup
=
proto
.
getNonGroup
();
...
...
c++/src/capnp/compiler/grammar.capnp.h
View file @
77d91c78
...
...
@@ -2536,6 +2536,8 @@ inline DeclName::Base::Builder DeclName::Builder::getBase() {
return
DeclName
::
Base
::
Builder
(
_builder
);
}
inline
DeclName
::
Base
::
Builder
DeclName
::
Builder
::
initBase
()
{
_builder
.
setDataField
<
::
uint16_t
>
(
0
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
0
*
::
capnp
::
POINTERS
);
return
DeclName
::
Base
::
Builder
(
_builder
);
}
inline
bool
DeclName
::
Reader
::
hasMemberPath
()
const
{
...
...
@@ -3344,6 +3346,8 @@ inline Declaration::Id::Builder Declaration::Builder::getId() {
return
Declaration
::
Id
::
Builder
(
_builder
);
}
inline
Declaration
::
Id
::
Builder
Declaration
::
Builder
::
initId
()
{
_builder
.
setDataField
<
::
uint16_t
>
(
0
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
1
*
::
capnp
::
POINTERS
);
return
Declaration
::
Id
::
Builder
(
_builder
);
}
inline
bool
Declaration
::
Reader
::
hasNestedDecls
()
const
{
...
...
@@ -3528,6 +3532,7 @@ inline Declaration::Using::Builder Declaration::Builder::getUsing() {
inline
Declaration
::
Using
::
Builder
Declaration
::
Builder
::
initUsing
()
{
_builder
.
setDataField
<
Declaration
::
Which
>
(
1
*
::
capnp
::
ELEMENTS
,
Declaration
::
USING
);
_builder
.
clearPointer
(
5
*
::
capnp
::
POINTERS
);
return
Declaration
::
Using
::
Builder
(
_builder
);
}
inline
Declaration
::
Const
::
Reader
Declaration
::
Reader
::
getConst
()
const
{
...
...
@@ -3543,6 +3548,8 @@ inline Declaration::Const::Builder Declaration::Builder::getConst() {
inline
Declaration
::
Const
::
Builder
Declaration
::
Builder
::
initConst
()
{
_builder
.
setDataField
<
Declaration
::
Which
>
(
1
*
::
capnp
::
ELEMENTS
,
Declaration
::
CONST
);
_builder
.
clearPointer
(
5
*
::
capnp
::
POINTERS
);
_builder
.
clearPointer
(
6
*
::
capnp
::
POINTERS
);
return
Declaration
::
Const
::
Builder
(
_builder
);
}
inline
bool
Declaration
::
Reader
::
hasEnum
()
const
{
...
...
@@ -3651,6 +3658,9 @@ inline Declaration::Field::Builder Declaration::Builder::getField() {
inline
Declaration
::
Field
::
Builder
Declaration
::
Builder
::
initField
()
{
_builder
.
setDataField
<
Declaration
::
Which
>
(
1
*
::
capnp
::
ELEMENTS
,
Declaration
::
FIELD
);
_builder
.
setDataField
<
::
uint16_t
>
(
6
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
5
*
::
capnp
::
POINTERS
);
_builder
.
clearPointer
(
6
*
::
capnp
::
POINTERS
);
return
Declaration
::
Field
::
Builder
(
_builder
);
}
inline
bool
Declaration
::
Reader
::
hasUnion
()
const
{
...
...
@@ -3759,6 +3769,9 @@ inline Declaration::Method::Builder Declaration::Builder::getMethod() {
inline
Declaration
::
Method
::
Builder
Declaration
::
Builder
::
initMethod
()
{
_builder
.
setDataField
<
Declaration
::
Which
>
(
1
*
::
capnp
::
ELEMENTS
,
Declaration
::
METHOD
);
_builder
.
setDataField
<
::
uint16_t
>
(
6
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
5
*
::
capnp
::
POINTERS
);
_builder
.
clearPointer
(
6
*
::
capnp
::
POINTERS
);
return
Declaration
::
Method
::
Builder
(
_builder
);
}
inline
Declaration
::
Annotation
::
Reader
Declaration
::
Reader
::
getAnnotation
()
const
{
...
...
@@ -3774,6 +3787,19 @@ inline Declaration::Annotation::Builder Declaration::Builder::getAnnotation() {
inline
Declaration
::
Annotation
::
Builder
Declaration
::
Builder
::
initAnnotation
()
{
_builder
.
setDataField
<
Declaration
::
Which
>
(
1
*
::
capnp
::
ELEMENTS
,
Declaration
::
ANNOTATION
);
_builder
.
setDataField
<
bool
>
(
96
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
97
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
98
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
99
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
100
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
101
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
102
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
103
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
104
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
105
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
106
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
107
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
5
*
::
capnp
::
POINTERS
);
return
Declaration
::
Annotation
::
Builder
(
_builder
);
}
inline
bool
Declaration
::
Reader
::
hasNakedId
()
const
{
...
...
@@ -4407,6 +4433,8 @@ inline Declaration::AnnotationApplication::Value::Builder Declaration::Annotatio
return
Declaration
::
AnnotationApplication
::
Value
::
Builder
(
_builder
);
}
inline
Declaration
::
AnnotationApplication
::
Value
::
Builder
Declaration
::
AnnotationApplication
::
Builder
::
initValue
()
{
_builder
.
setDataField
<
::
uint16_t
>
(
0
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
1
*
::
capnp
::
POINTERS
);
return
Declaration
::
AnnotationApplication
::
Value
::
Builder
(
_builder
);
}
inline
Declaration
::
AnnotationApplication
::
Value
::
Which
Declaration
::
AnnotationApplication
::
Value
::
Reader
::
which
()
const
{
...
...
@@ -4598,6 +4626,8 @@ inline Declaration::Param::DefaultValue::Builder Declaration::Param::Builder::ge
return
Declaration
::
Param
::
DefaultValue
::
Builder
(
_builder
);
}
inline
Declaration
::
Param
::
DefaultValue
::
Builder
Declaration
::
Param
::
Builder
::
initDefaultValue
()
{
_builder
.
setDataField
<
::
uint16_t
>
(
0
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
3
*
::
capnp
::
POINTERS
);
return
Declaration
::
Param
::
DefaultValue
::
Builder
(
_builder
);
}
inline
Declaration
::
Param
::
DefaultValue
::
Which
Declaration
::
Param
::
DefaultValue
::
Reader
::
which
()
const
{
...
...
@@ -4955,6 +4985,8 @@ inline Declaration::Field::DefaultValue::Builder Declaration::Field::Builder::ge
return
Declaration
::
Field
::
DefaultValue
::
Builder
(
_builder
);
}
inline
Declaration
::
Field
::
DefaultValue
::
Builder
Declaration
::
Field
::
Builder
::
initDefaultValue
()
{
_builder
.
setDataField
<
::
uint16_t
>
(
6
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
6
*
::
capnp
::
POINTERS
);
return
Declaration
::
Field
::
DefaultValue
::
Builder
(
_builder
);
}
inline
Declaration
::
Field
::
DefaultValue
::
Which
Declaration
::
Field
::
DefaultValue
::
Reader
::
which
()
const
{
...
...
@@ -5082,6 +5114,8 @@ inline Declaration::Method::ReturnType::Builder Declaration::Method::Builder::ge
return
Declaration
::
Method
::
ReturnType
::
Builder
(
_builder
);
}
inline
Declaration
::
Method
::
ReturnType
::
Builder
Declaration
::
Method
::
Builder
::
initReturnType
()
{
_builder
.
setDataField
<
::
uint16_t
>
(
6
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
6
*
::
capnp
::
POINTERS
);
return
Declaration
::
Method
::
ReturnType
::
Builder
(
_builder
);
}
inline
Declaration
::
Method
::
ReturnType
::
Which
Declaration
::
Method
::
ReturnType
::
Reader
::
which
()
const
{
...
...
c++/src/capnp/compiler/lexer.capnp.h
View file @
77d91c78
...
...
@@ -918,6 +918,8 @@ inline Statement::Block::Builder Statement::Builder::getBlock() {
return
Statement
::
Block
::
Builder
(
_builder
);
}
inline
Statement
::
Block
::
Builder
Statement
::
Builder
::
initBlock
()
{
_builder
.
setDataField
<
::
uint16_t
>
(
0
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
1
*
::
capnp
::
POINTERS
);
return
Statement
::
Block
::
Builder
(
_builder
);
}
inline
bool
Statement
::
Reader
::
hasDocComment
()
const
{
...
...
c++/src/capnp/encoding-test.c++
View file @
77d91c78
...
...
@@ -434,6 +434,72 @@ TEST(Encoding, Groups) {
}
}
TEST
(
Encoding
,
InterleavedGroups
)
{
MallocMessageBuilder
builder
;
auto
root
=
builder
.
initRoot
<
test
::
TestInterleavedGroups
>
();
// Init both groups to different values.
{
auto
group
=
root
.
getGroup1
();
group
.
setFoo
(
12345678u
);
group
.
setBar
(
123456789012345llu
);
auto
corge
=
group
.
initCorge
();
corge
.
setGrault
(
987654321098765llu
);
corge
.
setGarply
(
12345u
);
corge
.
setPlugh
(
"plugh"
);
corge
.
setXyzzy
(
"xyzzy"
);
group
.
setWaldo
(
"waldo"
);
}
{
auto
group
=
root
.
getGroup2
();
group
.
setFoo
(
23456789u
);
group
.
setBar
(
234567890123456llu
);
auto
corge
=
group
.
initCorge
();
corge
.
setGrault
(
876543210987654llu
);
corge
.
setGarply
(
23456u
);
corge
.
setPlugh
(
"hgulp"
);
corge
.
setXyzzy
(
"yzzyx"
);
group
.
setWaldo
(
"odlaw"
);
}
// Check group1 is still set correctly.
{
auto
group
=
root
.
asReader
().
getGroup1
();
EXPECT_EQ
(
12345678u
,
group
.
getFoo
());
EXPECT_EQ
(
123456789012345llu
,
group
.
getBar
());
auto
corge
=
group
.
getCorge
();
EXPECT_EQ
(
987654321098765llu
,
corge
.
getGrault
());
EXPECT_EQ
(
12345u
,
corge
.
getGarply
());
EXPECT_EQ
(
"plugh"
,
corge
.
getPlugh
());
EXPECT_EQ
(
"xyzzy"
,
corge
.
getXyzzy
());
EXPECT_EQ
(
"waldo"
,
group
.
getWaldo
());
}
// Zero out group 1 and see if it is zero'd.
{
auto
group
=
root
.
initGroup1
().
asReader
();
EXPECT_EQ
(
0u
,
group
.
getFoo
());
EXPECT_EQ
(
0u
,
group
.
getBar
());
EXPECT_EQ
(
test
::
TestInterleavedGroups
::
Group1
::
QUX
,
group
.
which
());
EXPECT_EQ
(
0u
,
group
.
getQux
());
EXPECT_FALSE
(
group
.
hasWaldo
());
}
// Group 2 should not have been touched.
{
auto
group
=
root
.
asReader
().
getGroup2
();
EXPECT_EQ
(
23456789u
,
group
.
getFoo
());
EXPECT_EQ
(
234567890123456llu
,
group
.
getBar
());
auto
corge
=
group
.
getCorge
();
EXPECT_EQ
(
876543210987654llu
,
corge
.
getGrault
());
EXPECT_EQ
(
23456u
,
corge
.
getGarply
());
EXPECT_EQ
(
"hgulp"
,
corge
.
getPlugh
());
EXPECT_EQ
(
"yzzyx"
,
corge
.
getXyzzy
());
EXPECT_EQ
(
"odlaw"
,
group
.
getWaldo
());
}
}
TEST
(
Encoding
,
UnionDefault
)
{
MallocMessageBuilder
builder
;
TestUnionDefaults
::
Reader
reader
=
builder
.
getRoot
<
TestUnionDefaults
>
().
asReader
();
...
...
c++/src/capnp/layout.c++
View file @
77d91c78
...
...
@@ -2143,6 +2143,11 @@ OrphanBuilder StructBuilder::disown(WirePointerCount ptrIndex) {
return
WireHelpers
::
disown
(
segment
,
pointers
+
ptrIndex
);
}
void
StructBuilder
::
clearPointer
(
WirePointerCount
ptrIndex
)
{
WireHelpers
::
zeroObject
(
segment
,
pointers
+
ptrIndex
);
memset
(
pointers
+
ptrIndex
,
0
,
sizeof
(
WirePointer
));
}
void
StructBuilder
::
transferContentFrom
(
StructBuilder
other
)
{
// Determine the amount of data the builders have in common.
BitCount
sharedDataSize
=
kj
::
min
(
dataSize
,
other
.
dataSize
);
...
...
c++/src/capnp/layout.h
View file @
77d91c78
...
...
@@ -368,6 +368,9 @@ public:
// Detach the given pointer field from this object. The pointer becomes null, and the child
// object is returned as an orphan.
void
clearPointer
(
WirePointerCount
ptrIndex
);
// Equivalent to calling disown() and letting the result simply be destroyed.
void
transferContentFrom
(
StructBuilder
other
);
// Adopt all pointers from `other`, and also copy all data. If `other`'s sections are larger
// than this, the extra data is not transferred, meaning there is a risk of data loss when
...
...
c++/src/capnp/schema.capnp.h
View file @
77d91c78
...
...
@@ -2410,6 +2410,13 @@ inline Node::Struct::Builder Node::Builder::getStruct() {
inline
Node
::
Struct
::
Builder
Node
::
Builder
::
initStruct
()
{
_builder
.
setDataField
<
Node
::
Which
>
(
6
*
::
capnp
::
ELEMENTS
,
Node
::
STRUCT
);
_builder
.
setDataField
<
::
uint16_t
>
(
7
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
::
uint16_t
>
(
12
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
::
uint16_t
>
(
13
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
224
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
::
uint16_t
>
(
15
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
::
uint32_t
>
(
8
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
3
*
::
capnp
::
POINTERS
);
return
Node
::
Struct
::
Builder
(
_builder
);
}
inline
Node
::
Enum
::
Reader
Node
::
Reader
::
getEnum
()
const
{
...
...
@@ -2425,6 +2432,7 @@ inline Node::Enum::Builder Node::Builder::getEnum() {
inline
Node
::
Enum
::
Builder
Node
::
Builder
::
initEnum
()
{
_builder
.
setDataField
<
Node
::
Which
>
(
6
*
::
capnp
::
ELEMENTS
,
Node
::
ENUM
);
_builder
.
clearPointer
(
3
*
::
capnp
::
POINTERS
);
return
Node
::
Enum
::
Builder
(
_builder
);
}
inline
Node
::
Interface
::
Reader
Node
::
Reader
::
getInterface
()
const
{
...
...
@@ -2440,6 +2448,7 @@ inline Node::Interface::Builder Node::Builder::getInterface() {
inline
Node
::
Interface
::
Builder
Node
::
Builder
::
initInterface
()
{
_builder
.
setDataField
<
Node
::
Which
>
(
6
*
::
capnp
::
ELEMENTS
,
Node
::
INTERFACE
);
_builder
.
clearPointer
(
3
*
::
capnp
::
POINTERS
);
return
Node
::
Interface
::
Builder
(
_builder
);
}
inline
Node
::
Const
::
Reader
Node
::
Reader
::
getConst
()
const
{
...
...
@@ -2455,6 +2464,8 @@ inline Node::Const::Builder Node::Builder::getConst() {
inline
Node
::
Const
::
Builder
Node
::
Builder
::
initConst
()
{
_builder
.
setDataField
<
Node
::
Which
>
(
6
*
::
capnp
::
ELEMENTS
,
Node
::
CONST
);
_builder
.
clearPointer
(
3
*
::
capnp
::
POINTERS
);
_builder
.
clearPointer
(
4
*
::
capnp
::
POINTERS
);
return
Node
::
Const
::
Builder
(
_builder
);
}
inline
Node
::
Annotation
::
Reader
Node
::
Reader
::
getAnnotation
()
const
{
...
...
@@ -2470,6 +2481,19 @@ inline Node::Annotation::Builder Node::Builder::getAnnotation() {
inline
Node
::
Annotation
::
Builder
Node
::
Builder
::
initAnnotation
()
{
_builder
.
setDataField
<
Node
::
Which
>
(
6
*
::
capnp
::
ELEMENTS
,
Node
::
ANNOTATION
);
_builder
.
setDataField
<
bool
>
(
112
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
113
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
114
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
115
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
116
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
117
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
118
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
119
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
120
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
121
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
122
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
bool
>
(
123
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
3
*
::
capnp
::
POINTERS
);
return
Node
::
Annotation
::
Builder
(
_builder
);
}
inline
bool
Node
::
NestedNode
::
Reader
::
hasName
()
const
{
...
...
@@ -3221,6 +3245,9 @@ inline Field::NonGroup::Builder Field::Builder::getNonGroup() {
inline
Field
::
NonGroup
::
Builder
Field
::
Builder
::
initNonGroup
()
{
_builder
.
setDataField
<
Field
::
Which
>
(
4
*
::
capnp
::
ELEMENTS
,
Field
::
NON_GROUP
);
_builder
.
setDataField
<
::
uint32_t
>
(
1
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
clearPointer
(
2
*
::
capnp
::
POINTERS
);
_builder
.
clearPointer
(
3
*
::
capnp
::
POINTERS
);
return
Field
::
NonGroup
::
Builder
(
_builder
);
}
inline
bool
Field
::
Reader
::
hasGroup
()
const
{
...
...
@@ -3261,6 +3288,8 @@ inline Field::Ordinal::Builder Field::Builder::getOrdinal() {
return
Field
::
Ordinal
::
Builder
(
_builder
);
}
inline
Field
::
Ordinal
::
Builder
Field
::
Builder
::
initOrdinal
()
{
_builder
.
setDataField
<
::
uint16_t
>
(
5
*
::
capnp
::
ELEMENTS
,
0
);
_builder
.
setDataField
<
::
uint16_t
>
(
6
*
::
capnp
::
ELEMENTS
,
0
);
return
Field
::
Ordinal
::
Builder
(
_builder
);
}
inline
bool
Field
::
NonGroup
::
Reader
::
hasOffset
()
const
{
...
...
c++/src/capnp/test.capnp
View file @
77d91c78
...
...
@@ -270,18 +270,18 @@ struct TestUnnamedUnion {
}
struct TestGroups {
groups union {
foo group {
groups
:
union {
foo
:
group {
corge @0 :Int32;
grault @2 :Int64;
garply @8 :Text;
}
bar group {
bar
:
group {
corge @3 :Int32;
grault @4 :Text;
garply @5 :Int64;
}
baz group {
baz
:
group {
corge @1 :Int32;
grault @6 :Text;
garply @7 :Text;
...
...
@@ -289,6 +289,44 @@ struct TestGroups {
}
}
struct TestInterleavedGroups {
group1 :group {
foo @0 :UInt32;
bar @2 :UInt64;
union {
qux @4 :UInt16;
corge :group {
grault @6 :UInt64;
garply @8 :UInt16;
plugh @14 :Text;
xyzzy @16 :Text;
}
fred @12 :Text;
}
waldo @10 :Text;
}
group2 :group {
foo @1 :UInt32;
bar @3 :UInt64;
union {
qux @5 :UInt16;
corge :group {
grault @7 :UInt64;
garply @9 :UInt16;
plugh @15 :Text;
xyzzy @17 :Text;
}
fred @13 :Text;
}
waldo @11 :Text;
}
}
struct TestUnionDefaults {
s16s8s64s8Set @0 :TestUnion =
(union0 = (u0f0s16 = 321), union1 = (u1f0s8 = 123), union2 = (u2f0s64 = 12345678901234567),
...
...
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