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
f966fc41
Commit
f966fc41
authored
Apr 09, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Store primitive fields XOR'd with their defaults.
parent
f3c4121b
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
371 additions
and
283 deletions
+371
-283
layout-test.c++
c++/src/capnproto/layout-test.c++
+75
-57
layout.c++
c++/src/capnproto/layout.c++
+51
-58
layout.h
c++/src/capnproto/layout.h
+146
-31
list.h
c++/src/capnproto/list.h
+2
-3
message.c++
c++/src/capnproto/message.c++
+7
-8
message.h
c++/src/capnproto/message.h
+7
-8
test.capnp
c++/src/capnproto/test.capnp
+1
-1
CxxGenerator.hs
compiler/src/CxxGenerator.hs
+39
-43
WireFormat.hs
compiler/src/WireFormat.hs
+30
-53
c++-header.mustache
compiler/src/c++-header.mustache
+12
-14
c++-source.mustache
compiler/src/c++-source.mustache
+1
-7
No files found.
c++/src/capnproto/layout-test.c++
View file @
f966fc41
...
@@ -45,46 +45,58 @@ TEST(WireFormat, SimpleRawDataStruct) {
...
@@ -45,46 +45,58 @@ TEST(WireFormat, SimpleRawDataStruct) {
0x01
,
0x23
,
0x45
,
0x67
,
0x89
,
0xab
,
0xcd
,
0xef
0x01
,
0x23
,
0x45
,
0x67
,
0x89
,
0xab
,
0xcd
,
0xef
}};
}};
StructReader
reader
=
StructReader
::
readRootTrusted
(
data
.
words
,
data
.
words
);
StructReader
reader
=
StructReader
::
readRootTrusted
(
data
.
words
);
EXPECT_EQ
(
0xefcdab8967452301ull
,
reader
.
getDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0xefcdab8967452301ull
,
reader
.
getDataField
<
uint64_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
0u
,
reader
.
getDataField
<
uint64_t
>
(
1
*
ELEMENTS
));
EXPECT_EQ
(
0x67452301u
,
reader
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
0xefcdab89u
,
reader
.
getDataField
<
uint32_t
>
(
1
*
ELEMENTS
));
EXPECT_EQ
(
0u
,
reader
.
getDataField
<
uint32_t
>
(
2
*
ELEMENTS
));
EXPECT_EQ
(
0x2301u
,
reader
.
getDataField
<
uint16_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
0x6745u
,
reader
.
getDataField
<
uint16_t
>
(
1
*
ELEMENTS
));
EXPECT_EQ
(
0xab89u
,
reader
.
getDataField
<
uint16_t
>
(
2
*
ELEMENTS
));
EXPECT_EQ
(
0xefcdu
,
reader
.
getDataField
<
uint16_t
>
(
3
*
ELEMENTS
));
EXPECT_EQ
(
0u
,
reader
.
getDataField
<
uint16_t
>
(
4
*
ELEMENTS
));
EXPECT_EQ
(
321u
^
0xefcdab8967452301ull
,
reader
.
getDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
^
0x67452301u
,
reader
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
^
0x2301u
,
reader
.
getDataField
<
uint16_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint64_t
>
(
1
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint64_t
>
(
1
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0x67452301u
,
reader
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0xefcdab89u
,
reader
.
getDataField
<
uint32_t
>
(
1
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint32_t
>
(
2
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint32_t
>
(
2
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0x2301u
,
reader
.
getDataField
<
uint16_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0x6745u
,
reader
.
getDataField
<
uint16_t
>
(
1
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0xab89u
,
reader
.
getDataField
<
uint16_t
>
(
2
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0xefcdu
,
reader
.
getDataField
<
uint16_t
>
(
3
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint16_t
>
(
4
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint16_t
>
(
4
*
ELEMENTS
,
321u
));
// Bits
// Bits
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
0
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
1
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
2
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
3
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
4
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
5
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
6
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
7
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
8
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
9
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
10
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
11
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
12
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
13
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
14
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
15
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
63
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
64
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
0
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
0
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
1
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
1
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
2
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
3
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
4
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
5
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
6
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
7
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
8
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
9
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
10
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
11
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
12
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
13
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
14
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
15
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
63
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
63
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
63
*
ELEMENTS
,
true
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
64
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
64
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
64
*
ELEMENTS
,
true
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
0
*
ELEMENTS
,
true
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
1
*
ELEMENTS
,
true
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
63
*
ELEMENTS
,
true
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
64
*
ELEMENTS
,
true
));
}
}
static
const
AlignedData
<
6
>
STRUCT_DEFAULT
=
{{
0
,
0
,
0
,
0
,
2
,
0
,
4
,
0
,
0
}};
static
const
AlignedData
<
2
>
SUBSTRUCT_DEFAULT
=
{{
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}};
static
const
AlignedData
<
2
>
SUBSTRUCT_DEFAULT
=
{{
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}};
static
const
AlignedData
<
3
>
STRUCTLIST_ELEMENT_DEFAULT
=
static
const
AlignedData
<
3
>
STRUCTLIST_ELEMENT_DEFAULT
=
{{
0
,
0
,
0
,
0
,
1
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}};
{{
0
,
0
,
0
,
0
,
1
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}};
...
@@ -106,7 +118,8 @@ static void setupStruct(StructBuilder builder) {
...
@@ -106,7 +118,8 @@ static void setupStruct(StructBuilder builder) {
builder
.
setDataField
<
bool
>
(
127
*
ELEMENTS
,
false
);
builder
.
setDataField
<
bool
>
(
127
*
ELEMENTS
,
false
);
{
{
StructBuilder
subStruct
=
builder
.
initStructField
(
0
*
REFERENCES
,
SUBSTRUCT_DEFAULT
.
words
);
StructBuilder
subStruct
=
builder
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
));
subStruct
.
setDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
123
);
subStruct
.
setDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
123
);
}
}
...
@@ -120,12 +133,12 @@ static void setupStruct(StructBuilder builder) {
...
@@ -120,12 +133,12 @@ static void setupStruct(StructBuilder builder) {
{
{
ListBuilder
list
=
builder
.
initStructListField
(
ListBuilder
list
=
builder
.
initStructListField
(
2
*
REFERENCES
,
4
*
ELEMENTS
,
S
TRUCTLIST_ELEMENT_DEFAULT
.
words
);
2
*
REFERENCES
,
4
*
ELEMENTS
,
S
tructSize
(
1
*
WORDS
,
1
*
REFERENCES
)
);
EXPECT_EQ
(
4
*
ELEMENTS
,
list
.
size
());
EXPECT_EQ
(
4
*
ELEMENTS
,
list
.
size
());
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
2
*
WORDS
/
ELEMENTS
,
1
*
WORDS
);
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
2
*
WORDS
/
ELEMENTS
,
1
*
WORDS
);
element
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
300
+
i
);
element
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
300
+
i
);
element
.
initStructField
(
0
*
REFERENCES
,
S
TRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
element
.
initStructField
(
0
*
REFERENCES
,
S
tructSize
(
1
*
WORDS
,
0
*
REFERENCES
)
)
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
400
+
i
);
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
400
+
i
);
}
}
}
}
...
@@ -159,7 +172,8 @@ static void checkStruct(StructBuilder builder) {
...
@@ -159,7 +172,8 @@ static void checkStruct(StructBuilder builder) {
EXPECT_FALSE
(
builder
.
getDataField
<
bool
>
(
127
*
ELEMENTS
));
EXPECT_FALSE
(
builder
.
getDataField
<
bool
>
(
127
*
ELEMENTS
));
{
{
StructBuilder
subStruct
=
builder
.
getStructField
(
0
*
REFERENCES
,
SUBSTRUCT_DEFAULT
.
words
);
StructBuilder
subStruct
=
builder
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
),
SUBSTRUCT_DEFAULT
.
words
);
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
}
}
...
@@ -178,7 +192,8 @@ static void checkStruct(StructBuilder builder) {
...
@@ -178,7 +192,8 @@ static void checkStruct(StructBuilder builder) {
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
2
*
WORDS
/
ELEMENTS
,
1
*
WORDS
);
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
2
*
WORDS
/
ELEMENTS
,
1
*
WORDS
);
EXPECT_EQ
(
300
+
i
,
element
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
300
+
i
,
element
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
400
+
i
,
EXPECT_EQ
(
400
+
i
,
element
.
getStructField
(
0
*
REFERENCES
,
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
element
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
),
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
}
}
}
}
...
@@ -197,22 +212,22 @@ static void checkStruct(StructBuilder builder) {
...
@@ -197,22 +212,22 @@ static void checkStruct(StructBuilder builder) {
}
}
static
void
checkStruct
(
StructReader
reader
)
{
static
void
checkStruct
(
StructReader
reader
)
{
EXPECT_EQ
(
0x1011121314151617ull
,
reader
.
getDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
1616
));
EXPECT_EQ
(
0x1011121314151617ull
,
reader
.
getDataField
<
uint64_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
0x20212223u
,
reader
.
getDataField
<
uint32_t
>
(
2
*
ELEMENTS
,
1616
));
EXPECT_EQ
(
0x20212223u
,
reader
.
getDataField
<
uint32_t
>
(
2
*
ELEMENTS
));
EXPECT_EQ
(
0x3031u
,
reader
.
getDataField
<
uint16_t
>
(
6
*
ELEMENTS
,
1616
));
EXPECT_EQ
(
0x3031u
,
reader
.
getDataField
<
uint16_t
>
(
6
*
ELEMENTS
));
EXPECT_EQ
(
0x40u
,
reader
.
getDataField
<
uint8_t
>
(
14
*
ELEMENTS
,
16
));
EXPECT_EQ
(
0x40u
,
reader
.
getDataField
<
uint8_t
>
(
14
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
120
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
120
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
121
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
121
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
122
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
122
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
123
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
123
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
124
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
124
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
125
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
125
*
ELEMENTS
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
126
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
126
*
ELEMENTS
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
127
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
127
*
ELEMENTS
));
{
{
StructReader
subStruct
=
reader
.
getStructField
(
0
*
REFERENCES
,
SUBSTRUCT_DEFAULT
.
words
);
StructReader
subStruct
=
reader
.
getStructField
(
0
*
REFERENCES
,
SUBSTRUCT_DEFAULT
.
words
);
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
456
));
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
}
}
{
{
...
@@ -227,11 +242,11 @@ static void checkStruct(StructReader reader) {
...
@@ -227,11 +242,11 @@ static void checkStruct(StructReader reader) {
ListReader
list
=
reader
.
getListField
(
2
*
REFERENCES
,
FieldSize
::
INLINE_COMPOSITE
,
nullptr
);
ListReader
list
=
reader
.
getListField
(
2
*
REFERENCES
,
FieldSize
::
INLINE_COMPOSITE
,
nullptr
);
ASSERT_EQ
(
4
*
ELEMENTS
,
list
.
size
());
ASSERT_EQ
(
4
*
ELEMENTS
,
list
.
size
());
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
StructReader
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_DEFAULT
.
words
);
StructReader
element
=
list
.
getStructElement
(
i
*
ELEMENTS
);
EXPECT_EQ
(
300
+
i
,
element
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
,
1616
));
EXPECT_EQ
(
300
+
i
,
element
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
400
+
i
,
EXPECT_EQ
(
400
+
i
,
element
.
getStructField
(
0
*
REFERENCES
,
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
element
.
getStructField
(
0
*
REFERENCES
,
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
,
1616
));
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
}
}
}
}
...
@@ -255,7 +270,8 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
...
@@ -255,7 +270,8 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
SegmentBuilder
*
segment
=
arena
.
getSegmentWithAvailable
(
1
*
WORDS
);
SegmentBuilder
*
segment
=
arena
.
getSegmentWithAvailable
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
STRUCT_DEFAULT
.
words
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// word count:
// word count:
...
@@ -280,8 +296,8 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
...
@@ -280,8 +296,8 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
checkStruct
(
builder
);
checkStruct
(
builder
);
checkStruct
(
builder
.
asReader
());
checkStruct
(
builder
.
asReader
());
checkStruct
(
StructReader
::
readRootTrusted
(
segment
->
getStartPtr
()
,
nullptr
));
checkStruct
(
StructReader
::
readRootTrusted
(
segment
->
getStartPtr
()));
checkStruct
(
StructReader
::
readRoot
(
segment
->
getStartPtr
(),
nullptr
,
segment
,
4
));
checkStruct
(
StructReader
::
readRoot
(
segment
->
getStartPtr
(),
segment
,
4
));
}
}
TEST
(
WireFormat
,
StructRoundTrip_OneSegmentPerAllocation
)
{
TEST
(
WireFormat
,
StructRoundTrip_OneSegmentPerAllocation
)
{
...
@@ -290,7 +306,8 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
...
@@ -290,7 +306,8 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
SegmentBuilder
*
segment
=
arena
.
getSegmentWithAvailable
(
1
*
WORDS
);
SegmentBuilder
*
segment
=
arena
.
getSegmentWithAvailable
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
STRUCT_DEFAULT
.
words
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// Verify that we made 15 segments.
// Verify that we made 15 segments.
...
@@ -317,7 +334,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
...
@@ -317,7 +334,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
checkStruct
(
builder
);
checkStruct
(
builder
);
checkStruct
(
builder
.
asReader
());
checkStruct
(
builder
.
asReader
());
checkStruct
(
StructReader
::
readRoot
(
segment
->
getStartPtr
(),
nullptr
,
segment
,
4
));
checkStruct
(
StructReader
::
readRoot
(
segment
->
getStartPtr
(),
segment
,
4
));
}
}
TEST
(
WireFormat
,
StructRoundTrip_MultipleSegmentsWithMultipleAllocations
)
{
TEST
(
WireFormat
,
StructRoundTrip_MultipleSegmentsWithMultipleAllocations
)
{
...
@@ -326,7 +343,8 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
...
@@ -326,7 +343,8 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
SegmentBuilder
*
segment
=
arena
.
getSegmentWithAvailable
(
1
*
WORDS
);
SegmentBuilder
*
segment
=
arena
.
getSegmentWithAvailable
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
STRUCT_DEFAULT
.
words
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// Verify that we made 6 segments.
// Verify that we made 6 segments.
...
@@ -344,7 +362,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
...
@@ -344,7 +362,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
checkStruct
(
builder
);
checkStruct
(
builder
);
checkStruct
(
builder
.
asReader
());
checkStruct
(
builder
.
asReader
());
checkStruct
(
StructReader
::
readRoot
(
segment
->
getStartPtr
(),
nullptr
,
segment
,
4
));
checkStruct
(
StructReader
::
readRoot
(
segment
->
getStartPtr
(),
segment
,
4
));
}
}
}
// namespace
}
// namespace
...
...
c++/src/capnproto/layout.c++
View file @
f966fc41
...
@@ -129,6 +129,10 @@ struct WireReference {
...
@@ -129,6 +129,10 @@ struct WireReference {
dataSize
.
set
(
ds
);
dataSize
.
set
(
ds
);
refCount
.
set
(
rc
);
refCount
.
set
(
rc
);
}
}
CAPNPROTO_ALWAYS_INLINE
(
void
set
(
StructSize
size
))
{
dataSize
.
set
(
size
.
data
);
refCount
.
set
(
size
.
pointers
);
}
}
structRef
;
}
structRef
;
// Also covers capabilities.
// Also covers capabilities.
...
@@ -403,47 +407,42 @@ struct WireHelpers {
...
@@ -403,47 +407,42 @@ struct WireHelpers {
// -----------------------------------------------------------------
// -----------------------------------------------------------------
static
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
initStructReference
(
static
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
initStructReference
(
WireReference
*
ref
,
SegmentBuilder
*
segment
,
const
word
*
typeDefaultValue
))
{
WireReference
*
ref
,
SegmentBuilder
*
segment
,
StructSize
size
))
{
const
WireReference
*
defaultRef
=
reinterpret_cast
<
const
WireReference
*>
(
typeDefaultValue
);
// Allocate space for the new struct. Newly-allocated space is automatically zeroed.
word
*
ptr
=
allocate
(
ref
,
segment
,
size
.
total
(),
WireReference
::
STRUCT
);
// Allocate space for the new struct.
word
*
ptr
=
allocate
(
ref
,
segment
,
defaultRef
->
structRef
.
wordSize
(),
WireReference
::
STRUCT
);
// Copy over the data segment from the default value. We don't have to copy the reference
// segment because it is presumed to be all-null.
memcpy
(
ptr
,
defaultRef
->
target
(),
defaultRef
->
structRef
.
dataSize
.
get
()
*
BYTES_PER_WORD
/
BYTES
);
// Initialize the reference.
// Initialize the reference.
ref
->
structRef
.
set
(
defaultRef
->
structRef
.
dataSize
.
get
(),
defaultRef
->
structRef
.
refCount
.
get
()
);
ref
->
structRef
.
set
(
size
);
// Build the StructBuilder.
// Build the StructBuilder.
return
StructBuilder
(
segment
,
ptr
,
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
));
reinterpret_cast
<
WireReference
*>
(
ptr
+
defaultRef
->
structRef
.
dataSize
.
get
()));
}
}
static
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
getWritableStructReference
(
static
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
getWritableStructReference
(
WireReference
*
ref
,
SegmentBuilder
*
segment
,
const
word
*
defaultValue
))
{
WireReference
*
ref
,
SegmentBuilder
*
segment
,
StructSize
size
,
const
word
*
defaultValue
))
{
const
WireReference
*
defaultRef
=
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
);
word
*
ptr
;
word
*
ptr
;
if
(
ref
->
isNull
())
{
if
(
ref
->
isNull
())
{
ptr
=
copyMessage
(
segment
,
ref
,
defaultRef
);
if
(
defaultValue
==
nullptr
)
{
ptr
=
allocate
(
ref
,
segment
,
size
.
total
(),
WireReference
::
STRUCT
);
ref
->
structRef
.
set
(
size
);
}
else
{
ptr
=
copyMessage
(
segment
,
ref
,
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
));
}
}
else
{
}
else
{
ptr
=
followFars
(
ref
,
segment
);
ptr
=
followFars
(
ref
,
segment
);
CAPNPROTO_DEBUG_ASSERT
(
ref
->
kind
()
==
WireReference
::
STRUCT
,
CAPNPROTO_DEBUG_ASSERT
(
ref
->
kind
()
==
WireReference
::
STRUCT
,
"Called getStruct{Field,Element}() but existing reference is not a struct."
);
"Called getStruct{Field,Element}() but existing reference is not a struct."
);
CAPNPROTO_DEBUG_ASSERT
(
CAPNPROTO_DEBUG_ASSERT
(
ref
->
structRef
.
dataSize
.
get
()
==
defaultRef
->
structRef
.
dataSize
.
get
()
,
ref
->
structRef
.
dataSize
.
get
()
==
size
.
data
,
"Trying to update struct with incorrect data size."
);
"Trying to update struct with incorrect data size."
);
CAPNPROTO_DEBUG_ASSERT
(
CAPNPROTO_DEBUG_ASSERT
(
ref
->
structRef
.
refCount
.
get
()
==
defaultRef
->
structRef
.
refCount
.
get
()
,
ref
->
structRef
.
refCount
.
get
()
==
size
.
pointers
,
"Trying to update struct with incorrect reference count."
);
"Trying to update struct with incorrect reference count."
);
}
}
return
StructBuilder
(
segment
,
ptr
,
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
));
reinterpret_cast
<
WireReference
*>
(
ptr
+
defaultRef
->
structRef
.
dataSize
.
get
()));
}
}
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initListReference
(
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initListReference
(
...
@@ -468,10 +467,8 @@ struct WireHelpers {
...
@@ -468,10 +467,8 @@ struct WireHelpers {
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initStructListReference
(
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initStructListReference
(
WireReference
*
ref
,
SegmentBuilder
*
segment
,
ElementCount
elementCount
,
WireReference
*
ref
,
SegmentBuilder
*
segment
,
ElementCount
elementCount
,
const
word
*
elementDefaultValue
))
{
StructSize
elementSize
))
{
const
WireReference
*
defaultRef
=
reinterpret_cast
<
const
WireReference
*>
(
elementDefaultValue
);
auto
wordsPerElement
=
elementSize
.
total
()
/
ELEMENTS
;
auto
wordsPerElement
=
defaultRef
->
structRef
.
wordSize
()
/
ELEMENTS
;
// Allocate the list, prefixed by a single WireReference.
// Allocate the list, prefixed by a single WireReference.
WordCount
wordCount
=
elementCount
*
wordsPerElement
;
WordCount
wordCount
=
elementCount
*
wordsPerElement
;
...
@@ -484,22 +481,9 @@ struct WireHelpers {
...
@@ -484,22 +481,9 @@ struct WireHelpers {
// Initialize the list tag.
// Initialize the list tag.
reinterpret_cast
<
WireReference
*>
(
ptr
)
->
setKindAndInlineCompositeListElementCount
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
->
setKindAndInlineCompositeListElementCount
(
WireReference
::
STRUCT
,
elementCount
);
WireReference
::
STRUCT
,
elementCount
);
reinterpret_cast
<
WireReference
*>
(
ptr
)
->
structRef
.
set
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
->
structRef
.
set
(
elementSize
);
defaultRef
->
structRef
.
dataSize
.
get
(),
defaultRef
->
structRef
.
refCount
.
get
());
ptr
+=
REFERENCE_SIZE_IN_WORDS
;
ptr
+=
REFERENCE_SIZE_IN_WORDS
;
// Initialize the elements. We only have to copy the data segments, as the reference segment
// in a struct type default value is always all-null.
ByteCount
elementDataByteSize
=
defaultRef
->
structRef
.
dataSize
.
get
()
*
BYTES_PER_WORD
;
const
word
*
defaultData
=
defaultRef
->
target
();
word
*
elementPtr
=
ptr
;
uint
n
=
elementCount
/
ELEMENTS
;
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
memcpy
(
elementPtr
,
defaultData
,
elementDataByteSize
/
BYTES
);
elementPtr
+=
1
*
ELEMENTS
*
wordsPerElement
;
}
// Build the ListBuilder.
// Build the ListBuilder.
return
ListBuilder
(
segment
,
ptr
,
elementCount
);
return
ListBuilder
(
segment
,
ptr
,
elementCount
);
}
}
...
@@ -618,6 +602,10 @@ struct WireHelpers {
...
@@ -618,6 +602,10 @@ struct WireHelpers {
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
useDefault
:
if
(
defaultValue
==
nullptr
)
{
return
StructReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
WORDS
,
0
*
REFERENCES
,
0
*
BITS
,
std
::
numeric_limits
<
int
>::
max
());
}
segment
=
nullptr
;
segment
=
nullptr
;
ref
=
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
);
ref
=
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
);
ptr
=
ref
->
target
();
ptr
=
ref
->
target
();
...
@@ -940,25 +928,26 @@ struct WireHelpers {
...
@@ -940,25 +928,26 @@ struct WireHelpers {
// =======================================================================================
// =======================================================================================
StructBuilder
StructBuilder
::
initRoot
(
StructBuilder
StructBuilder
::
initRoot
(
SegmentBuilder
*
segment
,
word
*
location
,
const
word
*
defaultValu
e
)
{
SegmentBuilder
*
segment
,
word
*
location
,
StructSize
siz
e
)
{
return
WireHelpers
::
initStructReference
(
return
WireHelpers
::
initStructReference
(
reinterpret_cast
<
WireReference
*>
(
location
),
segment
,
defaultValu
e
);
reinterpret_cast
<
WireReference
*>
(
location
),
segment
,
siz
e
);
}
}
StructBuilder
StructBuilder
::
getRoot
(
StructBuilder
StructBuilder
::
getRoot
(
SegmentBuilder
*
segment
,
word
*
location
,
const
word
*
defaultValu
e
)
{
SegmentBuilder
*
segment
,
word
*
location
,
StructSize
siz
e
)
{
return
WireHelpers
::
getWritableStructReference
(
return
WireHelpers
::
getWritableStructReference
(
reinterpret_cast
<
WireReference
*>
(
location
),
segment
,
defaultValue
);
reinterpret_cast
<
WireReference
*>
(
location
),
segment
,
size
,
nullptr
);
}
}
StructBuilder
StructBuilder
::
initStructField
(
StructBuilder
StructBuilder
::
initStructField
(
WireReferenceCount
refIndex
,
const
word
*
typeDefaultValu
e
)
const
{
WireReferenceCount
refIndex
,
StructSize
siz
e
)
const
{
return
WireHelpers
::
initStructReference
(
references
+
refIndex
,
segment
,
typeDefaultValu
e
);
return
WireHelpers
::
initStructReference
(
references
+
refIndex
,
segment
,
siz
e
);
}
}
StructBuilder
StructBuilder
::
getStructField
(
StructBuilder
StructBuilder
::
getStructField
(
WireReferenceCount
refIndex
,
const
word
*
defaultValue
)
const
{
WireReferenceCount
refIndex
,
StructSize
size
,
const
word
*
defaultValue
)
const
{
return
WireHelpers
::
getWritableStructReference
(
references
+
refIndex
,
segment
,
defaultValue
);
return
WireHelpers
::
getWritableStructReference
(
references
+
refIndex
,
segment
,
size
,
defaultValue
);
}
}
ListBuilder
StructBuilder
::
initListField
(
ListBuilder
StructBuilder
::
initListField
(
...
@@ -969,10 +958,9 @@ ListBuilder StructBuilder::initListField(
...
@@ -969,10 +958,9 @@ ListBuilder StructBuilder::initListField(
}
}
ListBuilder
StructBuilder
::
initStructListField
(
ListBuilder
StructBuilder
::
initStructListField
(
WireReferenceCount
refIndex
,
ElementCount
elementCount
,
WireReferenceCount
refIndex
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
const
word
*
elementDefaultValue
)
const
{
return
WireHelpers
::
initStructListReference
(
return
WireHelpers
::
initStructListReference
(
references
+
refIndex
,
segment
,
elementCount
,
element
DefaultValu
e
);
references
+
refIndex
,
segment
,
elementCount
,
element
Siz
e
);
}
}
ListBuilder
StructBuilder
::
getListField
(
ListBuilder
StructBuilder
::
getListField
(
...
@@ -1016,20 +1004,25 @@ StructReader StructBuilder::asReader() const {
...
@@ -1016,20 +1004,25 @@ StructReader StructBuilder::asReader() const {
0xffff
*
WORDS
,
0xffff
*
REFERENCES
,
0
*
BITS
,
std
::
numeric_limits
<
int
>::
max
());
0xffff
*
WORDS
,
0xffff
*
REFERENCES
,
0
*
BITS
,
std
::
numeric_limits
<
int
>::
max
());
}
}
StructReader
StructReader
::
readRootTrusted
(
const
word
*
location
,
const
word
*
defaultValue
)
{
StructReader
StructReader
::
readRootTrusted
(
const
word
*
location
)
{
return
WireHelpers
::
readStructReference
(
nullptr
,
reinterpret_cast
<
const
WireReference
*>
(
location
),
return
WireHelpers
::
readStructReference
(
nullptr
,
reinterpret_cast
<
const
WireReference
*>
(
location
),
defaultValue
,
std
::
numeric_limits
<
int
>::
max
());
nullptr
,
std
::
numeric_limits
<
int
>::
max
());
}
}
StructReader
StructReader
::
readRoot
(
const
word
*
location
,
const
word
*
defaultValue
,
StructReader
StructReader
::
readRoot
(
SegmentReader
*
segment
,
int
nestingLimit
)
{
const
word
*
location
,
SegmentReader
*
segment
,
int
nestingLimit
)
{
if
(
!
segment
->
containsInterval
(
location
,
location
+
REFERENCE_SIZE_IN_WORDS
))
{
if
(
!
segment
->
containsInterval
(
location
,
location
+
REFERENCE_SIZE_IN_WORDS
))
{
segment
->
getArena
()
->
reportInvalidData
(
"Root location out-of-bounds."
);
segment
->
getArena
()
->
reportInvalidData
(
"Root location out-of-bounds."
);
location
=
nullptr
;
location
=
nullptr
;
}
}
return
WireHelpers
::
readStructReference
(
segment
,
reinterpret_cast
<
const
WireReference
*>
(
location
),
return
WireHelpers
::
readStructReference
(
segment
,
reinterpret_cast
<
const
WireReference
*>
(
location
),
defaultValue
,
nestingLimit
);
nullptr
,
nestingLimit
);
}
StructReader
StructReader
::
readEmpty
()
{
return
StructReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
WORDS
,
0
*
REFERENCES
,
0
*
BITS
,
std
::
numeric_limits
<
int
>::
max
());
}
}
StructReader
StructReader
::
getStructField
(
StructReader
StructReader
::
getStructField
(
...
@@ -1072,10 +1065,10 @@ ListBuilder ListBuilder::initListElement(
...
@@ -1072,10 +1065,10 @@ ListBuilder ListBuilder::initListElement(
}
}
ListBuilder
ListBuilder
::
initStructListElement
(
ListBuilder
ListBuilder
::
initStructListElement
(
WireReferenceCount
index
,
ElementCount
elementCount
,
const
word
*
elementDefaultValu
e
)
const
{
WireReferenceCount
index
,
ElementCount
elementCount
,
StructSize
elementSiz
e
)
const
{
return
WireHelpers
::
initStructListReference
(
return
WireHelpers
::
initStructListReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
elementCount
,
element
DefaultValu
e
);
elementCount
,
element
Siz
e
);
}
}
ListBuilder
ListBuilder
::
getListElement
(
WireReferenceCount
index
)
const
{
ListBuilder
ListBuilder
::
getListElement
(
WireReferenceCount
index
)
const
{
...
@@ -1123,11 +1116,11 @@ ListReader ListBuilder::asReader(WordCount dataSize, WireReferenceCount referenc
...
@@ -1123,11 +1116,11 @@ ListReader ListBuilder::asReader(WordCount dataSize, WireReferenceCount referenc
dataSize
,
referenceCount
,
std
::
numeric_limits
<
int
>::
max
());
dataSize
,
referenceCount
,
std
::
numeric_limits
<
int
>::
max
());
}
}
StructReader
ListReader
::
getStructElement
(
ElementCount
index
,
const
word
*
defaultValue
)
const
{
StructReader
ListReader
::
getStructElement
(
ElementCount
index
)
const
{
if
(
CAPNPROTO_EXPECT_FALSE
((
segment
!=
nullptr
)
&
(
nestingLimit
==
0
)))
{
if
(
CAPNPROTO_EXPECT_FALSE
((
segment
!=
nullptr
)
&
(
nestingLimit
==
0
)))
{
segment
->
getArena
()
->
reportInvalidData
(
segment
->
getArena
()
->
reportInvalidData
(
"Message is too deeply-nested or contains cycles. See capnproto::ReadOptions."
);
"Message is too deeply-nested or contains cycles. See capnproto::ReadOptions."
);
return
WireHelpers
::
readStructReference
(
nullptr
,
nullptr
,
defaultValue
,
nestingLimit
);
return
StructReader
::
readEmpty
(
);
}
else
{
}
else
{
BitCount64
indexBit
=
ElementCount64
(
index
)
*
stepBits
;
BitCount64
indexBit
=
ElementCount64
(
index
)
*
stepBits
;
const
byte
*
structPtr
=
reinterpret_cast
<
const
byte
*>
(
ptr
)
+
indexBit
/
BITS_PER_BYTE
;
const
byte
*
structPtr
=
reinterpret_cast
<
const
byte
*>
(
ptr
)
+
indexBit
/
BITS_PER_BYTE
;
...
...
c++/src/capnproto/layout.h
View file @
f966fc41
...
@@ -123,6 +123,91 @@ union AlignedData {
...
@@ -123,6 +123,91 @@ union AlignedData {
word
words
[
wordCount
];
word
words
[
wordCount
];
};
};
struct
StructSize
{
WordCount16
data
;
WireReferenceCount16
pointers
;
inline
constexpr
WordCount
total
()
const
{
return
data
+
pointers
*
WORDS_PER_REFERENCE
;
}
StructSize
()
=
default
;
inline
constexpr
StructSize
(
WordCount
data
,
WireReferenceCount
pointers
)
:
data
(
data
),
pointers
(
pointers
)
{}
};
template
<
typename
T
>
class
IsEnum
{
// Detects whether a primitive value is an enum.
typedef
char
no
;
typedef
long
yes
;
static
no
test
(
int
i
);
static
yes
test
(...);
public
:
static
constexpr
bool
value
=
sizeof
(
test
(
T
()))
==
sizeof
(
yes
);
};
// -------------------------------------------------------------------
// Masking of default values
template
<
typename
T
,
bool
isEnum
=
IsEnum
<
T
>::
value
>
struct
MaskType
{
typedef
T
Type
;
};
template
<
typename
T
>
struct
MaskType
<
T
,
false
>
{
typedef
T
Type
;
};
template
<
typename
T
>
struct
MaskType
<
T
,
true
>
{
typedef
uint16_t
Type
;
};
template
<>
struct
MaskType
<
float
,
false
>
{
typedef
uint32_t
Type
;
};
template
<>
struct
MaskType
<
double
,
false
>
{
typedef
uint64_t
Type
;
};
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
typename
MaskType
<
T
>::
Type
mask
(
T
value
,
typename
MaskType
<
T
>::
Type
mask
));
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
T
unmask
(
typename
MaskType
<
T
>::
Type
value
,
typename
MaskType
<
T
>::
Type
mask
));
template
<
typename
T
>
inline
typename
MaskType
<
T
>::
Type
mask
(
T
value
,
typename
MaskType
<
T
>::
Type
mask
)
{
return
static_cast
<
typename
MaskType
<
T
>::
Type
>
(
value
)
^
mask
;
}
template
<>
inline
uint32_t
mask
<
float
>
(
float
value
,
uint32_t
mask
)
{
uint32_t
i
;
static_assert
(
sizeof
(
i
)
==
sizeof
(
value
),
"float is not 32 bits?"
);
memcpy
(
&
i
,
&
value
,
sizeof
(
value
));
return
i
^
mask
;
}
template
<>
inline
uint64_t
mask
<
double
>
(
double
value
,
uint64_t
mask
)
{
uint64_t
i
;
static_assert
(
sizeof
(
i
)
==
sizeof
(
value
),
"double is not 64 bits?"
);
memcpy
(
&
i
,
&
value
,
sizeof
(
value
));
return
i
^
mask
;
}
template
<
typename
T
>
inline
T
unmask
(
typename
MaskType
<
T
>::
Type
value
,
typename
MaskType
<
T
>::
Type
mask
)
{
return
static_cast
<
T
>
(
value
^
mask
);
}
template
<>
inline
float
unmask
<
float
>
(
uint32_t
value
,
uint32_t
mask
)
{
value
^=
mask
;
float
result
;
static_assert
(
sizeof
(
result
)
==
sizeof
(
value
),
"float is not 32 bits?"
);
memcpy
(
&
result
,
&
value
,
sizeof
(
value
));
return
result
;
}
template
<>
inline
double
unmask
<
double
>
(
uint64_t
value
,
uint64_t
mask
)
{
value
^=
mask
;
double
result
;
static_assert
(
sizeof
(
result
)
==
sizeof
(
value
),
"double is not 64 bits?"
);
memcpy
(
&
result
,
&
value
,
sizeof
(
value
));
return
result
;
}
// -------------------------------------------------------------------
// -------------------------------------------------------------------
template
<
typename
T
>
template
<
typename
T
>
...
@@ -154,30 +239,42 @@ class StructBuilder {
...
@@ -154,30 +239,42 @@ class StructBuilder {
public
:
public
:
inline
StructBuilder
()
:
segment
(
nullptr
),
data
(
nullptr
),
references
(
nullptr
)
{}
inline
StructBuilder
()
:
segment
(
nullptr
),
data
(
nullptr
),
references
(
nullptr
)
{}
static
StructBuilder
initRoot
(
SegmentBuilder
*
segment
,
word
*
location
,
const
word
*
defaultValu
e
);
static
StructBuilder
initRoot
(
SegmentBuilder
*
segment
,
word
*
location
,
StructSize
siz
e
);
static
StructBuilder
getRoot
(
SegmentBuilder
*
segment
,
word
*
location
,
const
word
*
defaultValu
e
);
static
StructBuilder
getRoot
(
SegmentBuilder
*
segment
,
word
*
location
,
StructSize
siz
e
);
template
<
typename
T
>
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
T
getDataField
(
ElementCount
offset
)
const
);
CAPNPROTO_ALWAYS_INLINE
(
T
getDataField
(
ElementCount
offset
)
const
);
// Gets the data field value of the given type at the given offset. The offset is measured in
// Gets the data field value of the given type at the given offset. The offset is measured in
// multiples of the field size, determined by the type.
// multiples of the field size, determined by the type.
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
T
getDataField
(
ElementCount
offset
,
typename
MaskType
<
T
>::
Type
mask
)
const
);
// Like getDataField() but applies the given XOR mask to the data on load. Used for reading
// fields with non-zero default values.
template
<
typename
T
>
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
void
setDataField
(
CAPNPROTO_ALWAYS_INLINE
(
void
setDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
value
)
const
);
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
value
)
const
);
// Sets the data field value at the given offset.
// Sets the data field value at the given offset.
StructBuilder
initStructField
(
WireReferenceCount
refIndex
,
const
word
*
typeDefaultValue
)
const
;
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
void
setDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
value
,
typename
MaskType
<
T
>::
Type
mask
)
const
);
// Like setDataField() but applies the given XOR mask before storing. Used for writing fields
// with non-zero default values.
StructBuilder
initStructField
(
WireReferenceCount
refIndex
,
StructSize
size
)
const
;
// Initializes the struct field at the given index in the reference segment. If it is already
// Initializes the struct field at the given index in the reference segment. If it is already
// initialized, the previous value is discarded or overwritten. The struct is initialized to
// initialized, the previous value is discarded or overwritten. The struct is initialized to
// match the given default value (a trusted message). This must be the default value for the
// the type's default state (all-zero). Use getStructField() if you want the struct to be
// *type*, not the specific field, and in particular its reference segment is expected to be
// initialized as a copy of the field's default value (which may have non-null references).
// all nulls (only the data segment is copied). Use getStructField() if you want the struct
// to be initialized as a copy of the field's default value (which may have non-null references).
StructBuilder
getStructField
(
WireReferenceCount
refIndex
,
const
word
*
defaultValue
)
const
;
StructBuilder
getStructField
(
WireReferenceCount
refIndex
,
StructSize
size
,
const
word
*
defaultValue
)
const
;
// Gets the struct field at the given index in the reference segment. If the field is not already
// Gets the struct field at the given index in the reference segment. If the field is not already
// initialized, it is initialized as a deep copy of the given default value (a trusted message).
// initialized, it is initialized as a deep copy of the given default value (a trusted message),
// or to the empty state if defaultValue is nullptr.
ListBuilder
initListField
(
WireReferenceCount
refIndex
,
FieldSize
elementSize
,
ListBuilder
initListField
(
WireReferenceCount
refIndex
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
;
ElementCount
elementCount
)
const
;
...
@@ -185,11 +282,9 @@ public:
...
@@ -185,11 +282,9 @@ public:
// segment, and return a pointer to it. All elements are initialized to zero.
// segment, and return a pointer to it. All elements are initialized to zero.
ListBuilder
initStructListField
(
WireReferenceCount
refIndex
,
ElementCount
elementCount
,
ListBuilder
initStructListField
(
WireReferenceCount
refIndex
,
ElementCount
elementCount
,
const
word
*
elementDefaultValu
e
)
const
;
StructSize
siz
e
)
const
;
// Allocates a new list of the given size for the field at the given index in the reference
// Allocates a new list of the given size for the field at the given index in the reference
// segment, and return a pointer to it. Each element is initialized as a copy of
// segment, and return a pointer to it. Each element is initialized to its empty state.
// elementDefaultValue. As with initStructField(), this should be the default value for the
// *type*, with all-null references.
ListBuilder
getListField
(
WireReferenceCount
refIndex
,
const
word
*
defaultValue
)
const
;
ListBuilder
getListField
(
WireReferenceCount
refIndex
,
const
word
*
defaultValue
)
const
;
// Gets the already-allocated list field for the given reference index. If the list is not
// Gets the already-allocated list field for the given reference index. If the list is not
...
@@ -234,21 +329,27 @@ public:
...
@@ -234,21 +329,27 @@ public:
:
segment
(
nullptr
),
data
(
nullptr
),
references
(
nullptr
),
dataSize
(
0
),
:
segment
(
nullptr
),
data
(
nullptr
),
references
(
nullptr
),
dataSize
(
0
),
referenceCount
(
0
),
bit0Offset
(
0
*
BITS
),
nestingLimit
(
0
)
{}
referenceCount
(
0
),
bit0Offset
(
0
*
BITS
),
nestingLimit
(
0
)
{}
static
StructReader
readRootTrusted
(
const
word
*
location
,
const
word
*
defaultValue
);
static
StructReader
readRootTrusted
(
const
word
*
location
);
static
StructReader
readRoot
(
const
word
*
location
,
const
word
*
defaultValue
,
static
StructReader
readRoot
(
const
word
*
location
,
SegmentReader
*
segment
,
int
nestingLimit
);
SegmentReader
*
segment
,
int
nestingLimit
);
static
StructReader
readEmpty
(
);
template
<
typename
T
>
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
CAPNPROTO_ALWAYS_INLINE
(
T
getDataField
(
ElementCount
offset
)
const
);
T
getDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
defaultValue
)
const
);
// Get the data field value of the given type at the given offset. The offset is measured in
// Get the data field value of the given type at the given offset. The offset is measured in
// multiples of the field size, determined by the type. Returns the default value if the offset
// multiples of the field size, determined by the type. Returns zero if the offset is past the
// is past the end of the struct's data segment.
// end of the struct's data segment.
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
T
getDataField
(
ElementCount
offset
,
typename
MaskType
<
T
>::
Type
mask
)
const
);
// Like getDataField(offset), but applies the given XOR mask to the result. Used for reading
// fields with non-zero default values.
StructReader
getStructField
(
WireReferenceCount
refIndex
,
const
word
*
defaultValue
)
const
;
StructReader
getStructField
(
WireReferenceCount
refIndex
,
const
word
*
defaultValue
)
const
;
// Get the struct field at the given index in the reference segment, or the default value if not
// Get the struct field at the given index in the reference segment, or the default value if not
// initialized. defaultValue will be interpreted as a trusted message -- it must point at a
// initialized. defaultValue will be interpreted as a trusted message -- it must point at a
// struct reference, which in turn points at the struct value.
// struct reference, which in turn points at the struct value. The default value is allowed to
// be null, in which case an empty struct is used.
ListReader
getListField
(
WireReferenceCount
refIndex
,
FieldSize
expectedElementSize
,
ListReader
getListField
(
WireReferenceCount
refIndex
,
FieldSize
expectedElementSize
,
const
word
*
defaultValue
)
const
;
const
word
*
defaultValue
)
const
;
...
@@ -322,11 +423,9 @@ public:
...
@@ -322,11 +423,9 @@ public:
// to zero.
// to zero.
ListBuilder
initStructListElement
(
WireReferenceCount
index
,
ElementCount
elementCount
,
ListBuilder
initStructListElement
(
WireReferenceCount
index
,
ElementCount
elementCount
,
const
word
*
elementDefaultValu
e
)
const
;
StructSize
siz
e
)
const
;
// Allocates a new list of the given size for the field at the given index in the reference
// Allocates a new list of the given size for the field at the given index in the reference
// segment, and return a pointer to it. Each element is initialized as a copy of
// segment, and return a pointer to it. Each element is initialized to its empty state.
// elementDefaultValue. As with StructBuilder::initStructListElement(), this should be the
// default value for the *type*, with all-null references.
ListBuilder
getListElement
(
WireReferenceCount
index
)
const
;
ListBuilder
getListElement
(
WireReferenceCount
index
)
const
;
// Get the existing list element at the given index. Returns an empty list if the element is
// Get the existing list element at the given index. Returns an empty list if the element is
...
@@ -378,7 +477,7 @@ public:
...
@@ -378,7 +477,7 @@ public:
CAPNPROTO_ALWAYS_INLINE
(
T
getDataElement
(
ElementCount
index
)
const
);
CAPNPROTO_ALWAYS_INLINE
(
T
getDataElement
(
ElementCount
index
)
const
);
// Get the element of the given type at the given index.
// Get the element of the given type at the given index.
StructReader
getStructElement
(
ElementCount
index
,
const
word
*
defaultValue
)
const
;
StructReader
getStructElement
(
ElementCount
index
)
const
;
// Get the struct element at the given index.
// Get the struct element at the given index.
ListReader
getListElement
(
WireReferenceCount
index
,
FieldSize
expectedElementSize
)
const
;
ListReader
getListElement
(
WireReferenceCount
index
,
FieldSize
expectedElementSize
)
const
;
...
@@ -451,6 +550,11 @@ inline Void StructBuilder::getDataField<Void>(ElementCount offset) const {
...
@@ -451,6 +550,11 @@ inline Void StructBuilder::getDataField<Void>(ElementCount offset) const {
return
Void
::
VOID
;
return
Void
::
VOID
;
}
}
template
<
typename
T
>
inline
T
StructBuilder
::
getDataField
(
ElementCount
offset
,
typename
MaskType
<
T
>::
Type
mask
)
const
{
return
unmask
<
T
>
(
getDataField
<
typename
MaskType
<
T
>::
Type
>
(
offset
),
mask
);
}
template
<
typename
T
>
template
<
typename
T
>
inline
void
StructBuilder
::
setDataField
(
inline
void
StructBuilder
::
setDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
value
)
const
{
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
value
)
const
{
...
@@ -469,19 +573,25 @@ inline void StructBuilder::setDataField<bool>(ElementCount offset, bool value) c
...
@@ -469,19 +573,25 @@ inline void StructBuilder::setDataField<bool>(ElementCount offset, bool value) c
template
<>
template
<>
inline
void
StructBuilder
::
setDataField
<
Void
>
(
ElementCount
offset
,
Void
value
)
const
{}
inline
void
StructBuilder
::
setDataField
<
Void
>
(
ElementCount
offset
,
Void
value
)
const
{}
template
<
typename
T
>
inline
void
StructBuilder
::
setDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
value
,
typename
MaskType
<
T
>::
Type
m
)
const
{
setDataField
<
typename
MaskType
<
T
>::
Type
>
(
offset
,
mask
<
T
>
(
value
,
m
));
}
// -------------------------------------------------------------------
// -------------------------------------------------------------------
template
<
typename
T
>
template
<
typename
T
>
T
StructReader
::
getDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
defaultValue
)
const
{
T
StructReader
::
getDataField
(
ElementCount
offset
)
const
{
if
(
offset
*
bytesPerElement
<
T
>
()
<
dataSize
*
BYTES_PER_WORD
)
{
if
(
offset
*
bytesPerElement
<
T
>
()
<
dataSize
*
BYTES_PER_WORD
)
{
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
data
)[
offset
/
ELEMENTS
].
get
();
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
data
)[
offset
/
ELEMENTS
].
get
();
}
else
{
}
else
{
return
defaultValue
;
return
static_cast
<
T
>
(
0
)
;
}
}
}
}
template
<>
template
<>
inline
bool
StructReader
::
getDataField
<
bool
>
(
ElementCount
offset
,
bool
defaultValue
)
const
{
inline
bool
StructReader
::
getDataField
<
bool
>
(
ElementCount
offset
)
const
{
BitCount
boffset
=
offset
*
(
1
*
BITS
/
ELEMENTS
);
BitCount
boffset
=
offset
*
(
1
*
BITS
/
ELEMENTS
);
// This branch should always be optimized away when inlining.
// This branch should always be optimized away when inlining.
...
@@ -491,15 +601,20 @@ inline bool StructReader::getDataField<bool>(ElementCount offset, bool defaultVa
...
@@ -491,15 +601,20 @@ inline bool StructReader::getDataField<bool>(ElementCount offset, bool defaultVa
const
byte
*
b
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
boffset
/
BITS_PER_BYTE
;
const
byte
*
b
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
boffset
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
const
uint8_t
*>
(
b
)
&
(
1
<<
(
boffset
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
return
(
*
reinterpret_cast
<
const
uint8_t
*>
(
b
)
&
(
1
<<
(
boffset
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
}
else
{
}
else
{
return
defaultValu
e
;
return
fals
e
;
}
}
}
}
template
<>
template
<>
inline
Void
StructReader
::
getDataField
<
Void
>
(
ElementCount
offset
,
Void
defaultValue
)
const
{
inline
Void
StructReader
::
getDataField
<
Void
>
(
ElementCount
offset
)
const
{
return
Void
::
VOID
;
return
Void
::
VOID
;
}
}
template
<
typename
T
>
T
StructReader
::
getDataField
(
ElementCount
offset
,
typename
MaskType
<
T
>::
Type
mask
)
const
{
return
unmask
<
T
>
(
getDataField
<
typename
MaskType
<
T
>::
Type
>
(
offset
),
mask
);
}
// -------------------------------------------------------------------
// -------------------------------------------------------------------
inline
ElementCount
ListBuilder
::
size
()
{
return
elementCount
;
}
inline
ElementCount
ListBuilder
::
size
()
{
return
elementCount
;
}
...
...
c++/src/capnproto/list.h
View file @
f966fc41
...
@@ -216,7 +216,7 @@ struct List<T, false> {
...
@@ -216,7 +216,7 @@ struct List<T, false> {
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
typename
T
::
Reader
operator
[](
uint
index
)
{
inline
typename
T
::
Reader
operator
[](
uint
index
)
{
return
typename
T
::
Reader
(
reader
.
getStructElement
(
index
*
ELEMENTS
,
T
::
DEFAULT
.
words
));
return
typename
T
::
Reader
(
reader
.
getStructElement
(
index
*
ELEMENTS
));
}
}
typedef
internal
::
IndexingIterator
<
Reader
,
typename
T
::
Reader
>
iterator
;
typedef
internal
::
IndexingIterator
<
Reader
,
typename
T
::
Reader
>
iterator
;
...
@@ -235,8 +235,7 @@ struct List<T, false> {
...
@@ -235,8 +235,7 @@ struct List<T, false> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
T
::
Builder
operator
[](
uint
index
)
{
inline
typename
T
::
Builder
operator
[](
uint
index
)
{
return
typename
T
::
Builder
(
builder
.
getStructElement
(
index
*
ELEMENTS
,
return
typename
T
::
Builder
(
builder
.
getStructElement
(
index
*
ELEMENTS
,
(
T
::
DATA_SIZE
+
T
::
REFERENCE_COUNT
*
WORDS_PER_REFERENCE
)
/
ELEMENTS
,
T
::
STRUCT_SIZE
.
total
()
/
ELEMENTS
,
T
::
STRUCT_SIZE
.
data
));
T
::
DATA_SIZE
));
}
}
typedef
internal
::
IndexingIterator
<
Builder
,
typename
T
::
Builder
>
iterator
;
typedef
internal
::
IndexingIterator
<
Builder
,
typename
T
::
Builder
>
iterator
;
...
...
c++/src/capnproto/message.c++
View file @
f966fc41
...
@@ -38,7 +38,7 @@ MessageReader::~MessageReader() {
...
@@ -38,7 +38,7 @@ MessageReader::~MessageReader() {
}
}
}
}
internal
::
StructReader
MessageReader
::
getRoot
(
const
word
*
defaultValue
)
{
internal
::
StructReader
MessageReader
::
getRoot
Internal
(
)
{
if
(
!
allocatedArena
)
{
if
(
!
allocatedArena
)
{
static_assert
(
sizeof
(
internal
::
ReaderArena
)
<=
sizeof
(
arenaSpace
),
static_assert
(
sizeof
(
internal
::
ReaderArena
)
<=
sizeof
(
arenaSpace
),
"arenaSpace is too small to hold a ReaderArena. Please increase it. This will break "
"arenaSpace is too small to hold a ReaderArena. Please increase it. This will break "
...
@@ -51,10 +51,9 @@ internal::StructReader MessageReader::getRoot(const word* defaultValue) {
...
@@ -51,10 +51,9 @@ internal::StructReader MessageReader::getRoot(const word* defaultValue) {
if
(
segment
==
nullptr
||
if
(
segment
==
nullptr
||
!
segment
->
containsInterval
(
segment
->
getStartPtr
(),
segment
->
getStartPtr
()
+
1
))
{
!
segment
->
containsInterval
(
segment
->
getStartPtr
(),
segment
->
getStartPtr
()
+
1
))
{
arena
()
->
reportInvalidData
(
"Message did not contain a root pointer."
);
arena
()
->
reportInvalidData
(
"Message did not contain a root pointer."
);
return
internal
::
StructReader
::
read
RootTrusted
(
defaultValue
,
defaultValue
);
return
internal
::
StructReader
::
read
Empty
(
);
}
else
{
}
else
{
return
internal
::
StructReader
::
readRoot
(
return
internal
::
StructReader
::
readRoot
(
segment
->
getStartPtr
(),
segment
,
options
.
nestingLimit
);
segment
->
getStartPtr
(),
defaultValue
,
segment
,
options
.
nestingLimit
);
}
}
}
}
...
@@ -88,16 +87,16 @@ internal::SegmentBuilder* MessageBuilder::getRootSegment() {
...
@@ -88,16 +87,16 @@ internal::SegmentBuilder* MessageBuilder::getRootSegment() {
}
}
}
}
internal
::
StructBuilder
MessageBuilder
::
initRoot
(
const
word
*
defaultValu
e
)
{
internal
::
StructBuilder
MessageBuilder
::
initRoot
(
internal
::
StructSize
siz
e
)
{
internal
::
SegmentBuilder
*
rootSegment
=
getRootSegment
();
internal
::
SegmentBuilder
*
rootSegment
=
getRootSegment
();
return
internal
::
StructBuilder
::
initRoot
(
return
internal
::
StructBuilder
::
initRoot
(
rootSegment
,
rootSegment
->
getPtrUnchecked
(
0
*
WORDS
),
defaultValu
e
);
rootSegment
,
rootSegment
->
getPtrUnchecked
(
0
*
WORDS
),
siz
e
);
}
}
internal
::
StructBuilder
MessageBuilder
::
getRoot
(
const
word
*
defaultValu
e
)
{
internal
::
StructBuilder
MessageBuilder
::
getRoot
(
internal
::
StructSize
siz
e
)
{
internal
::
SegmentBuilder
*
rootSegment
=
getRootSegment
();
internal
::
SegmentBuilder
*
rootSegment
=
getRootSegment
();
return
internal
::
StructBuilder
::
getRoot
(
return
internal
::
StructBuilder
::
getRoot
(
rootSegment
,
rootSegment
->
getPtrUnchecked
(
0
*
WORDS
),
defaultValu
e
);
rootSegment
,
rootSegment
->
getPtrUnchecked
(
0
*
WORDS
),
siz
e
);
}
}
ArrayPtr
<
const
ArrayPtr
<
const
word
>>
MessageBuilder
::
getSegmentsForOutput
()
{
ArrayPtr
<
const
ArrayPtr
<
const
word
>>
MessageBuilder
::
getSegmentsForOutput
()
{
...
...
c++/src/capnproto/message.h
View file @
f966fc41
...
@@ -144,7 +144,7 @@ private:
...
@@ -144,7 +144,7 @@ private:
bool
allocatedArena
;
bool
allocatedArena
;
internal
::
ReaderArena
*
arena
()
{
return
reinterpret_cast
<
internal
::
ReaderArena
*>
(
arenaSpace
);
}
internal
::
ReaderArena
*
arena
()
{
return
reinterpret_cast
<
internal
::
ReaderArena
*>
(
arenaSpace
);
}
internal
::
StructReader
getRoot
(
const
word
*
defaultValue
);
internal
::
StructReader
getRoot
Internal
(
);
};
};
class
MessageBuilder
{
class
MessageBuilder
{
...
@@ -175,8 +175,8 @@ private:
...
@@ -175,8 +175,8 @@ private:
internal
::
BuilderArena
*
arena
()
{
return
reinterpret_cast
<
internal
::
BuilderArena
*>
(
arenaSpace
);
}
internal
::
BuilderArena
*
arena
()
{
return
reinterpret_cast
<
internal
::
BuilderArena
*>
(
arenaSpace
);
}
internal
::
SegmentBuilder
*
getRootSegment
();
internal
::
SegmentBuilder
*
getRootSegment
();
internal
::
StructBuilder
initRoot
(
const
word
*
defaultValu
e
);
internal
::
StructBuilder
initRoot
(
internal
::
StructSize
siz
e
);
internal
::
StructBuilder
getRoot
(
const
word
*
defaultValu
e
);
internal
::
StructBuilder
getRoot
(
internal
::
StructSize
siz
e
);
};
};
template
<
typename
RootType
>
template
<
typename
RootType
>
...
@@ -297,23 +297,22 @@ inline const ReaderOptions& MessageReader::getOptions() {
...
@@ -297,23 +297,22 @@ inline const ReaderOptions& MessageReader::getOptions() {
template
<
typename
RootType
>
template
<
typename
RootType
>
inline
typename
RootType
::
Reader
MessageReader
::
getRoot
()
{
inline
typename
RootType
::
Reader
MessageReader
::
getRoot
()
{
return
typename
RootType
::
Reader
(
getRoot
(
RootType
::
DEFAULT
.
words
));
return
typename
RootType
::
Reader
(
getRoot
Internal
(
));
}
}
template
<
typename
RootType
>
template
<
typename
RootType
>
inline
typename
RootType
::
Builder
MessageBuilder
::
initRoot
()
{
inline
typename
RootType
::
Builder
MessageBuilder
::
initRoot
()
{
return
typename
RootType
::
Builder
(
initRoot
(
RootType
::
DEFAULT
.
words
));
return
typename
RootType
::
Builder
(
initRoot
(
RootType
::
STRUCT_SIZE
));
}
}
template
<
typename
RootType
>
template
<
typename
RootType
>
inline
typename
RootType
::
Builder
MessageBuilder
::
getRoot
()
{
inline
typename
RootType
::
Builder
MessageBuilder
::
getRoot
()
{
return
typename
RootType
::
Builder
(
getRoot
(
RootType
::
DEFAULT
.
words
));
return
typename
RootType
::
Builder
(
getRoot
(
RootType
::
STRUCT_SIZE
));
}
}
template
<
typename
RootType
>
template
<
typename
RootType
>
typename
RootType
::
Reader
readMessageTrusted
(
const
word
*
data
)
{
typename
RootType
::
Reader
readMessageTrusted
(
const
word
*
data
)
{
return
typename
RootType
::
Reader
(
internal
::
StructReader
::
readRootTrusted
(
return
typename
RootType
::
Reader
(
internal
::
StructReader
::
readRootTrusted
(
data
));
data
,
RootType
::
DEFAULT
.
words
));
}
}
}
// namespace capnproto
}
// namespace capnproto
...
...
c++/src/capnproto/test.capnp
View file @
f966fc41
...
@@ -67,7 +67,7 @@ struct TestAllTypes {
...
@@ -67,7 +67,7 @@ struct TestAllTypes {
dataList @30 : List(Data);
dataList @30 : List(Data);
structList @31 : List(TestAllTypes);
structList @31 : List(TestAllTypes);
enumList @32 : List(TestEnum);
enumList @32 : List(TestEnum);
interfaceList @33 :
Void
; # TODO
interfaceList @33 :
List(Void)
; # TODO
}
}
struct TestDefaults {
struct TestDefaults {
...
...
compiler/src/CxxGenerator.hs
View file @
f966fc41
...
@@ -29,6 +29,7 @@ import qualified Data.ByteString.UTF8 as ByteStringUTF8
...
@@ -29,6 +29,7 @@ import qualified Data.ByteString.UTF8 as ByteStringUTF8
import
Data.FileEmbed
(
embedFile
)
import
Data.FileEmbed
(
embedFile
)
import
Data.Word
(
Word8
)
import
Data.Word
(
Word8
)
import
qualified
Data.Digest.MD5
as
MD5
import
qualified
Data.Digest.MD5
as
MD5
import
Data.Binary.IEEE754
(
floatToWord
,
doubleToWord
)
import
Text.Printf
(
printf
)
import
Text.Printf
(
printf
)
import
Text.Hastache
import
Text.Hastache
import
Text.Hastache.Context
import
Text.Hastache.Context
...
@@ -106,25 +107,41 @@ cxxFieldSizeString Size64 = "EIGHT_BYTES";
...
@@ -106,25 +107,41 @@ cxxFieldSizeString Size64 = "EIGHT_BYTES";
cxxFieldSizeString
SizeReference
=
"REFERENCE"
;
cxxFieldSizeString
SizeReference
=
"REFERENCE"
;
cxxFieldSizeString
(
SizeInlineComposite
_
_
)
=
"INLINE_COMPOSITE"
;
cxxFieldSizeString
(
SizeInlineComposite
_
_
)
=
"INLINE_COMPOSITE"
;
cxxValueString
VoidDesc
=
" ::capnproto::Void::VOID"
isDefaultZero
VoidDesc
=
True
cxxValueString
(
BoolDesc
b
)
=
if
b
then
"true"
else
"false"
isDefaultZero
(
BoolDesc
b
)
=
not
b
cxxValueString
(
Int8Desc
i
)
=
show
i
isDefaultZero
(
Int8Desc
i
)
=
i
==
0
cxxValueString
(
Int16Desc
i
)
=
show
i
isDefaultZero
(
Int16Desc
i
)
=
i
==
0
cxxValueString
(
Int32Desc
i
)
=
show
i
isDefaultZero
(
Int32Desc
i
)
=
i
==
0
cxxValueString
(
Int64Desc
i
)
=
show
i
++
"ll"
isDefaultZero
(
Int64Desc
i
)
=
i
==
0
cxxValueString
(
UInt8Desc
i
)
=
show
i
isDefaultZero
(
UInt8Desc
i
)
=
i
==
0
cxxValueString
(
UInt16Desc
i
)
=
show
i
isDefaultZero
(
UInt16Desc
i
)
=
i
==
0
cxxValueString
(
UInt32Desc
i
)
=
show
i
++
"u"
isDefaultZero
(
UInt32Desc
i
)
=
i
==
0
cxxValueString
(
UInt64Desc
i
)
=
show
i
++
"llu"
isDefaultZero
(
UInt64Desc
i
)
=
i
==
0
cxxValueString
(
Float32Desc
x
)
=
show
x
++
"f"
isDefaultZero
(
Float32Desc
x
)
=
x
==
0
cxxValueString
(
Float64Desc
x
)
=
show
x
isDefaultZero
(
Float64Desc
x
)
=
x
==
0
cxxValueString
(
EnumValueValueDesc
v
)
=
isDefaultZero
(
EnumValueValueDesc
v
)
=
enumValueNumber
v
==
0
cxxTypeString
(
EnumType
$
enumValueParent
v
)
++
"::"
++
isDefaultZero
(
TextDesc
_
)
=
error
"Can't call isDefaultZero on aggregate types."
toUpperCaseWithUnderscores
(
enumValueName
v
)
isDefaultZero
(
DataDesc
_
)
=
error
"Can't call isDefaultZero on aggregate types."
cxxValueString
(
TextDesc
_
)
=
error
"No default value literal for aggregate type."
isDefaultZero
(
StructValueDesc
_
)
=
error
"Can't call isDefaultZero on aggregate types."
cxxValueString
(
DataDesc
_
)
=
error
"No default value literal for aggregate type."
isDefaultZero
(
ListDesc
_
)
=
error
"Can't call isDefaultZero on aggregate types."
cxxValueString
(
StructValueDesc
_
)
=
error
"No default value literal for aggregate type."
cxxValueString
(
ListDesc
_
)
=
error
"No default value literal for aggregate type."
defaultMask
VoidDesc
=
"0"
defaultMask
(
BoolDesc
b
)
=
if
b
then
"true"
else
"false"
defaultMask
(
Int8Desc
i
)
=
show
i
defaultMask
(
Int16Desc
i
)
=
show
i
defaultMask
(
Int32Desc
i
)
=
show
i
defaultMask
(
Int64Desc
i
)
=
show
i
++
"ll"
defaultMask
(
UInt8Desc
i
)
=
show
i
defaultMask
(
UInt16Desc
i
)
=
show
i
defaultMask
(
UInt32Desc
i
)
=
show
i
++
"u"
defaultMask
(
UInt64Desc
i
)
=
show
i
++
"llu"
defaultMask
(
Float32Desc
x
)
=
show
(
floatToWord
x
)
++
"u"
defaultMask
(
Float64Desc
x
)
=
show
(
doubleToWord
x
)
++
"ul"
defaultMask
(
EnumValueValueDesc
v
)
=
show
(
enumValueNumber
v
)
defaultMask
(
TextDesc
_
)
=
error
"Can't call defaultMask on aggregate types."
defaultMask
(
DataDesc
_
)
=
error
"Can't call defaultMask on aggregate types."
defaultMask
(
StructValueDesc
_
)
=
error
"Can't call defaultMask on aggregate types."
defaultMask
(
ListDesc
_
)
=
error
"Can't call defaultMask on aggregate types."
defaultValueBytes
_
(
TextDesc
s
)
=
Just
(
UTF8
.
encode
s
++
[
0
])
defaultValueBytes
_
(
TextDesc
s
)
=
Just
(
UTF8
.
encode
s
++
[
0
])
defaultValueBytes
_
(
DataDesc
d
)
=
Just
d
defaultValueBytes
_
(
DataDesc
d
)
=
Just
d
...
@@ -132,25 +149,6 @@ defaultValueBytes t v@(StructValueDesc _) = Just $ encodeMessage t v
...
@@ -132,25 +149,6 @@ defaultValueBytes t v@(StructValueDesc _) = Just $ encodeMessage t v
defaultValueBytes
t
v
@
(
ListDesc
_
)
=
Just
$
encodeMessage
t
v
defaultValueBytes
t
v
@
(
ListDesc
_
)
=
Just
$
encodeMessage
t
v
defaultValueBytes
_
_
=
Nothing
defaultValueBytes
_
_
=
Nothing
cxxDefaultDefault
(
BuiltinType
BuiltinVoid
)
=
" ::capnproto::Void::VOID"
cxxDefaultDefault
(
BuiltinType
BuiltinBool
)
=
"false"
cxxDefaultDefault
(
BuiltinType
BuiltinInt8
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinInt16
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinInt32
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinInt64
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinUInt8
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinUInt16
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinUInt32
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinUInt64
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinFloat32
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinFloat64
)
=
"0"
cxxDefaultDefault
(
BuiltinType
BuiltinText
)
=
"
\"\"
"
cxxDefaultDefault
(
EnumType
desc
)
=
cxxValueString
$
EnumValueValueDesc
$
head
$
enumValues
desc
cxxDefaultDefault
(
BuiltinType
BuiltinData
)
=
error
"No default value literal for aggregate type."
cxxDefaultDefault
(
StructType
_
)
=
error
"No default value literal for aggregate type."
cxxDefaultDefault
(
InterfaceType
_
)
=
error
"No default value literal for aggregate type."
cxxDefaultDefault
(
ListType
_
)
=
error
"No default value literal for aggregate type."
elementType
(
ListType
t
)
=
t
elementType
(
ListType
t
)
=
t
elementType
_
=
error
"Called elementType on non-list."
elementType
_
=
error
"Called elementType on non-list."
...
@@ -197,9 +195,9 @@ fieldContext parent desc = mkStrContext context where
...
@@ -197,9 +195,9 @@ fieldContext parent desc = mkStrContext context where
context
"fieldType"
=
MuVariable
$
cxxTypeString
$
fieldType
desc
context
"fieldType"
=
MuVariable
$
cxxTypeString
$
fieldType
desc
context
"fieldBlobType"
=
MuVariable
$
blobTypeString
$
fieldType
desc
context
"fieldBlobType"
=
MuVariable
$
blobTypeString
$
fieldType
desc
context
"fieldOffset"
=
MuVariable
$
fieldOffset
desc
context
"fieldOffset"
=
MuVariable
$
fieldOffset
desc
context
"fieldDefault
Value
"
=
case
fieldDefaultValue
desc
of
context
"fieldDefault
Mask
"
=
case
fieldDefaultValue
desc
of
Just
v
->
MuVariable
$
cxxValueString
v
Nothing
->
MuVariable
""
Nothing
->
MuVariable
$
cxxDefaultDefault
$
fieldType
desc
Just
v
->
MuVariable
(
if
isDefaultZero
v
then
""
else
", "
++
defaultMask
v
)
context
"fieldElementSize"
=
context
"fieldElementSize"
=
MuVariable
$
cxxFieldSizeString
$
elementSize
$
elementType
$
fieldType
desc
MuVariable
$
cxxFieldSizeString
$
elementSize
$
elementType
$
fieldType
desc
context
"fieldElementType"
=
context
"fieldElementType"
=
...
@@ -212,8 +210,6 @@ structContext parent desc = mkStrContext context where
...
@@ -212,8 +210,6 @@ structContext parent desc = mkStrContext context where
context
"structDataSize"
=
MuVariable
$
packingDataSize
$
structPacking
desc
context
"structDataSize"
=
MuVariable
$
packingDataSize
$
structPacking
desc
context
"structReferenceCount"
=
MuVariable
$
packingReferenceCount
$
structPacking
desc
context
"structReferenceCount"
=
MuVariable
$
packingReferenceCount
$
structPacking
desc
context
"structChildren"
=
MuList
[]
-- TODO
context
"structChildren"
=
MuList
[]
-- TODO
context
"structDefault"
=
MuList
[
defaultBytesContext
context
(
StructType
desc
)
(
encodeMessage
(
StructType
desc
)
(
StructValueDesc
[]
))]
context
s
=
parent
s
context
s
=
parent
s
fileContext
desc
=
mkStrContext
context
where
fileContext
desc
=
mkStrContext
context
where
...
...
compiler/src/WireFormat.hs
View file @
f966fc41
...
@@ -25,8 +25,7 @@ module WireFormat(encodeMessage) where
...
@@ -25,8 +25,7 @@ module WireFormat(encodeMessage) where
import
Data.List
(
sortBy
,
genericLength
,
genericReplicate
)
import
Data.List
(
sortBy
,
genericLength
,
genericReplicate
)
import
Data.Word
import
Data.Word
import
Data.Bits
(
shiftL
,
shiftR
,
Bits
,
setBit
)
import
Data.Bits
(
shiftL
,
shiftR
,
Bits
,
setBit
,
xor
)
import
qualified
Data.Set
as
Set
import
Semantics
import
Semantics
import
Data.Binary.IEEE754
(
floatToWord
,
doubleToWord
)
import
Data.Binary.IEEE754
(
floatToWord
,
doubleToWord
)
import
qualified
Codec.Binary.UTF8.String
as
UTF8
import
qualified
Codec.Binary.UTF8.String
as
UTF8
...
@@ -69,27 +68,34 @@ encodeDataValue (EnumValueValueDesc v) = bytes (enumValueNumber v) 2
...
@@ -69,27 +68,34 @@ encodeDataValue (EnumValueValueDesc v) = bytes (enumValueNumber v) 2
encodeDataValue
(
StructValueDesc
_
)
=
error
"Not fixed-width data."
encodeDataValue
(
StructValueDesc
_
)
=
error
"Not fixed-width data."
encodeDataValue
(
ListDesc
_
)
=
error
"Not fixed-width data."
encodeDataValue
(
ListDesc
_
)
=
error
"Not fixed-width data."
packBits
::
Bits
a
=>
Int
->
[
Bool
]
->
a
encodeMaskedDataValue
v
Nothing
=
encodeDataValue
v
encodeMaskedDataValue
v
(
Just
d
)
=
zipWith
xor
(
encodeDataValue
v
)
(
encodeDataValue
d
)
packBits
::
Bits
a
=>
Int
->
[(
Bool
,
Maybe
Bool
)]
->
a
packBits
_
[]
=
0
packBits
_
[]
=
0
packBits
offset
(
True
:
bits
)
=
setBit
(
packBits
(
offset
+
1
)
bits
)
offset
packBits
offset
((
True
,
Nothing
)
:
bits
)
=
setBit
(
packBits
(
offset
+
1
)
bits
)
offset
packBits
offset
(
False
:
bits
)
=
packBits
(
offset
+
1
)
bits
packBits
offset
((
False
,
Nothing
)
:
bits
)
=
packBits
(
offset
+
1
)
bits
packBits
offset
((
b
,
Just
d
)
:
bits
)
=
packBits
offset
((
b
/=
d
,
Nothing
)
:
bits
)
encodeData
::
Integer
->
[(
Integer
,
TypeDesc
,
ValueDesc
)]
->
[
Word8
]
-- The tuples are (offsetInBits, type, value, defaultValue) for each field to encode.
encodeData
::
Integer
->
[(
Integer
,
TypeDesc
,
ValueDesc
,
Maybe
ValueDesc
)]
->
[
Word8
]
encodeData
size
=
loop
0
where
encodeData
size
=
loop
0
where
loop
bit
[]
|
bit
==
size
=
[]
loop
bit
[]
|
bit
==
size
=
[]
loop
bit
[]
|
bit
>
size
=
error
"Data values overran size."
loop
bit
[]
|
bit
>
size
=
error
"Data values overran size."
loop
bit
[]
=
0
:
loop
(
bit
+
8
)
[]
loop
bit
[]
=
0
:
loop
(
bit
+
8
)
[]
loop
bit
rest
@
((
valuePos
,
_
,
BoolDesc
_
)
:
_
)
|
valuePos
==
bit
=
let
loop
bit
rest
@
((
valuePos
,
_
,
BoolDesc
_
,
_
)
:
_
)
|
valuePos
==
bit
=
let
(
bits
,
rest2
)
=
popBits
(
bit
+
8
)
rest
(
bits
,
rest2
)
=
popBits
(
bit
+
8
)
rest
in
packBits
0
bits
:
loop
(
bit
+
8
)
rest2
in
packBits
0
bits
:
loop
(
bit
+
8
)
rest2
loop
bit
((
valuePos
,
_
,
value
)
:
rest
)
|
valuePos
==
bit
=
loop
bit
((
valuePos
,
_
,
value
,
defaultValue
)
:
rest
)
|
valuePos
==
bit
=
encodeDataValue
value
++
loop
(
bit
+
sizeInBits
(
fieldValueSize
value
))
rest
encodeMaskedDataValue
value
defaultValue
++
loop
bit
rest
@
((
valuePos
,
_
,
_
)
:
_
)
|
valuePos
>
bit
=
0
:
loop
(
bit
+
8
)
rest
loop
(
bit
+
sizeInBits
(
fieldValueSize
value
))
rest
loop
bit
rest
@
((
valuePos
,
_
,
_
,
_
)
:
_
)
|
valuePos
>
bit
=
0
:
loop
(
bit
+
8
)
rest
loop
_
_
=
error
"Data values were out-of-order."
loop
_
_
=
error
"Data values were out-of-order."
popBits
limit
((
valuePos
,
_
,
BoolDesc
b
)
:
rest
)
|
valuePos
<
limit
=
let
popBits
limit
((
valuePos
,
_
,
BoolDesc
b
,
d
)
:
rest
)
|
valuePos
<
limit
=
let
(
restBits
,
rest2
)
=
popBits
limit
rest
(
restBits
,
rest2
)
=
popBits
limit
rest
in
(
b
:
restBits
,
rest2
)
defaultB
=
fmap
(
\
(
BoolDesc
b2
)
->
b2
)
d
in
((
b
,
defaultB
)
:
restBits
,
rest2
)
popBits
_
rest
=
(
[]
,
rest
)
popBits
_
rest
=
(
[]
,
rest
)
encodeReferences
::
Integer
->
Integer
->
[(
Integer
,
TypeDesc
,
ValueDesc
)]
->
([
Word8
],
[
Word8
])
encodeReferences
::
Integer
->
Integer
->
[(
Integer
,
TypeDesc
,
ValueDesc
)]
->
([
Word8
],
[
Word8
])
...
@@ -156,10 +162,6 @@ fieldSizeEnum (SizeInlineComposite _ _) = 7
...
@@ -156,10 +162,6 @@ fieldSizeEnum (SizeInlineComposite _ _) = 7
structTag
=
0
structTag
=
0
listTag
=
1
listTag
=
1
-- Is this field a non-retroactive member of a union? If so, its default value is not written.
isNonRetroUnionMember
(
FieldDesc
{
fieldNumber
=
n
,
fieldUnion
=
Just
u
})
=
n
>
unionNumber
u
isNonRetroUnionMember
_
=
False
-- What is this union's default tag value? If there is a retroactive field, it is that field's
-- What is this union's default tag value? If there is a retroactive field, it is that field's
-- number, otherwise it is the union's number (meaning no field set).
-- number, otherwise it is the union's number (meaning no field set).
unionDefault
desc
=
UInt8Desc
$
fromIntegral
$
unionDefault
desc
=
UInt8Desc
$
fromIntegral
$
...
@@ -168,49 +170,24 @@ unionDefault desc = UInt8Desc $ fromIntegral $
...
@@ -168,49 +170,24 @@ unionDefault desc = UInt8Desc $ fromIntegral $
-- childOffset = number of words between the last reference and the location where children will
-- childOffset = number of words between the last reference and the location where children will
-- be allocated.
-- be allocated.
encodeStruct
desc
assignments
childOffset
=
(
dataBytes
,
referenceBytes
,
children
)
where
encodeStruct
desc
assignments
childOffset
=
(
dataBytes
,
referenceBytes
,
children
)
where
explicitlyAssignedNums
=
Set
.
fromList
[
fieldNumber
f
|
(
f
,
_
)
<-
assignments
]
explicitlyAssignedUnions
=
Set
.
fromList
[
unionNumber
u
|
(
FieldDesc
{
fieldUnion
=
Just
u
},
_
)
<-
assignments
]
-- Was this field explicitly assigned, or was another member of the same union explicitly
-- assigned? If so, its default value is not written.
isExplicitlyAssigned
(
FieldDesc
{
fieldNumber
=
n
,
fieldUnion
=
u
})
=
Set
.
member
n
explicitlyAssignedNums
||
maybe
False
(
flip
Set
.
member
explicitlyAssignedUnions
.
unionNumber
)
u
-- Values explicitly assigned.
-- Values explicitly assigned.
explicitValues
=
[(
fieldOffset
f
,
fieldType
f
,
v
)
|
(
f
,
v
)
<-
assignments
]
explicitValues
=
[(
fieldOffset
f
,
fieldType
f
,
v
,
fieldDefaultValue
f
)
|
(
f
,
v
)
<-
assignments
]
-- Values from defaults.
defaultValues
=
[(
o
,
fieldType
field
,
v
)
|
field
@
(
FieldDesc
{
fieldOffset
=
o
,
fieldDefaultValue
=
Just
v
})
<-
structFields
desc
-- Don't include default values for fields that were explicitly assigned.
,
not
$
isExplicitlyAssigned
field
-- Don't encode defaults for union members since they'd overwrite each other, and anyway
-- they wouldn't be valid unless the union tag specified them, which by default it doesn't,
-- except of course in the case of retroactively-added fields. So do include retro fields.
,
not
$
isNonRetroUnionMember
field
-- Don't encode defaults for references. Setting them to null has the same effect.
,
isDataFieldSize
$
fieldValueSize
v
]
-- Values of union tags.
-- Values of union tags.
unionValues
=
[(
unionTagOffset
u
,
BuiltinType
BuiltinUInt8
,
UInt8Desc
$
fromIntegral
n
)
unionValues
=
[(
unionTagOffset
u
,
BuiltinType
BuiltinUInt8
,
UInt8Desc
$
fromIntegral
n
,
Just
$
unionDefault
u
)
|
(
FieldDesc
{
fieldUnion
=
Just
u
,
fieldNumber
=
n
},
_
)
<-
assignments
]
|
(
FieldDesc
{
fieldUnion
=
Just
u
,
fieldNumber
=
n
},
_
)
<-
assignments
]
-- Default values of union tags.
allValues
=
explicitValues
++
unionValues
unionDefaultValues
=
[(
unionTagOffset
u
,
BuiltinType
BuiltinUInt8
,
unionDefault
u
)
allData
=
[
(
o
*
sizeInBits
(
fieldValueSize
v
),
t
,
v
,
d
)
|
u
<-
structUnions
desc
|
(
o
,
t
,
v
,
d
)
<-
allValues
,
isDataFieldSize
$
fieldValueSize
v
]
,
not
$
Set
.
member
(
unionNumber
u
)
explicitlyAssignedUnions
]
allReferences
=
[
(
o
,
t
,
v
)
|
(
o
,
t
,
v
,
_
)
<-
allValues
allValues
=
explicitValues
++
defaultValues
++
unionValues
++
unionDefaultValues
allData
=
[
(
o
*
sizeInBits
(
fieldValueSize
v
),
t
,
v
)
|
(
o
,
t
,
v
)
<-
allValues
,
isDataFieldSize
$
fieldValueSize
v
]
allReferences
=
[
(
o
,
t
,
v
)
|
(
o
,
t
,
v
)
<-
allValues
,
not
$
isDataFieldSize
$
fieldValueSize
v
]
,
not
$
isDataFieldSize
$
fieldValueSize
v
]
sortedData
=
sortBy
compareValues
allData
sortedData
=
sortBy
compareDataValues
allData
sortedReferences
=
sortBy
compareValues
allReferences
compareDataValues
(
o1
,
_
,
_
,
_
)
(
o2
,
_
,
_
,
_
)
=
compare
o1
o2
compareValues
(
o1
,
_
,
_
)
(
o2
,
_
,
_
)
=
compare
o1
o2
sortedReferences
=
sortBy
compareReferenceValues
allReferences
compareReferenceValues
(
o1
,
_
,
_
)
(
o2
,
_
,
_
)
=
compare
o1
o2
dataBytes
=
encodeData
(
packingDataSize
(
structPacking
desc
)
*
64
)
sortedData
dataBytes
=
encodeData
(
packingDataSize
(
structPacking
desc
)
*
64
)
sortedData
(
referenceBytes
,
children
)
=
encodeReferences
childOffset
(
referenceBytes
,
children
)
=
encodeReferences
childOffset
...
@@ -228,7 +205,7 @@ encodeList elementType elements = case elementSize elementType of
...
@@ -228,7 +205,7 @@ encodeList elementType elements = case elementSize elementType of
(
refBytes
,
childBytes
)
=
encodeReferences
0
(
genericLength
elements
)
(
refBytes
,
childBytes
)
=
encodeReferences
0
(
genericLength
elements
)
$
zipWith
(
\
i
v
->
(
i
,
elementType
,
v
))
[
0
..
]
elements
$
zipWith
(
\
i
v
->
(
i
,
elementType
,
v
))
[
0
..
]
elements
size
->
encodeData
(
roundUpToMultiple
64
(
genericLength
elements
*
sizeInBits
size
))
size
->
encodeData
(
roundUpToMultiple
64
(
genericLength
elements
*
sizeInBits
size
))
$
zipWith
(
\
i
v
->
(
i
*
sizeInBits
size
,
elementType
,
v
))
[
0
..
]
elements
$
zipWith
(
\
i
v
->
(
i
*
sizeInBits
size
,
elementType
,
v
,
Nothing
))
[
0
..
]
elements
encodeMessage
(
StructType
desc
)
(
StructValueDesc
assignments
)
=
let
encodeMessage
(
StructType
desc
)
(
StructValueDesc
assignments
)
=
let
(
dataBytes
,
refBytes
,
childBytes
)
=
encodeStruct
desc
assignments
0
(
dataBytes
,
refBytes
,
childBytes
)
=
encodeStruct
desc
assignments
0
...
...
compiler/src/c++-header.mustache
View file @
f966fc41
...
@@ -41,12 +41,9 @@ struct {{structName}} {
...
@@ -41,12 +41,9 @@ struct {{structName}} {
struct
{{
structChildName
}}
;
struct
{{
structChildName
}}
;
{{/
structChildren
}}
{{/
structChildren
}}
static constexpr ::capnproto::WordCount DATA_SIZE =
{{
structDataSize
}}
* ::capnproto::WORDS;
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
static constexpr ::capnproto::WireReferenceCount REFERENCE_COUNT =
::capnproto::internal::StructSize(
{{
structDataSize
}}
* ::capnproto::WORDS,
{{
structReferenceCount
}}
* ::capnproto::REFERENCES;
{{
structReferenceCount
}}
* ::capnproto::REFERENCES);
{{#
structDefault
}}
static const ::capnproto::internal::AlignedData
<
{{
defaultWordCount
}}
>
DEFAULT;
{{/
structDefault
}}
{{#
structFields
}}
{{#
structFields
}}
{{#
fieldDefaultBytes
}}
{{#
fieldDefaultBytes
}}
static const ::capnproto::internal::AlignedData
<
{{
defaultWordCount
}}
>
DEFAULT_
{{
fieldUpperCase
}}
;
static const ::capnproto::internal::AlignedData
<
{{
defaultWordCount
}}
>
DEFAULT_
{{
fieldUpperCase
}}
;
...
@@ -140,7 +137,7 @@ private:
...
@@ -140,7 +137,7 @@ private:
{{#
fieldIsPrimitive
}}
{{#
fieldIsPrimitive
}}
inline
{{
fieldType
}}
{{
structName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
inline
{{
fieldType
}}
{{
structName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
return _reader.getDataField
<
{{
fieldType
}}
>
(
return _reader.getDataField
<
{{
fieldType
}}
>
(
{{
fieldOffset
}}
* ::capnproto::ELEMENTS
,
{{
fieldDefaultValue
}}
);
{{
fieldOffset
}}
* ::capnproto::ELEMENTS
{{
fieldDefaultMask
}}
);
}
}
{{/
fieldIsPrimitive
}}
{{/
fieldIsPrimitive
}}
{{#
fieldIsBlob
}}
{{#
fieldIsBlob
}}
...
@@ -159,7 +156,7 @@ inline {{fieldType}}::Reader {{structName}}::Reader::get{{fieldTitleCase}}() {
...
@@ -159,7 +156,7 @@ inline {{fieldType}}::Reader {{structName}}::Reader::get{{fieldTitleCase}}() {
return
{{
fieldType
}}
::Reader(_reader.getStructField(
return
{{
fieldType
}}
::Reader(_reader.getStructField(
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}
{{
fieldType
}}
::DEFAULT.words
{{/
fieldDefaultBytes
}}
));
{{^
fieldDefaultBytes
}}
nullptr
{{/
fieldDefaultBytes
}}
));
}
}
{{/
fieldIsStruct
}}
{{/
fieldIsStruct
}}
{{#
fieldIsList
}}
{{#
fieldIsList
}}
...
@@ -179,11 +176,12 @@ inline {{fieldType}}::Reader {{structName}}::Reader::get{{fieldTitleCase}}() {
...
@@ -179,11 +176,12 @@ inline {{fieldType}}::Reader {{structName}}::Reader::get{{fieldTitleCase}}() {
//
{{
structName
}}
.
{{
fieldDecl
}}
//
{{
structName
}}
.
{{
fieldDecl
}}
{{#
fieldIsPrimitive
}}
{{#
fieldIsPrimitive
}}
inline
{{
fieldType
}}
{{
structName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
inline
{{
fieldType
}}
{{
structName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
return _builder.getDataField
<
{{
fieldType
}}
>
(
{{
fieldOffset
}}
* ::capnproto::ELEMENTS);
return _builder.getDataField
<
{{
fieldType
}}
>
(
{{
fieldOffset
}}
* ::capnproto::ELEMENTS
{{
fieldDefaultMask
}}
);
}
}
inline void
{{
structName
}}
::Builder::set
{{
fieldTitleCase
}}
(
{{
fieldType
}}
value) {
inline void
{{
structName
}}
::Builder::set
{{
fieldTitleCase
}}
(
{{
fieldType
}}
value) {
return _builder.setDataField
<
{{
fieldType
}}
>
(
return _builder.setDataField
<
{{
fieldType
}}
>
(
{{
fieldOffset
}}
* ::capnproto::ELEMENTS, value);
{{
fieldOffset
}}
* ::capnproto::ELEMENTS, value
{{
fieldDefaultMask
}}
);
}
}
{{/
fieldIsPrimitive
}}
{{/
fieldIsPrimitive
}}
{{#
fieldIsBlob
}}
{{#
fieldIsBlob
}}
...
@@ -205,14 +203,14 @@ inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}(un
...
@@ -205,14 +203,14 @@ inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}(un
{{#
fieldIsStruct
}}
{{#
fieldIsStruct
}}
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::init
{{
fieldTitleCase
}}
() {
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::init
{{
fieldTitleCase
}}
() {
return
{{
fieldType
}}
::Builder(_builder.initStructField(
return
{{
fieldType
}}
::Builder(_builder.initStructField(
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{
fieldType
}}
::
DEFAULT.words
));
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{
fieldType
}}
::
STRUCT_SIZE
));
}
}
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
{{! TODO: Support per-field default values. }}
{{! TODO: Support per-field default values. }}
return
{{
fieldType
}}
::Builder(_builder.getStructField(
return
{{
fieldType
}}
::Builder(_builder.getStructField(
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{
fieldType
}}
::STRUCT_SIZE,
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}
{{
fieldType
}}
::DEFAULT.words
{{/
fieldDefaultBytes
}}
));
{{^
fieldDefaultBytes
}}
nullptr
{{/
fieldDefaultBytes
}}
));
}
}
{{/
fieldIsStruct
}}
{{/
fieldIsStruct
}}
{{#
fieldIsNonStructList
}}
{{#
fieldIsNonStructList
}}
...
@@ -249,7 +247,7 @@ inline void {{structName}}::Builder::set{{fieldTitleCase}}(
...
@@ -249,7 +247,7 @@ inline void {{structName}}::Builder::set{{fieldTitleCase}}(
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::init
{{
fieldTitleCase
}}
(unsigned int size) {
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::init
{{
fieldTitleCase
}}
(unsigned int size) {
return
{{
fieldType
}}
::Builder(_builder.initStructListField(
return
{{
fieldType
}}
::Builder(_builder.initStructListField(
{{
fieldOffset
}}
* ::capnproto::REFERENCES, size * ::capnproto::ELEMENTS,
{{
fieldOffset
}}
* ::capnproto::REFERENCES, size * ::capnproto::ELEMENTS,
{{
fieldElementType
}}
::
DEFAULT.words
));
{{
fieldElementType
}}
::
STRUCT_SIZE
));
}
}
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
return
{{
fieldType
}}
::Builder(_builder.getListField(
return
{{
fieldType
}}
::Builder(_builder.getListField(
...
...
compiler/src/c++-source.mustache
View file @
f966fc41
...
@@ -32,13 +32,7 @@ namespace {{namespaceName}} {
...
@@ -32,13 +32,7 @@ namespace {{namespaceName}} {
{{/
fileNamespaces
}}
{{/
fileNamespaces
}}
{{#
fileStructs
}}
{{#
fileStructs
}}
constexpr ::capnproto::WordCount
{{
structName
}}
::DATA_SIZE;
constexpr ::capnproto::internal::StructSize
{{
structName
}}
::STRUCT_SIZE;
constexpr ::capnproto::WireReferenceCount
{{
structName
}}
::REFERENCE_COUNT;
{{#
structDefault
}}
const ::capnproto::internal::AlignedData
<
{{
defaultWordCount
}}
>
{{
structName
}}
::DEFAULT = {
{
{{
defaultByteList
}}
}
};
{{/
structDefault
}}
{{#
structFields
}}
{{#
structFields
}}
{{#
fieldDefaultBytes
}}
{{#
fieldDefaultBytes
}}
...
...
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