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
eab15190
Commit
eab15190
authored
Apr 26, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Runtime support and tests for inline lists.
parent
13ab0872
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
781 additions
and
152 deletions
+781
-152
encoding-test.c++
c++/src/capnproto/encoding-test.c++
+178
-0
layout-test.c++
c++/src/capnproto/layout-test.c++
+15
-13
layout.c++
c++/src/capnproto/layout.c++
+96
-53
layout.h
c++/src/capnproto/layout.h
+205
-57
list.h
c++/src/capnproto/list.h
+14
-15
test.capnp
c++/src/capnproto/test.capnp
+78
-2
type-safety.h
c++/src/capnproto/type-safety.h
+15
-0
Compiler.hs
compiler/src/Compiler.hs
+19
-2
CxxGenerator.hs
compiler/src/CxxGenerator.hs
+28
-0
Semantics.hs
compiler/src/Semantics.hs
+3
-2
WireFormat.hs
compiler/src/WireFormat.hs
+5
-2
c++-header.mustache
compiler/src/c++-header.mustache
+125
-6
No files found.
c++/src/capnproto/encoding-test.c++
View file @
eab15190
...
...
@@ -594,6 +594,184 @@ TEST(Encoding, InlineDefaults) {
EXPECT_EQ
(
"qux"
,
unions
.
getUnion3
().
getF16p
().
getP0
());
EXPECT_EQ
(
"quux"
,
unions
.
getUnion3
().
getF16p
().
getP1
());
}
{
auto
lists
=
reader
.
getLists
();
ASSERT_EQ
(
2u
,
lists
.
getVoidList
().
size
());
ASSERT_EQ
(
3u
,
lists
.
getBoolList
().
size
());
ASSERT_EQ
(
4u
,
lists
.
getUInt8List
().
size
());
ASSERT_EQ
(
5u
,
lists
.
getUInt16List
().
size
());
ASSERT_EQ
(
6u
,
lists
.
getUInt32List
().
size
());
ASSERT_EQ
(
7u
,
lists
.
getUInt64List
().
size
());
ASSERT_EQ
(
8u
,
lists
.
getTextList
().
size
());
ASSERT_EQ
(
2u
,
lists
.
getStructList0
().
size
());
ASSERT_EQ
(
3u
,
lists
.
getStructList1
().
size
());
ASSERT_EQ
(
4u
,
lists
.
getStructList8
().
size
());
ASSERT_EQ
(
2u
,
lists
.
getStructList16
().
size
());
ASSERT_EQ
(
3u
,
lists
.
getStructList32
().
size
());
ASSERT_EQ
(
4u
,
lists
.
getStructList64
().
size
());
ASSERT_EQ
(
2u
,
lists
.
getStructList128
().
size
());
ASSERT_EQ
(
3u
,
lists
.
getStructList192
().
size
());
ASSERT_EQ
(
4u
,
lists
.
getStructList0p
().
size
());
ASSERT_EQ
(
2u
,
lists
.
getStructList1p
().
size
());
ASSERT_EQ
(
3u
,
lists
.
getStructList8p
().
size
());
ASSERT_EQ
(
4u
,
lists
.
getStructList16p
().
size
());
ASSERT_EQ
(
2u
,
lists
.
getStructList32p
().
size
());
ASSERT_EQ
(
3u
,
lists
.
getStructList64p
().
size
());
ASSERT_EQ
(
4u
,
lists
.
getStructList128p
().
size
());
ASSERT_EQ
(
2u
,
lists
.
getStructList192p
().
size
());
EXPECT_EQ
(
Void
::
VOID
,
lists
.
getVoidList
()[
0
]);
EXPECT_EQ
(
Void
::
VOID
,
lists
.
getVoidList
()[
1
]);
EXPECT_FALSE
(
lists
.
getBoolList
()[
0
]);
EXPECT_TRUE
(
lists
.
getBoolList
()[
1
]);
EXPECT_FALSE
(
lists
.
getBoolList
()[
2
]);
EXPECT_EQ
(
12u
,
lists
.
getUInt8List
()[
0
]);
EXPECT_EQ
(
34u
,
lists
.
getUInt8List
()[
1
]);
EXPECT_EQ
(
56u
,
lists
.
getUInt8List
()[
2
]);
EXPECT_EQ
(
78u
,
lists
.
getUInt8List
()[
3
]);
EXPECT_EQ
(
1234u
,
lists
.
getUInt16List
()[
0
]);
EXPECT_EQ
(
5678u
,
lists
.
getUInt16List
()[
1
]);
EXPECT_EQ
(
9012u
,
lists
.
getUInt16List
()[
2
]);
EXPECT_EQ
(
3456u
,
lists
.
getUInt16List
()[
3
]);
EXPECT_EQ
(
7890u
,
lists
.
getUInt16List
()[
4
]);
EXPECT_EQ
(
123456789u
,
lists
.
getUInt32List
()[
0
]);
EXPECT_EQ
(
234567890u
,
lists
.
getUInt32List
()[
1
]);
EXPECT_EQ
(
345678901u
,
lists
.
getUInt32List
()[
2
]);
EXPECT_EQ
(
456789012u
,
lists
.
getUInt32List
()[
3
]);
EXPECT_EQ
(
567890123u
,
lists
.
getUInt32List
()[
4
]);
EXPECT_EQ
(
678901234u
,
lists
.
getUInt32List
()[
5
]);
for
(
uint
i
=
0
;
i
<
7
;
i
++
)
{
EXPECT_EQ
(
i
+
1
,
lists
.
getUInt64List
()[
i
]);
}
EXPECT_EQ
(
"foo"
,
lists
.
getTextList
()[
0
]);
EXPECT_EQ
(
"bar"
,
lists
.
getTextList
()[
1
]);
EXPECT_EQ
(
"baz"
,
lists
.
getTextList
()[
2
]);
EXPECT_EQ
(
"qux"
,
lists
.
getTextList
()[
3
]);
EXPECT_EQ
(
"quux"
,
lists
.
getTextList
()[
4
]);
EXPECT_EQ
(
"corge"
,
lists
.
getTextList
()[
5
]);
EXPECT_EQ
(
"grault"
,
lists
.
getTextList
()[
6
]);
EXPECT_EQ
(
"garply"
,
lists
.
getTextList
()[
7
]);
EXPECT_EQ
(
Void
::
VOID
,
lists
.
getStructList0
()[
0
].
getF
());
EXPECT_EQ
(
Void
::
VOID
,
lists
.
getStructList0
()[
1
].
getF
());
EXPECT_TRUE
(
lists
.
getStructList1
()[
0
].
getF
());
EXPECT_FALSE
(
lists
.
getStructList1
()[
1
].
getF
());
// EXPECT_TRUE(lists.getStructList1()[2].getF());
EXPECT_TRUE
(
lists
.
getStructList8
()[
0
].
getF0
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
0
].
getF1
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
0
].
getF2
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
1
].
getF0
());
EXPECT_TRUE
(
lists
.
getStructList8
()[
1
].
getF1
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
1
].
getF2
());
EXPECT_TRUE
(
lists
.
getStructList8
()[
2
].
getF0
());
EXPECT_TRUE
(
lists
.
getStructList8
()[
2
].
getF1
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
2
].
getF2
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
3
].
getF0
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
3
].
getF1
());
EXPECT_TRUE
(
lists
.
getStructList8
()[
3
].
getF2
());
EXPECT_EQ
(
12u
,
lists
.
getStructList16
()[
0
].
getF0
());
EXPECT_EQ
(
34u
,
lists
.
getStructList16
()[
0
].
getF1
());
EXPECT_EQ
(
56u
,
lists
.
getStructList16
()[
1
].
getF0
());
EXPECT_EQ
(
78u
,
lists
.
getStructList16
()[
1
].
getF1
());
EXPECT_EQ
(
90u
,
lists
.
getStructList32
()[
0
].
getF0
());
EXPECT_EQ
(
12345u
,
lists
.
getStructList32
()[
0
].
getF1
());
EXPECT_EQ
(
67u
,
lists
.
getStructList32
()[
1
].
getF0
());
EXPECT_EQ
(
8901u
,
lists
.
getStructList32
()[
1
].
getF1
());
EXPECT_EQ
(
23u
,
lists
.
getStructList32
()[
2
].
getF0
());
EXPECT_EQ
(
45678u
,
lists
.
getStructList32
()[
2
].
getF1
());
EXPECT_EQ
(
90u
,
lists
.
getStructList64
()[
0
].
getF0
());
EXPECT_EQ
(
123456789u
,
lists
.
getStructList64
()[
0
].
getF1
());
EXPECT_EQ
(
12u
,
lists
.
getStructList64
()[
1
].
getF0
());
EXPECT_EQ
(
345678901u
,
lists
.
getStructList64
()[
1
].
getF1
());
EXPECT_EQ
(
234u
,
lists
.
getStructList64
()[
2
].
getF0
());
EXPECT_EQ
(
567890123u
,
lists
.
getStructList64
()[
2
].
getF1
());
EXPECT_EQ
(
45u
,
lists
.
getStructList64
()[
3
].
getF0
());
EXPECT_EQ
(
678901234u
,
lists
.
getStructList64
()[
3
].
getF1
());
EXPECT_EQ
(
56789012345678ull
,
lists
.
getStructList128
()[
0
].
getF0
());
EXPECT_EQ
(
90123456789012ull
,
lists
.
getStructList128
()[
0
].
getF1
());
EXPECT_EQ
(
34567890123456ull
,
lists
.
getStructList128
()[
1
].
getF0
());
EXPECT_EQ
(
78901234567890ull
,
lists
.
getStructList128
()[
1
].
getF1
());
EXPECT_EQ
(
1234567890123ull
,
lists
.
getStructList192
()[
0
].
getF0
());
EXPECT_EQ
(
4567890123456ull
,
lists
.
getStructList192
()[
0
].
getF1
());
EXPECT_EQ
(
7890123456789ull
,
lists
.
getStructList192
()[
0
].
getF2
());
EXPECT_EQ
(
123456789012ull
,
lists
.
getStructList192
()[
1
].
getF0
());
EXPECT_EQ
(
3456789012345ull
,
lists
.
getStructList192
()[
1
].
getF1
());
EXPECT_EQ
(
6789012345678ull
,
lists
.
getStructList192
()[
1
].
getF2
());
EXPECT_EQ
(
9012345678901ull
,
lists
.
getStructList192
()[
2
].
getF0
());
EXPECT_EQ
(
2345678901234ull
,
lists
.
getStructList192
()[
2
].
getF1
());
EXPECT_EQ
(
5678901234567ull
,
lists
.
getStructList192
()[
2
].
getF2
());
EXPECT_EQ
(
"foo"
,
lists
.
getStructList0p
()[
0
].
getP0
());
EXPECT_EQ
(
"bar"
,
lists
.
getStructList0p
()[
1
].
getP0
());
EXPECT_EQ
(
"baz"
,
lists
.
getStructList0p
()[
2
].
getP0
());
EXPECT_EQ
(
"qux"
,
lists
.
getStructList0p
()[
3
].
getP0
());
EXPECT_TRUE
(
lists
.
getStructList1p
()[
0
].
getF
().
getF
());
EXPECT_EQ
(
"quux"
,
lists
.
getStructList1p
()[
0
].
getP0
());
EXPECT_EQ
(
"corge"
,
lists
.
getStructList1p
()[
1
].
getP0
());
EXPECT_TRUE
(
lists
.
getStructList8p
()[
0
].
getF
().
getF0
());
EXPECT_EQ
(
"grault"
,
lists
.
getStructList8p
()[
0
].
getP0
());
EXPECT_EQ
(
"garply"
,
lists
.
getStructList8p
()[
1
].
getP0
());
EXPECT_EQ
(
"waldo"
,
lists
.
getStructList8p
()[
2
].
getP0
());
EXPECT_EQ
(
123u
,
lists
.
getStructList16p
()[
0
].
getF
().
getF0
());
EXPECT_EQ
(
"fred"
,
lists
.
getStructList16p
()[
0
].
getP0
());
EXPECT_EQ
(
"plugh"
,
lists
.
getStructList16p
()[
0
].
getP1
());
EXPECT_EQ
(
"xyzzy"
,
lists
.
getStructList16p
()[
1
].
getP0
());
EXPECT_EQ
(
"thud"
,
lists
.
getStructList16p
()[
1
].
getP1
());
EXPECT_EQ
(
"foobar"
,
lists
.
getStructList16p
()[
2
].
getP0
());
EXPECT_EQ
(
"barbaz"
,
lists
.
getStructList16p
()[
2
].
getP1
());
EXPECT_EQ
(
"bazqux"
,
lists
.
getStructList16p
()[
3
].
getP0
());
EXPECT_EQ
(
"quxquux"
,
lists
.
getStructList16p
()[
3
].
getP1
());
EXPECT_EQ
(
12345u
,
lists
.
getStructList32p
()[
0
].
getF
().
getF1
());
EXPECT_EQ
(
"quuxcorge"
,
lists
.
getStructList32p
()[
0
].
getP0
());
EXPECT_EQ
(
"corgegrault"
,
lists
.
getStructList32p
()[
0
].
getP1
());
EXPECT_EQ
(
"graultgarply"
,
lists
.
getStructList32p
()[
1
].
getP0
());
EXPECT_EQ
(
"garplywaldo"
,
lists
.
getStructList32p
()[
1
].
getP1
());
EXPECT_EQ
(
123456789u
,
lists
.
getStructList64p
()[
0
].
getF
().
getF1
());
EXPECT_EQ
(
"waldofred"
,
lists
.
getStructList64p
()[
0
].
getP0
());
EXPECT_EQ
(
"fredplugh"
,
lists
.
getStructList64p
()[
0
].
getP1
());
EXPECT_EQ
(
"plughxyzzy"
,
lists
.
getStructList64p
()[
1
].
getP0
());
EXPECT_EQ
(
"xyzzythud"
,
lists
.
getStructList64p
()[
1
].
getP1
());
EXPECT_EQ
(
"thudfoo"
,
lists
.
getStructList64p
()[
2
].
getP0
());
EXPECT_EQ
(
"foofoo"
,
lists
.
getStructList64p
()[
2
].
getP1
());
EXPECT_EQ
(
123456789012345ull
,
lists
.
getStructList128p
()[
0
].
getF
().
getF1
());
EXPECT_EQ
(
"foobaz"
,
lists
.
getStructList128p
()[
0
].
getP0
());
EXPECT_EQ
(
"fooqux"
,
lists
.
getStructList128p
()[
0
].
getP1
());
EXPECT_EQ
(
"foocorge"
,
lists
.
getStructList128p
()[
0
].
getP2
());
EXPECT_EQ
(
"barbaz"
,
lists
.
getStructList128p
()[
1
].
getP0
());
EXPECT_EQ
(
"barqux"
,
lists
.
getStructList128p
()[
1
].
getP1
());
EXPECT_EQ
(
"barcorge"
,
lists
.
getStructList128p
()[
1
].
getP2
());
EXPECT_EQ
(
"bazbaz"
,
lists
.
getStructList128p
()[
2
].
getP0
());
EXPECT_EQ
(
"bazqux"
,
lists
.
getStructList128p
()[
2
].
getP1
());
EXPECT_EQ
(
"bazcorge"
,
lists
.
getStructList128p
()[
2
].
getP2
());
EXPECT_EQ
(
"quxbaz"
,
lists
.
getStructList128p
()[
3
].
getP0
());
EXPECT_EQ
(
"quxqux"
,
lists
.
getStructList128p
()[
3
].
getP1
());
EXPECT_EQ
(
"quxcorge"
,
lists
.
getStructList128p
()[
3
].
getP2
());
EXPECT_EQ
(
123456789012345ull
,
lists
.
getStructList192p
()[
0
].
getF
().
getF2
());
EXPECT_EQ
(
"corgebaz"
,
lists
.
getStructList192p
()[
0
].
getP0
());
EXPECT_EQ
(
"corgequx"
,
lists
.
getStructList192p
()[
0
].
getP1
());
EXPECT_EQ
(
"corgecorge"
,
lists
.
getStructList192p
()[
0
].
getP2
());
EXPECT_EQ
(
"graultbaz"
,
lists
.
getStructList192p
()[
1
].
getP0
());
EXPECT_EQ
(
"graultqux"
,
lists
.
getStructList192p
()[
1
].
getP1
());
EXPECT_EQ
(
"graultcorge"
,
lists
.
getStructList192p
()[
1
].
getP2
());
}
}
// =======================================================================================
...
...
c++/src/capnproto/layout-test.c++
View file @
eab15190
...
...
@@ -102,6 +102,8 @@ static const AlignedData<2> SUBSTRUCT_DEFAULT = {{0,0,0,0,1,0,0,0, 0,0,0,0,0,0,
static
const
AlignedData
<
2
>
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
=
{{
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}};
static
constexpr
StructSize
STRUCTLIST_ELEMENT_SIZE
(
1
*
WORDS
,
1
*
REFERENCES
,
64
*
BITS
);
static
void
setupStruct
(
StructBuilder
builder
)
{
builder
.
setDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
0x1011121314151617ull
);
builder
.
setDataField
<
uint32_t
>
(
2
*
ELEMENTS
,
0x20212223u
);
...
...
@@ -118,7 +120,7 @@ static void setupStruct(StructBuilder builder) {
{
StructBuilder
subStruct
=
builder
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
));
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
64
*
BITS
));
subStruct
.
setDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
123
);
}
...
...
@@ -132,12 +134,12 @@ static void setupStruct(StructBuilder builder) {
{
ListBuilder
list
=
builder
.
initStructListField
(
2
*
REFERENCES
,
4
*
ELEMENTS
,
S
tructSize
(
1
*
WORDS
,
1
*
REFERENCES
)
);
2
*
REFERENCES
,
4
*
ELEMENTS
,
S
TRUCTLIST_ELEMENT_SIZE
);
EXPECT_EQ
(
4
*
ELEMENTS
,
list
.
size
());
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
2
*
WORDS
/
ELEMENTS
,
1
*
WORDS
);
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
element
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
300
+
i
);
element
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
))
element
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
64
*
BITS
))
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
400
+
i
);
}
}
...
...
@@ -147,7 +149,7 @@ static void setupStruct(StructBuilder builder) {
EXPECT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
for
(
uint
i
=
0
;
i
<
5
;
i
++
)
{
ListBuilder
element
=
list
.
initListElement
(
i
*
REFERENCE
S
,
FieldSize
::
TWO_BYTES
,
(
i
+
1
)
*
ELEMENTS
);
i
*
ELEMENT
S
,
FieldSize
::
TWO_BYTES
,
(
i
+
1
)
*
ELEMENTS
);
EXPECT_EQ
((
i
+
1
)
*
ELEMENTS
,
element
.
size
());
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
element
.
setDataElement
<
uint16_t
>
(
j
*
ELEMENTS
,
500
+
j
);
...
...
@@ -172,7 +174,7 @@ static void checkStruct(StructBuilder builder) {
{
StructBuilder
subStruct
=
builder
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
),
SUBSTRUCT_DEFAULT
.
words
);
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
64
*
BITS
),
SUBSTRUCT_DEFAULT
.
words
);
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
}
...
...
@@ -188,10 +190,10 @@ static void checkStruct(StructBuilder builder) {
ListBuilder
list
=
builder
.
getListField
(
2
*
REFERENCES
,
nullptr
);
ASSERT_EQ
(
4
*
ELEMENTS
,
list
.
size
());
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
2
*
WORDS
/
ELEMENTS
,
1
*
WORDS
);
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
EXPECT_EQ
(
300
+
i
,
element
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
400
+
i
,
element
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
),
element
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
64
*
BITS
),
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
}
...
...
@@ -201,7 +203,7 @@ static void checkStruct(StructBuilder builder) {
ListBuilder
list
=
builder
.
getListField
(
3
*
REFERENCES
,
nullptr
);
ASSERT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
for
(
uint
i
=
0
;
i
<
5
;
i
++
)
{
ListBuilder
element
=
list
.
getListElement
(
i
*
REFERENCE
S
);
ListBuilder
element
=
list
.
getListElement
(
i
*
ELEMENT
S
);
ASSERT_EQ
((
i
+
1
)
*
ELEMENTS
,
element
.
size
());
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
EXPECT_EQ
(
500u
+
j
,
element
.
getDataElement
<
uint16_t
>
(
j
*
ELEMENTS
));
...
...
@@ -254,7 +256,7 @@ static void checkStruct(StructReader reader) {
ListReader
list
=
reader
.
getListField
(
3
*
REFERENCES
,
FieldSize
::
REFERENCE
,
nullptr
);
ASSERT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
for
(
uint
i
=
0
;
i
<
5
;
i
++
)
{
ListReader
element
=
list
.
getListElement
(
i
*
REFERENCE
S
,
FieldSize
::
TWO_BYTES
);
ListReader
element
=
list
.
getListElement
(
i
*
ELEMENT
S
,
FieldSize
::
TWO_BYTES
);
ASSERT_EQ
((
i
+
1
)
*
ELEMENTS
,
element
.
size
());
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
EXPECT_EQ
(
500u
+
j
,
element
.
getDataElement
<
uint16_t
>
(
j
*
ELEMENTS
));
...
...
@@ -270,7 +272,7 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
128
*
BITS
));
setupStruct
(
builder
);
// word count:
...
...
@@ -306,7 +308,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
128
*
BITS
));
setupStruct
(
builder
);
// Verify that we made 15 segments.
...
...
@@ -343,7 +345,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
128
*
BITS
));
setupStruct
(
builder
);
// Verify that we made 6 segments.
...
...
c++/src/capnproto/layout.c++
View file @
eab15190
...
...
@@ -415,7 +415,8 @@ struct WireHelpers {
ref
->
structRef
.
set
(
size
);
// Build the StructBuilder.
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
),
0
*
BITS
);
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
),
0
*
BITS
,
size
.
pointers
);
}
static
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
getWritableStructReference
(
...
...
@@ -442,7 +443,8 @@ struct WireHelpers {
"Trying to update struct with incorrect reference count."
);
}
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
),
0
*
BITS
);
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
),
0
*
BITS
,
size
.
pointers
);
}
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initListReference
(
...
...
@@ -451,9 +453,10 @@ struct WireHelpers {
DPRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
"Should have called initStructListReference() instead."
);
auto
step
=
bitsPerElement
(
elementSize
);
// Calculate size of the list.
WordCount
wordCount
=
roundUpToWords
(
ElementCount64
(
elementCount
)
*
bitsPerElement
(
elementSize
));
WordCount
wordCount
=
roundUpToWords
(
ElementCount64
(
elementCount
)
*
step
);
// Allocate the list.
word
*
ptr
=
allocate
(
ref
,
segment
,
wordCount
,
WireReference
::
LIST
);
...
...
@@ -462,12 +465,33 @@ struct WireHelpers {
ref
->
listRef
.
set
(
elementSize
,
elementCount
);
// Build the ListBuilder.
return
ListBuilder
(
segment
,
ptr
,
elementCount
);
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
),
step
,
step
/
BITS_PER_REFERENCE
,
elementCount
);
}
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initStructListReference
(
WireReference
*
ref
,
SegmentBuilder
*
segment
,
ElementCount
elementCount
,
StructSize
elementSize
))
{
if
((
elementSize
.
pointers
==
0
*
REFERENCES
&&
elementSize
.
data
<=
1
*
WORDS
)
||
(
elementSize
.
pointers
==
1
*
REFERENCES
&&
elementSize
.
data
==
0
*
WORDS
))
{
// Small data-only struct. Allocate a list of primitives instead.
FieldSize
primitiveElementSize
=
FieldSize
::
VOID
;
if
(
elementSize
.
pointers
==
1
*
REFERENCES
)
{
primitiveElementSize
=
FieldSize
::
REFERENCE
;
}
else
{
switch
(
elementSize
.
dataBits
/
BITS
)
{
case
0
:
primitiveElementSize
=
FieldSize
::
VOID
;
break
;
case
1
:
primitiveElementSize
=
FieldSize
::
BIT
;
break
;
case
8
:
primitiveElementSize
=
FieldSize
::
BYTE
;
break
;
case
16
:
primitiveElementSize
=
FieldSize
::
TWO_BYTES
;
break
;
case
32
:
primitiveElementSize
=
FieldSize
::
FOUR_BYTES
;
break
;
case
64
:
primitiveElementSize
=
FieldSize
::
EIGHT_BYTES
;
break
;
default
:
FAIL_PRECOND
(
"Invalid struct size."
);
break
;
}
}
return
initListReference
(
ref
,
segment
,
elementCount
,
primitiveElementSize
);
}
auto
wordsPerElement
=
elementSize
.
total
()
/
ELEMENTS
;
// Allocate the list, prefixed by a single WireReference.
...
...
@@ -485,7 +509,9 @@ struct WireHelpers {
ptr
+=
REFERENCE_SIZE_IN_WORDS
;
// Build the ListBuilder.
return
ListBuilder
(
segment
,
ptr
,
elementCount
);
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
elementSize
.
data
),
wordsPerElement
*
BITS_PER_WORD
,
wordsPerElement
/
WORDS_PER_REFERENCE
,
elementCount
);
}
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getWritableListReference
(
...
...
@@ -495,7 +521,8 @@ struct WireHelpers {
if
(
ref
->
isNull
())
{
if
(
defaultValue
==
nullptr
)
{
return
ListBuilder
(
segment
,
nullptr
,
0
*
ELEMENTS
);
return
ListBuilder
(
segment
,
nullptr
,
nullptr
,
0
*
BITS
/
ELEMENTS
,
0
*
REFERENCES
/
ELEMENTS
,
0
*
ELEMENTS
);
}
ptr
=
copyMessage
(
segment
,
ref
,
defaultRef
);
}
else
{
...
...
@@ -510,12 +537,19 @@ struct WireHelpers {
WireReference
*
tag
=
reinterpret_cast
<
WireReference
*>
(
ptr
);
PRECOND
(
tag
->
kind
()
==
WireReference
::
STRUCT
,
"INLINE_COMPOSITE list with non-STRUCT elements not supported."
);
ElementCount
elementCount
=
tag
->
inlineCompositeListElementCount
();
// First list element is at tag + 1 reference.
return
ListBuilder
(
segment
,
reinterpret_cast
<
word
*>
(
tag
+
1
),
elementCount
);
word
*
data
=
reinterpret_cast
<
word
*>
(
tag
+
1
);
WireReference
*
pointers
=
reinterpret_cast
<
WireReference
*>
(
data
+
tag
->
structRef
.
dataSize
.
get
());
auto
step
=
tag
->
structRef
.
wordSize
()
/
ELEMENTS
;
return
ListBuilder
(
segment
,
data
,
pointers
,
step
*
BITS_PER_WORD
,
step
/
WORDS_PER_REFERENCE
,
tag
->
inlineCompositeListElementCount
());
}
else
{
return
ListBuilder
(
segment
,
ptr
,
ref
->
listRef
.
elementCount
());
decltype
(
BITS
/
ELEMENTS
)
step
=
bitsPerElement
(
ref
->
listRef
.
elementSize
());
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
),
step
,
step
/
BITS_PER_REFERENCE
,
ref
->
listRef
.
elementCount
());
}
}
...
...
@@ -649,7 +683,9 @@ struct WireHelpers {
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
if
(
defaultValue
==
nullptr
)
{
return
ListReader
(
nullptr
,
nullptr
,
0
*
ELEMENTS
,
0
*
BITS
/
ELEMENTS
,
nestingLimit
-
1
);
return
ListReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
ELEMENTS
,
0
*
BITS
/
ELEMENTS
,
0
*
REFERENCES
/
ELEMENTS
,
nestingLimit
-
1
);
}
segment
=
nullptr
;
ref
=
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
);
...
...
@@ -751,7 +787,10 @@ struct WireHelpers {
}
}
return
ListReader
(
segment
,
ptr
,
size
,
wordsPerElement
*
BITS_PER_WORD
,
return
ListReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
+
tag
->
structRef
.
dataSize
.
get
()),
size
,
wordsPerElement
*
BITS_PER_WORD
,
wordsPerElement
/
WORDS_PER_REFERENCE
,
tag
->
structRef
.
dataSize
.
get
()
*
BITS_PER_WORD
,
tag
->
structRef
.
refCount
.
get
(),
nestingLimit
-
1
);
...
...
@@ -768,7 +807,9 @@ struct WireHelpers {
}
if
(
ref
->
listRef
.
elementSize
()
==
expectedElementSize
)
{
return
ListReader
(
segment
,
ptr
,
ref
->
listRef
.
elementCount
(),
step
,
nestingLimit
-
1
);
return
ListReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
),
ref
->
listRef
.
elementCount
(),
step
,
step
/
BITS_PER_REFERENCE
,
nestingLimit
-
1
);
}
else
if
(
expectedElementSize
==
FieldSize
::
INLINE_COMPOSITE
)
{
// We were expecting a struct list, but we received a list of some other type. Perhaps a
// non-struct list was recently upgraded to a struct list, but the sender is using the
...
...
@@ -792,7 +833,8 @@ struct WireHelpers {
break
;
}
return
ListReader
(
segment
,
ptr
,
ref
->
listRef
.
elementCount
(),
step
,
return
ListReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
),
ref
->
listRef
.
elementCount
(),
step
,
step
/
BITS_PER_REFERENCE
,
dataSize
,
referenceCount
,
nestingLimit
-
1
);
}
else
{
PRECOND
(
segment
!=
nullptr
,
"Trusted message had incompatible list element type."
);
...
...
@@ -1017,101 +1059,102 @@ Data::Reader StructReader::getDataField(
return
WireHelpers
::
readDataReference
(
segment
,
ref
,
defaultValue
,
defaultSize
);
}
StructBuilder
ListBuilder
::
getStructElement
(
ElementCount
index
,
decltype
(
WORDS
/
ELEMENTS
)
elementSize
,
WordCount
structDataSize
)
const
{
word
*
structPtr
=
ptr
+
elementSize
*
index
;
return
StructBuilder
(
segment
,
structPtr
,
reinterpret_cast
<
WireReference
*>
(
structPtr
+
structDataSize
),
0
*
BITS
);
StructBuilder
ListBuilder
::
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
{
// TODO: Inline this method?
BitCount64
indexBit
=
ElementCount64
(
index
)
*
stepBits
;
byte
*
structData
=
reinterpret_cast
<
byte
*>
(
data
)
+
indexBit
/
BITS_PER_BYTE
;
WireReference
*
structPointers
=
pointers
+
index
*
stepPointers
;
return
StructBuilder
(
segment
,
structData
,
structPointers
,
indexBit
%
BITS_PER_BYTE
,
elementSize
.
pointers
);
}
ListBuilder
ListBuilder
::
initListElement
(
WireReference
Count
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
{
Element
Count
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
{
return
WireHelpers
::
initListReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
pointers
+
index
*
stepPointers
,
segment
,
elementCount
,
elementSize
);
}
ListBuilder
ListBuilder
::
initStructListElement
(
WireReference
Count
index
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
Element
Count
index
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
return
WireHelpers
::
initStructListReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
pointers
+
index
*
stepPointers
,
segment
,
elementCount
,
elementSize
);
}
ListBuilder
ListBuilder
::
getListElement
(
WireReference
Count
index
)
const
{
ListBuilder
ListBuilder
::
getListElement
(
Element
Count
index
)
const
{
return
WireHelpers
::
getWritableListReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
nullptr
);
pointers
+
index
*
stepPointers
,
segment
,
nullptr
);
}
Text
::
Builder
ListBuilder
::
initTextElement
(
WireReference
Count
index
,
ByteCount
size
)
const
{
Text
::
Builder
ListBuilder
::
initTextElement
(
Element
Count
index
,
ByteCount
size
)
const
{
return
WireHelpers
::
initTextReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
size
);
pointers
+
index
*
stepPointers
,
segment
,
size
);
}
void
ListBuilder
::
setTextElement
(
WireReference
Count
index
,
Text
::
Reader
value
)
const
{
void
ListBuilder
::
setTextElement
(
Element
Count
index
,
Text
::
Reader
value
)
const
{
WireHelpers
::
setTextReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
value
);
pointers
+
index
*
stepPointers
,
segment
,
value
);
}
Text
::
Builder
ListBuilder
::
getTextElement
(
WireReference
Count
index
)
const
{
Text
::
Builder
ListBuilder
::
getTextElement
(
Element
Count
index
)
const
{
return
WireHelpers
::
getWritableTextReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
""
,
0
*
BYTES
);
pointers
+
index
*
stepPointers
,
segment
,
""
,
0
*
BYTES
);
}
Data
::
Builder
ListBuilder
::
initDataElement
(
WireReference
Count
index
,
ByteCount
size
)
const
{
Data
::
Builder
ListBuilder
::
initDataElement
(
Element
Count
index
,
ByteCount
size
)
const
{
return
WireHelpers
::
initDataReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
size
);
pointers
+
index
*
stepPointers
,
segment
,
size
);
}
void
ListBuilder
::
setDataElement
(
WireReference
Count
index
,
Data
::
Reader
value
)
const
{
void
ListBuilder
::
setDataElement
(
Element
Count
index
,
Data
::
Reader
value
)
const
{
WireHelpers
::
setDataReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
value
);
pointers
+
index
*
stepPointers
,
segment
,
value
);
}
Data
::
Builder
ListBuilder
::
getDataElement
(
WireReference
Count
index
)
const
{
Data
::
Builder
ListBuilder
::
getDataElement
(
Element
Count
index
)
const
{
return
WireHelpers
::
getWritableDataReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
nullptr
,
0
*
BYTES
);
pointers
+
index
*
stepPointers
,
segment
,
nullptr
,
0
*
BYTES
);
}
ListReader
ListBuilder
::
asReader
(
FieldSize
elementSize
)
const
{
// TODO: For INLINE_COMPOSITE I suppose we could just check the tag?
PRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
"Need to call the other asReader() overload for INLINE_COMPOSITE lists."
);
return
ListReader
(
segment
,
ptr
,
elementCount
,
bitsPerElement
(
elementSize
)
,
return
ListReader
(
segment
,
data
,
pointers
,
elementCount
,
stepBits
,
stepPointers
,
std
::
numeric_limits
<
int
>::
max
());
}
ListReader
ListBuilder
::
asReader
(
BitCount
dataSize
,
WireReferenceCount
referenceCount
)
const
{
return
ListReader
(
segment
,
ptr
,
elementCount
,
(
dataSize
+
referenceCount
*
WORDS_PER_REFERENCE
*
BITS_PER_WORD
)
/
ELEMENTS
,
dataSize
,
referenceCount
,
std
::
numeric_limits
<
int
>::
max
());
ListReader
ListBuilder
::
asReader
(
StructSize
elementSize
)
const
{
return
ListReader
(
segment
,
data
,
pointers
,
elementCount
,
stepBits
,
stepPointers
,
elementSize
.
dataBits
,
elementSize
.
pointers
,
std
::
numeric_limits
<
int
>::
max
());
}
StructReader
ListReader
::
getStructElement
(
ElementCount
index
)
const
{
// TODO: Inline this method?
VALIDATE_INPUT
((
segment
==
nullptr
)
|
(
nestingLimit
>
0
),
"Message is too deeply-nested or contains cycles. See capnproto::ReadOptions."
)
{
return
StructReader
::
readEmpty
();
}
BitCount64
indexBit
=
ElementCount64
(
index
)
*
stepBits
;
const
byte
*
struct
Ptr
=
reinterpret_cast
<
const
byte
*>
(
ptr
)
+
indexBit
/
BITS_PER_BYTE
;
const
byte
*
struct
Data
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
indexBit
/
BITS_PER_BYTE
;
return
StructReader
(
segment
,
structPtr
,
reinterpret_cast
<
const
WireReference
*>
(
structPtr
+
structDataSize
/
BITS_PER_BYTE
),
segment
,
structData
,
pointers
+
index
*
stepPointers
,
structDataSize
,
structReferenceCount
,
indexBit
%
BITS_PER_BYTE
,
nestingLimit
-
1
);
}
ListReader
ListReader
::
getListElement
(
WireReference
Count
index
,
FieldSize
expectedElementSize
)
const
{
Element
Count
index
,
FieldSize
expectedElementSize
)
const
{
return
WireHelpers
::
readListReference
(
segment
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
)
+
index
,
segment
,
pointers
+
index
*
stepPointers
,
nullptr
,
expectedElementSize
,
nestingLimit
);
}
Text
::
Reader
ListReader
::
getTextElement
(
WireReference
Count
index
)
const
{
return
WireHelpers
::
readTextReference
(
segment
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
)
+
index
,
""
,
0
*
BYTES
);
Text
::
Reader
ListReader
::
getTextElement
(
Element
Count
index
)
const
{
return
WireHelpers
::
readTextReference
(
segment
,
pointers
+
index
*
stepPointers
,
""
,
0
*
BYTES
);
}
Data
::
Reader
ListReader
::
getDataElement
(
WireReference
Count
index
)
const
{
return
WireHelpers
::
readDataReference
(
segment
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
)
+
index
,
nullptr
,
0
*
BYTES
);
Data
::
Reader
ListReader
::
getDataElement
(
Element
Count
index
)
const
{
return
WireHelpers
::
readDataReference
(
segment
,
pointers
+
index
*
stepPointers
,
nullptr
,
0
*
BYTES
);
}
}
// namespace internal
...
...
c++/src/capnproto/layout.h
View file @
eab15190
...
...
@@ -132,11 +132,15 @@ struct StructSize {
WordCount16
data
;
WireReferenceCount16
pointers
;
BitCount32
dataBits
;
// If data == 1 word, dataBits may be 1, 8, 16, 32, or 64. Otherwise, it is data * BITS_PER_WORD.
// This is used when packing inline structs.
inline
constexpr
WordCount
total
()
const
{
return
data
+
pointers
*
WORDS_PER_REFERENCE
;
}
StructSize
()
=
default
;
inline
constexpr
StructSize
(
WordCount
data
,
WireReferenceCount
pointers
)
:
data
(
data
),
pointers
(
pointers
)
{}
inline
constexpr
StructSize
(
WordCount
data
,
WireReferenceCount
pointers
,
BitCount
dataBits
)
:
data
(
data
),
pointers
(
pointers
)
,
dataBits
(
dataBits
)
{}
};
template
<
typename
T
>
...
...
@@ -307,6 +311,34 @@ public:
// already allocated, it is allocated as a deep copy of the given default value (a trusted
// message). If the default value is null, an empty list is used.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initInlineDataListField
(
BitCount
offset
,
BitCount
inlineSize
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
);
// Initialize an inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initInlinePointerListField
(
WireReferenceCount
offset
,
WireReferenceCount
inlineSize
,
ElementCount
elementCount
)
const
);
// Initialize an inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initInlineStructListField
(
BitCount
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
);
// Initialize an inline struct list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getInlineDataListField
(
BitCount
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
);
// Get an already-initialized inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getInlinePointerListField
(
WireReferenceCount
offset
,
ElementCount
elementCount
)
const
);
// Get an already-initialized inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getInlineStructListField
(
BitCount
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
);
// Get an already-initialized inline struct list field.
Text
::
Builder
initTextField
(
WireReferenceCount
refIndex
,
ByteCount
size
)
const
;
// Initialize the text field to the given size in bytes (not including NUL terminator) and return
// a Text::Builder which can be used to fill in the content.
...
...
@@ -327,6 +359,8 @@ public:
StructReader
asReader
()
const
;
// Gets a StructReader pointing at the same memory.
WireReferenceCount
getReferenceCount
()
{
return
referenceCount
;
}
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the struct resides.
void
*
data
;
// Pointer to the encoded data.
...
...
@@ -336,9 +370,13 @@ private:
// A special hack: When accessing a boolean with field number zero, pretend its offset is this
// instead of the usual zero. This is needed to support 1-bit inline structs.
WireReferenceCount16
referenceCount
;
// Size of the pointer segment, available only for the sake of computing size of List(Inline(T)).
inline
StructBuilder
(
SegmentBuilder
*
segment
,
void
*
data
,
WireReference
*
references
,
BitCount8
bit0Offset
)
:
segment
(
segment
),
data
(
data
),
references
(
references
),
bit0Offset
(
bit0Offset
)
{}
BitCount8
bit0Offset
,
WireReferenceCount
referenceCount
)
:
segment
(
segment
),
data
(
data
),
references
(
references
),
bit0Offset
(
bit0Offset
),
referenceCount
(
referenceCount
)
{}
friend
class
ListBuilder
;
friend
struct
WireHelpers
;
...
...
@@ -382,6 +420,19 @@ public:
// Get the list field at the given index in the reference segment, or the default value if not
// initialized. The default value is allowed to be null, in which case an empty list is used.
CAPNPROTO_ALWAYS_INLINE
(
ListReader
getInlineDataListField
(
BitCount
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
);
// Get an inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListReader
getInlinePointerListField
(
WireReferenceCount
offset
,
ElementCount
elementCount
)
const
);
// Get an inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListReader
getInlineStructListField
(
BitCount
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
);
// Get an inline struct list field.
Text
::
Reader
getTextField
(
WireReferenceCount
refIndex
,
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
// Gets the text field, or the given default value if not initialized.
...
...
@@ -390,6 +441,8 @@ public:
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
// Gets the data field, or the given default value if not initialized.
WireReferenceCount
getReferenceCount
()
{
return
referenceCount
;
}
private
:
SegmentReader
*
segment
;
// Memory segment in which the struct resides.
...
...
@@ -425,7 +478,9 @@ private:
class
ListBuilder
{
public
:
inline
ListBuilder
()
:
segment
(
nullptr
),
ptr
(
nullptr
),
elementCount
(
0
)
{}
inline
ListBuilder
()
:
segment
(
nullptr
),
data
(
nullptr
),
pointers
(
nullptr
),
elementCount
(
0
*
ELEMENTS
),
stepBits
(
0
*
BITS
/
ELEMENTS
),
stepPointers
(
0
*
REFERENCES
/
ELEMENTS
)
{}
inline
ElementCount
size
();
// The number of elements in the list.
...
...
@@ -439,52 +494,61 @@ public:
ElementCount
index
,
typename
NoInfer
<
T
>::
Type
value
)
const
);
// Set the element at the given index.
StructBuilder
getStructElement
(
ElementCount
index
,
decltype
(
WORDS
/
ELEMENTS
)
elementSize
,
WordCount
structDataSize
)
const
;
// Get the struct element at the given index. elementSize is the size, in 64-bit words, of
// each element.
StructBuilder
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
;
// Get the struct element at the given index.
ListBuilder
initListElement
(
WireReference
Count
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
;
Element
Count
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
;
// Create a new list element of the given size at the given index. All elements are initialized
// to zero.
ListBuilder
initStructListElement
(
WireReference
Count
index
,
ElementCount
elementCount
,
ListBuilder
initStructListElement
(
Element
Count
index
,
ElementCount
elementCount
,
StructSize
size
)
const
;
// 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 to its empty state.
ListBuilder
getListElement
(
WireReference
Count
index
)
const
;
ListBuilder
getListElement
(
Element
Count
index
)
const
;
// Get the existing list element at the given index. Returns an empty list if the element is
// not initialized.
Text
::
Builder
initTextElement
(
WireReference
Count
index
,
ByteCount
size
)
const
;
Text
::
Builder
initTextElement
(
Element
Count
index
,
ByteCount
size
)
const
;
// Initialize the text element to the given size in bytes (not including NUL terminator) and
// return a Text::Builder which can be used to fill in the content.
void
setTextElement
(
WireReference
Count
index
,
Text
::
Reader
value
)
const
;
void
setTextElement
(
Element
Count
index
,
Text
::
Reader
value
)
const
;
// Set the text element to a copy of the given text.
Text
::
Builder
getTextElement
(
WireReference
Count
index
)
const
;
Text
::
Builder
getTextElement
(
Element
Count
index
)
const
;
// Get the text element. If it is not initialized, returns an empty Text::Builder.
Data
::
Builder
initDataElement
(
WireReference
Count
index
,
ByteCount
size
)
const
;
void
setDataElement
(
WireReference
Count
index
,
Data
::
Reader
value
)
const
;
Data
::
Builder
getDataElement
(
WireReference
Count
index
)
const
;
Data
::
Builder
initDataElement
(
Element
Count
index
,
ByteCount
size
)
const
;
void
setDataElement
(
Element
Count
index
,
Data
::
Reader
value
)
const
;
Data
::
Builder
getDataElement
(
Element
Count
index
)
const
;
ListReader
asReader
(
FieldSize
elementSize
)
const
;
// Get a ListReader pointing at the same memory. Use this version only for non-struct lists.
ListReader
asReader
(
BitCount
dataSize
,
WireReferenceCount
referenceCount
)
const
;
ListReader
asReader
(
StructSize
elementSize
)
const
;
// Get a ListReader pointing at the same memory. Use this version only for struct lists.
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the list resides.
word
*
ptr
;
// Pointer to the beginning of the list.
void
*
data
;
WireReference
*
pointers
;
// Pointers to list content.
ElementCount
elementCount
;
// Number of elements in the list.
inline
ListBuilder
(
SegmentBuilder
*
segment
,
word
*
ptr
,
ElementCount
size
)
:
segment
(
segment
),
ptr
(
ptr
),
elementCount
(
size
)
{}
decltype
(
BITS
/
ELEMENTS
)
stepBits
;
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
;
// The distance between elements. Can be tricky e.g. for inlined struct lists.
inline
ListBuilder
(
SegmentBuilder
*
segment
,
void
*
data
,
WireReference
*
pointers
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
ElementCount
size
)
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
size
),
stepBits
(
stepBits
),
stepPointers
(
stepPointers
)
{}
friend
class
StructBuilder
;
friend
struct
WireHelpers
;
...
...
@@ -493,9 +557,9 @@ private:
class
ListReader
{
public
:
inline
ListReader
()
:
segment
(
nullptr
),
ptr
(
nullptr
),
elementCount
(
0
),
stepBits
(
0
*
BITS
/
ELEMENTS
),
st
ructDataSize
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
0
)
{}
:
segment
(
nullptr
),
data
(
nullptr
),
pointers
(
nullptr
),
elementCount
(
0
),
stepBits
(
0
*
BITS
/
ELEMENTS
),
st
epPointers
(
0
*
REFERENCES
/
ELEMENTS
),
struct
DataSize
(
0
),
struct
ReferenceCount
(
0
),
nestingLimit
(
0
)
{}
inline
ElementCount
size
();
// The number of elements in the list.
...
...
@@ -507,50 +571,49 @@ public:
StructReader
getStructElement
(
ElementCount
index
)
const
;
// Get the struct element at the given index.
ListReader
getListElement
(
WireReference
Count
index
,
FieldSize
expectedElementSize
)
const
;
ListReader
getListElement
(
Element
Count
index
,
FieldSize
expectedElementSize
)
const
;
// Get the list element at the given index.
Text
::
Reader
getTextElement
(
WireReference
Count
index
)
const
;
Text
::
Reader
getTextElement
(
Element
Count
index
)
const
;
// Get the text element. If it is not initialized, returns an empty Text::Reader.
Data
::
Reader
getDataElement
(
WireReference
Count
index
)
const
;
Data
::
Reader
getDataElement
(
Element
Count
index
)
const
;
// Get the data element. If it is not initialized, returns an empty Data::Reader.
private
:
SegmentReader
*
segment
;
// Memory segment in which the list resides.
const
void
*
ptr
;
// Pointer to the data. If null, use defaultReferences. (Never null for data lists.)
//
Must be aligned appropriately for the elements
.
const
void
*
data
;
const
WireReference
*
pointers
;
//
Pointers to list content
.
ElementCount
elementCount
;
// Number of elements in the list.
decltype
(
BITS
/
ELEMENTS
)
stepBits
;
// The distance between elements, in bits. This is usually the element size, but can be larger
// if the sender upgraded a data list to a struct list. It will always be aligned properly for
// the type. Unsigned so that division by a constant power of 2 is efficient.
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
;
// The distance between elements. Can be tricky e.g. for inlined struct lists.
BitCount
structDataSize
;
WireReferenceCount
structReferenceCount
;
// If the elements are structs, the properties of the struct. The reference count is
// only used to check for field presence; the data size is also used to compute the reference
// pointer.
// If the elements are structs, the properties of the struct.
int
nestingLimit
;
// Limits the depth of message structures to guard against stack-overflow-based DoS attacks.
// Once this reaches zero, further pointers will be pruned.
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
ptr
,
ElementCount
elementCount
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
int
nestingLimit
)
:
segment
(
segment
),
ptr
(
ptr
),
elementCount
(
elementCount
),
stepBits
(
stepBits
),
structDataSize
(
0
),
structReferenceCount
(
0
),
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
data
,
const
WireReference
*
pointers
,
ElementCount
elementCount
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
int
nestingLimit
)
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
elementCount
),
stepBits
(
stepBits
),
stepPointers
(
stepPointers
),
structDataSize
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
nestingLimit
)
{}
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
ptr
,
ElementCount
elementCount
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
BitCount
structDataSize
,
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
data
,
const
WireReference
*
pointers
,
ElementCount
elementCount
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
BitCount
structDataSize
,
WireReferenceCount
structReferenceCount
,
int
nestingLimit
)
:
segment
(
segment
),
ptr
(
ptr
),
elementCount
(
elementCount
),
stepBits
(
stepBits
),
st
ructDataSize
(
structDataSize
),
structReferenceCount
(
structReferenceCount
),
nestingLimit
(
nestingLimit
)
{}
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
elementCount
),
st
epBits
(
stepBits
),
stepPointers
(
stepPointers
),
structDataSize
(
structDataSize
),
structReferenceCount
(
structReferenceCount
),
nestingLimit
(
nestingLimit
)
{}
friend
class
StructReader
;
friend
class
ListBuilder
;
...
...
@@ -637,14 +700,68 @@ inline StructBuilder StructBuilder::getInlineStructField(
// WireReference is incomplete here so we have to cast around... Bah.
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
word
*>
(
references
)
+
refIndex
*
WORDS_PER_REFERENCE
),
dataOffset
==
0
*
BITS
?
BitCount
(
bit0Offset
)
:
dataOffset
%
BITS_PER_BYTE
);
dataOffset
==
0
*
BITS
?
BitCount
(
bit0Offset
)
:
dataOffset
%
BITS_PER_BYTE
,
inlineRefCount
);
}
inline
ListBuilder
StructBuilder
::
initInlineDataListField
(
BitCount
offset
,
BitCount
inlineSize
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
{
memset
(
reinterpret_cast
<
byte
*>
(
data
)
+
offset
/
BITS_PER_BYTE
,
0
,
inlineSize
/
BITS_PER_BYTE
/
BYTES
);
return
getInlineDataListField
(
offset
,
elementCount
,
elementSize
);
}
inline
ListBuilder
StructBuilder
::
initInlinePointerListField
(
WireReferenceCount
offset
,
WireReferenceCount
inlineSize
,
ElementCount
elementCount
)
const
{
memset
(
reinterpret_cast
<
word
*>
(
references
)
+
offset
*
WORDS_PER_REFERENCE
,
0
,
inlineSize
*
BYTES_PER_REFERENCE
/
BYTES
);
return
getInlinePointerListField
(
offset
,
elementCount
);
}
inline
ListBuilder
StructBuilder
::
initInlineStructListField
(
BitCount
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
memset
(
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
,
0
,
elementSize
.
dataBits
/
BITS_PER_BYTE
/
BYTES
);
memset
(
reinterpret_cast
<
word
*>
(
references
)
+
ptrOffset
*
WORDS_PER_REFERENCE
,
0
,
elementSize
.
pointers
*
BYTES_PER_REFERENCE
/
BYTES
);
return
getInlineStructListField
(
dataOffset
,
ptrOffset
,
elementCount
,
elementSize
);
}
inline
ListBuilder
StructBuilder
::
getInlineDataListField
(
BitCount
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
{
return
ListBuilder
(
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
offset
/
BITS_PER_BYTE
,
nullptr
,
bitsPerElement
(
elementSize
),
0
*
REFERENCES
/
ELEMENTS
,
elementCount
);
}
inline
ListBuilder
StructBuilder
::
getInlinePointerListField
(
WireReferenceCount
offset
,
ElementCount
elementCount
)
const
{
return
ListBuilder
(
segment
,
nullptr
,
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
word
*>
(
references
)
+
offset
*
WORDS_PER_REFERENCE
),
0
*
BITS
/
ELEMENTS
,
1
*
REFERENCES
/
ELEMENTS
,
elementCount
);
}
inline
ListBuilder
StructBuilder
::
getInlineStructListField
(
BitCount
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
return
ListBuilder
(
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
,
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
word
*>
(
references
)
+
ptrOffset
*
WORDS_PER_REFERENCE
),
elementSize
.
dataBits
/
ELEMENTS
,
elementSize
.
pointers
/
ELEMENTS
,
elementCount
);
}
// -------------------------------------------------------------------
template
<
typename
T
>
T
StructReader
::
getDataField
(
ElementCount
offset
)
const
{
if
(
offset
*
capnproto
::
bitsPerElement
<
T
>
()
<
dataSize
)
{
if
(
(
offset
+
1
*
ELEMENTS
)
*
capnproto
::
bitsPerElement
<
T
>
()
<=
dataSize
)
{
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
data
)[
offset
/
ELEMENTS
].
get
();
}
else
{
return
static_cast
<
T
>
(
0
);
...
...
@@ -689,19 +806,49 @@ inline StructReader StructReader::getInlineStructField(
nestingLimit
);
}
inline
ListReader
StructReader
::
getInlineDataListField
(
BitCount
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
{
return
ListReader
(
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
offset
/
BITS_PER_BYTE
,
nullptr
,
elementCount
,
bitsPerElement
(
elementSize
),
0
*
REFERENCES
/
ELEMENTS
,
nestingLimit
);
}
inline
ListReader
StructReader
::
getInlinePointerListField
(
WireReferenceCount
offset
,
ElementCount
elementCount
)
const
{
return
ListReader
(
segment
,
nullptr
,
reinterpret_cast
<
const
WireReference
*>
(
reinterpret_cast
<
const
word
*>
(
references
)
+
offset
*
WORDS_PER_REFERENCE
),
elementCount
,
0
*
BITS
/
ELEMENTS
,
1
*
REFERENCES
/
ELEMENTS
,
nestingLimit
);
}
inline
ListReader
StructReader
::
getInlineStructListField
(
BitCount
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
return
ListReader
(
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
,
reinterpret_cast
<
const
WireReference
*>
(
reinterpret_cast
<
const
word
*>
(
references
)
+
ptrOffset
*
WORDS_PER_REFERENCE
),
elementCount
,
elementSize
.
dataBits
/
ELEMENTS
,
elementSize
.
pointers
/
ELEMENTS
,
elementSize
.
dataBits
,
elementSize
.
pointers
,
nestingLimit
);
}
// -------------------------------------------------------------------
inline
ElementCount
ListBuilder
::
size
()
{
return
elementCount
;
}
template
<
typename
T
>
inline
T
ListBuilder
::
getDataElement
(
ElementCount
index
)
const
{
return
reinterpret_cast
<
WireValue
<
T
>*>
(
ptr
)[
index
/
ELEMENTS
].
get
();
return
reinterpret_cast
<
WireValue
<
T
>*>
(
reinterpret_cast
<
byte
*>
(
data
)
+
index
*
stepBits
/
BITS_PER_BYTE
)
->
get
();
}
template
<>
inline
bool
ListBuilder
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
)
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
ptr
)
+
bindex
/
BITS_PER_BYTE
;
BitCount
bindex
=
index
*
stepBits
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
(
1
<<
(
bindex
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
}
...
...
@@ -712,13 +859,14 @@ inline Void ListBuilder::getDataElement<Void>(ElementCount index) const {
template
<
typename
T
>
inline
void
ListBuilder
::
setDataElement
(
ElementCount
index
,
typename
NoInfer
<
T
>::
Type
value
)
const
{
reinterpret_cast
<
WireValue
<
T
>*>
(
ptr
)[
index
/
ELEMENTS
].
set
(
value
);
reinterpret_cast
<
WireValue
<
T
>*>
(
reinterpret_cast
<
byte
*>
(
data
)
+
index
*
stepBits
/
BITS_PER_BYTE
)
->
set
(
value
);
}
template
<>
inline
void
ListBuilder
::
setDataElement
<
bool
>
(
ElementCount
index
,
bool
value
)
const
{
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
)
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
ptr
)
+
bindex
/
BITS_PER_BYTE
;
BitCount
bindex
=
index
*
stepBits
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
uint
bitnum
=
bindex
%
BITS_PER_BYTE
/
BITS
;
*
reinterpret_cast
<
uint8_t
*>
(
b
)
=
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
~
(
1
<<
bitnum
))
|
(
static_cast
<
uint8_t
>
(
value
)
<<
bitnum
);
...
...
@@ -733,14 +881,14 @@ inline ElementCount ListReader::size() { return elementCount; }
template
<
typename
T
>
inline
T
ListReader
::
getDataElement
(
ElementCount
index
)
const
{
return
*
reinterpret_cast
<
const
T
*>
(
reinterpret_cast
<
const
byte
*>
(
ptr
)
+
index
*
stepBits
/
BITS_PER_BYTE
);
return
reinterpret_cast
<
const
WireValue
<
T
>
*>
(
reinterpret_cast
<
const
byte
*>
(
data
)
+
index
*
stepBits
/
BITS_PER_BYTE
)
->
get
(
);
}
template
<>
inline
bool
ListReader
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
BitCount
bindex
=
index
*
stepBits
;
const
byte
*
b
=
reinterpret_cast
<
const
byte
*>
(
ptr
)
+
bindex
/
BITS_PER_BYTE
;
const
byte
*
b
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
const
uint8_t
*>
(
b
)
&
(
1
<<
(
bindex
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
}
...
...
c++/src/capnproto/list.h
View file @
eab15190
...
...
@@ -236,8 +236,7 @@ struct List<T, false> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
T
::
Builder
operator
[](
uint
index
)
{
return
typename
T
::
Builder
(
builder
.
getStructElement
(
index
*
ELEMENTS
,
T
::
STRUCT_SIZE
.
total
()
/
ELEMENTS
,
T
::
STRUCT_SIZE
.
data
));
return
typename
T
::
Builder
(
builder
.
getStructElement
(
index
*
ELEMENTS
,
T
::
STRUCT_SIZE
));
}
typedef
internal
::
IndexingIterator
<
Builder
,
typename
T
::
Builder
>
iterator
;
...
...
@@ -282,11 +281,11 @@ struct List<List<T>, true> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
List
<
T
>::
Builder
operator
[](
uint
index
)
{
return
typename
List
<
T
>::
Builder
(
builder
.
getListElement
(
index
*
REFERENCE
S
));
return
typename
List
<
T
>::
Builder
(
builder
.
getListElement
(
index
*
ELEMENT
S
));
}
inline
typename
List
<
T
>::
Builder
init
(
uint
index
,
uint
size
)
{
return
typename
List
<
T
>::
Builder
(
builder
.
initListElement
(
index
*
REFERENCE
S
,
internal
::
FieldSizeForType
<
T
>::
value
,
size
*
ELEMENTS
));
index
*
ELEMENT
S
,
internal
::
FieldSizeForType
<
T
>::
value
,
size
*
ELEMENTS
));
}
typedef
internal
::
IndexingIterator
<
Builder
,
typename
List
<
T
>::
Builder
>
iterator
;
...
...
@@ -312,7 +311,7 @@ struct List<List<T>, false> {
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
typename
List
<
T
>::
Reader
operator
[](
uint
index
)
{
return
typename
List
<
T
>::
Reader
(
reader
.
getListElement
(
index
*
REFERENCE
S
,
return
typename
List
<
T
>::
Reader
(
reader
.
getListElement
(
index
*
ELEMENT
S
,
internal
::
FieldSizeForType
<
T
>::
value
));
}
...
...
@@ -331,11 +330,11 @@ struct List<List<T>, false> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
List
<
T
>::
Builder
operator
[](
uint
index
)
{
return
typename
List
<
T
>::
Builder
(
builder
.
getListElement
(
index
*
REFERENCE
S
));
return
typename
List
<
T
>::
Builder
(
builder
.
getListElement
(
index
*
ELEMENT
S
));
}
inline
typename
List
<
T
>::
Builder
init
(
uint
index
,
uint
size
)
{
return
typename
List
<
T
>::
Builder
(
builder
.
initStructListElement
(
index
*
REFERENCE
S
,
size
*
ELEMENTS
,
T
::
DEFAULT
.
words
));
index
*
ELEMENT
S
,
size
*
ELEMENTS
,
T
::
DEFAULT
.
words
));
}
typedef
internal
::
IndexingIterator
<
Builder
,
typename
List
<
T
>::
Builder
>
iterator
;
...
...
@@ -361,7 +360,7 @@ struct List<Data, false> {
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
Data
::
Reader
operator
[](
uint
index
)
{
return
reader
.
getDataElement
(
index
*
REFERENCE
S
);
return
reader
.
getDataElement
(
index
*
ELEMENT
S
);
}
typedef
internal
::
IndexingIterator
<
Reader
,
Data
::
Reader
>
iterator
;
...
...
@@ -379,13 +378,13 @@ struct List<Data, false> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
Data
::
Builder
operator
[](
uint
index
)
{
return
builder
.
getDataElement
(
index
*
REFERENCE
S
);
return
builder
.
getDataElement
(
index
*
ELEMENT
S
);
}
inline
void
set
(
uint
index
,
Data
::
Reader
value
)
{
builder
.
setDataElement
(
index
*
REFERENCE
S
,
value
);
builder
.
setDataElement
(
index
*
ELEMENT
S
,
value
);
}
inline
Data
::
Builder
init
(
uint
index
,
uint
size
)
{
return
builder
.
initDataElement
(
index
*
REFERENCE
S
,
size
*
BYTES
);
return
builder
.
initDataElement
(
index
*
ELEMENT
S
,
size
*
BYTES
);
}
typedef
internal
::
IndexingIterator
<
Builder
,
Data
::
Builder
>
iterator
;
...
...
@@ -425,7 +424,7 @@ struct List<Text, false> {
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
Text
::
Reader
operator
[](
uint
index
)
{
return
reader
.
getTextElement
(
index
*
REFERENCE
S
);
return
reader
.
getTextElement
(
index
*
ELEMENT
S
);
}
typedef
internal
::
IndexingIterator
<
Reader
,
Text
::
Reader
>
iterator
;
...
...
@@ -443,13 +442,13 @@ struct List<Text, false> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
Text
::
Builder
operator
[](
uint
index
)
{
return
builder
.
getTextElement
(
index
*
REFERENCE
S
);
return
builder
.
getTextElement
(
index
*
ELEMENT
S
);
}
inline
void
set
(
uint
index
,
Text
::
Reader
value
)
{
builder
.
setTextElement
(
index
*
REFERENCE
S
,
value
);
builder
.
setTextElement
(
index
*
ELEMENT
S
,
value
);
}
inline
Text
::
Builder
init
(
uint
index
,
uint
size
)
{
return
builder
.
initTextElement
(
index
*
REFERENCE
S
,
size
*
BYTES
);
return
builder
.
initTextElement
(
index
*
ELEMENT
S
,
size
*
BYTES
);
}
typedef
internal
::
IndexingIterator
<
Builder
,
Text
::
Builder
>
iterator
;
...
...
c++/src/capnproto/test.capnp
View file @
eab15190
...
...
@@ -276,7 +276,7 @@ struct TestUsing {
innerNestedEnum @0 :NestedEnum = quux;
}
struct TestInline0 fixed(0 bits) {}
struct TestInline0 fixed(0 bits) {
f @0: Void;
}
struct TestInline1 fixed(1 bits) { f @0: Bool; }
struct TestInline8 fixed(8 bits) { f0 @0: Bool; f1 @1: Bool; f2 @2: Bool; }
struct TestInline16 fixed(16 bits) { f0 @0: UInt8; f1 @1: UInt8; }
...
...
@@ -384,9 +384,37 @@ struct TestInlineUnions {
byte0 @39: UInt8;
}
struct TestInlineLists {
voidList @ 0 : InlineList(Void, 2);
boolList @ 1 : InlineList(Bool, 3);
uInt8List @ 2 : InlineList(UInt8, 4);
uInt16List @ 3 : InlineList(UInt16, 5);
uInt32List @ 4 : InlineList(UInt32, 6);
uInt64List @ 5 : InlineList(UInt64, 7);
textList @ 6 : InlineList(Text, 8);
structList0 @ 7 : InlineList(TestInline0, 2);
structList1 @ 8 : InlineList(TestInline1, 3);
structList8 @ 9 : InlineList(TestInline8, 4);
structList16 @10 : InlineList(TestInline16, 2);
structList32 @11 : InlineList(TestInline32, 3);
structList64 @12 : InlineList(TestInline64, 4);
structList128 @13 : InlineList(TestInline128, 2);
structList192 @14 : InlineList(TestInline192, 3);
structList0p @15 : InlineList(TestInline0p, 4);
structList1p @16 : InlineList(TestInline1p, 2);
structList8p @17 : InlineList(TestInline8p, 3);
structList16p @18 : InlineList(TestInline16p, 4);
structList32p @19 : InlineList(TestInline32p, 2);
structList64p @20 : InlineList(TestInline64p, 3);
structList128p @21 : InlineList(TestInline128p, 4);
structList192p @22 : InlineList(TestInline192p, 2);
}
struct TestInlineDefaults {
normal @0 :TestInlineLayout = (
f0 = (),
f0 = (
f = void
),
f1 = (f = true),
f8 = (f0 = true, f1 = false, f2 = true),
f16 = (f0 = 123, f1 = 45),
...
...
@@ -411,4 +439,52 @@ struct TestInlineDefaults {
union1 = f128(f0 = 1234567890123, f1 = 4567890123456),
union2 = f1p(p0 = "foo"),
union3 = f16p(f = (f0 = 98, f1 = 76), p0 = "qux", p1 = "quux"));
lists @2 :TestInlineLists = (
voidList = [void, void],
boolList = [false, true, false],
uInt8List = [12, 34, 56, 78],
uInt16List = [1234, 5678, 9012, 3456, 7890],
uInt32List = [123456789, 234567890, 345678901, 456789012, 567890123, 678901234],
uInt64List = [1, 2, 3, 4, 5, 6, 7],
textList = ["foo", "bar", "baz", "qux", "quux", "corge", "grault", "garply"],
structList0 = [(f = void), ()],
structList1 = [(f = true), (f = false), (f = true)],
structList8 = [(f0 = true, f1 = false, f2 = false),
(f0 = false, f1 = true, f2 = false),
(f0 = true, f1 = true, f2 = false),
(f0 = false, f1 = false, f2 = true)],
structList16 = [(f0 = 12, f1 = 34), (f0 = 56, f1 = 78)],
structList32 = [(f0 = 90, f1 = 12345), (f0 = 67, f1 = 8901), (f0 = 23, f1 = 45678)],
structList64 = [(f0 = 90, f1 = 123456789), (f0 = 12, f1 = 345678901),
(f0 = 234, f1 = 567890123), (f0 = 45, f1 = 678901234)],
structList128 = [(f0 = 56789012345678, f1 = 90123456789012),
(f0 = 34567890123456, f1 = 78901234567890)],
structList192 = [(f0 = 1234567890123, f1 = 4567890123456, f2 = 7890123456789),
(f0 = 123456789012, f1 = 3456789012345, f2 = 6789012345678),
(f0 = 9012345678901, f1 = 2345678901234, f2 = 5678901234567)],
structList0p = [(f = (f = void), p0 = "foo"), (p0 = "bar"),
(f = (), p0 = "baz"), (p0 = "qux")],
structList1p = [(f = (f = true), p0 = "quux"), (p0 = "corge")],
structList8p = [(f = (f0 = true), p0 = "grault"), (p0 = "garply"), (p0 = "waldo")],
structList16p = [(f = (f0 = 123), p0 = "fred", p1 = "plugh"),
(p0 = "xyzzy", p1 = "thud"),
(p0 = "foobar", p1 = "barbaz"),
(p0 = "bazqux", p1 = "quxquux")],
structList32p = [(f = (f1 = 12345), p0 = "quuxcorge", p1 = "corgegrault"),
(p0 = "graultgarply", p1 = "garplywaldo")],
structList64p = [(f = (f1 = 123456789), p0 = "waldofred", p1 = "fredplugh"),
(p0 = "plughxyzzy", p1 = "xyzzythud"),
(p0 = "thudfoo", p1 = "foofoo")],
structList128p = [(f = (f1 = 123456789012345),
p0 = "foobaz", p1 = "fooqux", p2 = "foocorge"),
(p0 = "barbaz", p1 = "barqux", p2 = "barcorge"),
(p0 = "bazbaz", p1 = "bazqux", p2 = "bazcorge"),
(p0 = "quxbaz", p1 = "quxqux", p2 = "quxcorge")],
structList192p = [(f = (f2 = 123456789012345),
p0 = "corgebaz", p1 = "corgequx", p2 = "corgecorge"),
(p0 = "graultbaz", p1 = "graultqux", p2 = "graultcorge")]
);
}
c++/src/capnproto/type-safety.h
View file @
eab15190
...
...
@@ -326,6 +326,21 @@ public:
unit1PerUnit2
*
other
.
unit1PerUnit2
);
}
template
<
typename
OtherNumber
,
typename
Unit3
>
inline
constexpr
UnitRatio
<
decltype
(
Number
(
1
)
*
OtherNumber
(
1
)),
Unit3
,
Unit2
>
operator
/
(
UnitRatio
<
OtherNumber
,
Unit1
,
Unit3
>
other
)
{
// (U1 / U2) / (U1 / U3) = U3 / U2
return
UnitRatio
<
decltype
(
Number
(
1
)
*
OtherNumber
(
1
)),
Unit3
,
Unit2
>
(
unit1PerUnit2
/
other
.
unit1PerUnit2
);
}
template
<
typename
OtherNumber
,
typename
Unit3
>
inline
constexpr
UnitRatio
<
decltype
(
Number
(
1
)
*
OtherNumber
(
1
)),
Unit1
,
Unit3
>
operator
/
(
UnitRatio
<
OtherNumber
,
Unit3
,
Unit2
>
other
)
{
// (U1 / U2) / (U3 / U2) = U1 / U3
return
UnitRatio
<
decltype
(
Number
(
1
)
*
OtherNumber
(
1
)),
Unit1
,
Unit3
>
(
unit1PerUnit2
/
other
.
unit1PerUnit2
);
}
private
:
Number
unit1PerUnit2
;
...
...
compiler/src/Compiler.hs
View file @
eab15190
...
...
@@ -295,7 +295,13 @@ compileType scope (TypeExpression n params) = do
desc
<-
lookupDesc
scope
n
case
desc
of
DescBuiltinList
->
case
params
of
[
TypeParameterType
param
]
->
fmap
ListType
(
compileType
scope
param
)
[
TypeParameterType
param
]
->
do
inner
<-
compileType
scope
param
case
inner
of
InlineStructType
_
->
makeError
(
declNamePos
n
)
"Don't declare list elements 'Inline'. The regular encoding for struct
\
\
lists already inlines the elements."
_
->
return
(
ListType
inner
)
_
->
makeError
(
declNamePos
n
)
"'List' requires exactly one type parameter."
DescBuiltinInline
->
case
params
of
[
TypeParameterType
param
]
->
do
...
...
@@ -311,7 +317,18 @@ compileType scope (TypeExpression n params) = do
DescBuiltinInlineList
->
case
params
of
[
TypeParameterType
param
,
TypeParameterInteger
size
]
->
do
inner
<-
compileType
scope
param
return
$
InlineListType
inner
size
case
inner
of
InlineStructType
_
->
makeError
(
declNamePos
n
)
"Don't declare list elements 'Inline'. The regular encoding for struct
\
\
lists already inlines the elements."
StructType
s
->
if
structIsFixedWidth
s
then
return
(
InlineListType
(
InlineStructType
s
)
size
)
else
makeError
(
declNamePos
n
)
$
printf
"'%s' cannot be inlined because it is not fixed-width."
(
structName
s
)
InlineListType
_
_
->
makeError
(
declNamePos
n
)
"InlineList of InlineList not currently supported."
_
->
return
$
InlineListType
inner
size
_
->
makeError
(
declNamePos
n
)
"'InlineList' requires exactly two type parameters: a type and a size."
_
->
case
params
of
...
...
compiler/src/CxxGenerator.hs
View file @
eab15190
...
...
@@ -105,17 +105,24 @@ isInlineStruct (InlineStructType _) = True
isInlineStruct
_
=
False
isList
(
ListType
_
)
=
True
isList
(
InlineListType
_
_
)
=
True
isList
_
=
False
isNonStructList
(
ListType
t
)
=
not
$
isStruct
t
isNonStructList
(
InlineListType
t
_
)
=
not
$
isStruct
t
isNonStructList
_
=
False
isPrimitiveList
(
ListType
t
)
=
isPrimitive
t
isPrimitiveList
(
InlineListType
t
_
)
=
isPrimitive
t
isPrimitiveList
_
=
False
isStructList
(
ListType
t
)
=
isStruct
t
isStructList
(
InlineListType
t
_
)
=
isStruct
t
isStructList
_
=
False
isInlineList
(
InlineListType
_
_
)
=
True
isInlineList
_
=
False
blobTypeString
(
BuiltinType
BuiltinText
)
=
"Text"
blobTypeString
(
BuiltinType
BuiltinData
)
=
"Data"
blobTypeString
_
=
error
"Not a blob."
...
...
@@ -139,6 +146,7 @@ cxxTypeString (StructType desc) = globalName $ DescStruct desc
cxxTypeString
(
InlineStructType
desc
)
=
globalName
$
DescStruct
desc
cxxTypeString
(
InterfaceType
desc
)
=
globalName
$
DescInterface
desc
cxxTypeString
(
ListType
t
)
=
concat
[
" ::capnproto::List<"
,
cxxTypeString
t
,
">"
]
cxxTypeString
(
InlineListType
t
_
)
=
concat
[
" ::capnproto::List<"
,
cxxTypeString
t
,
">"
]
cxxFieldSizeString
SizeVoid
=
"VOID"
;
cxxFieldSizeString
(
SizeData
Size1
)
=
"BIT"
;
...
...
@@ -203,6 +211,7 @@ defaultValueBytes t v@(ListDesc _) = Just $ encodeMessage t v
defaultValueBytes
_
_
=
Nothing
elementType
(
ListType
t
)
=
t
elementType
(
InlineListType
t
_
)
=
t
elementType
_
=
error
"Called elementType on non-list."
repeatedlyTake
_
[]
=
[]
...
...
@@ -244,6 +253,7 @@ fieldContext parent desc = mkStrContext context where
context
"fieldIsNonStructList"
=
MuBool
$
isNonStructList
$
fieldType
desc
context
"fieldIsPrimitiveList"
=
MuBool
$
isPrimitiveList
$
fieldType
desc
context
"fieldIsStructList"
=
MuBool
$
isStructList
$
fieldType
desc
context
"fieldIsInlineList"
=
MuBool
$
isInlineList
$
fieldType
desc
context
"fieldDefaultBytes"
=
case
fieldDefaultValue
desc
>>=
defaultValueBytes
(
fieldType
desc
)
of
Just
v
->
muJust
$
defaultBytesContext
context
(
fieldType
desc
)
v
...
...
@@ -251,6 +261,23 @@ fieldContext parent desc = mkStrContext context where
context
"fieldType"
=
MuVariable
$
cxxTypeString
$
fieldType
desc
context
"fieldBlobType"
=
MuVariable
$
blobTypeString
$
fieldType
desc
context
"fieldOffset"
=
MuVariable
$
fieldOffsetInteger
$
fieldOffset
desc
context
"fieldInlineListSize"
=
case
fieldType
desc
of
InlineListType
_
n
->
MuVariable
n
_
->
muNull
context
"fieldInlineDataOffset"
=
case
fieldOffset
desc
of
InlineCompositeOffset
off
_
size
_
->
MuVariable
(
off
*
dataSizeInBits
(
dataSectionAlignment
size
))
_
->
muNull
context
"fieldInlineDataSize"
=
case
fieldOffset
desc
of
InlineCompositeOffset
_
_
size
_
->
MuVariable
$
dataSectionBits
size
_
->
muNull
context
"fieldInlinePointerOffset"
=
case
fieldOffset
desc
of
InlineCompositeOffset
_
off
_
_
->
MuVariable
off
_
->
muNull
context
"fieldInlinePointerSize"
=
case
fieldOffset
desc
of
InlineCompositeOffset
_
_
_
size
->
MuVariable
size
_
->
muNull
context
"fieldDefaultMask"
=
case
fieldDefaultValue
desc
of
Nothing
->
MuVariable
""
Just
v
->
MuVariable
(
if
isDefaultZero
v
then
""
else
", "
++
defaultMask
v
)
...
...
@@ -303,6 +330,7 @@ structContext parent desc = mkStrContext context where
context
"structFields"
=
MuList
$
map
(
fieldContext
context
)
$
structFields
desc
context
"structUnions"
=
MuList
$
map
(
unionContext
context
)
$
structUnions
desc
context
"structDataSize"
=
MuVariable
$
dataSectionWordSize
$
structDataSize
desc
context
"structDataBits"
=
MuVariable
$
dataSectionBits
$
structDataSize
desc
context
"structReferenceCount"
=
MuVariable
$
structPointerCount
desc
context
"structNestedEnums"
=
MuList
$
map
(
enumContext
context
)
[
m
|
DescEnum
m
<-
structMembers
desc
]
...
...
compiler/src/Semantics.hs
View file @
eab15190
...
...
@@ -320,6 +320,7 @@ fieldSize (InterfaceType _) = SizeReference
fieldSize
(
ListType
_
)
=
SizeReference
fieldSize
(
InlineListType
element
size
)
=
let
minDataSectionForBits
bits
|
bits
<=
0
=
DataSectionWords
0
|
bits
<=
1
=
DataSection1
|
bits
<=
8
=
DataSection8
|
bits
<=
16
=
DataSection16
...
...
@@ -329,12 +330,12 @@ fieldSize (InlineListType element size) = let
SizeVoid
->
DataSectionWords
0
SizeData
s
->
minDataSectionForBits
$
dataSizeInBits
s
*
size
SizeReference
->
DataSectionWords
0
SizeInlineComposite
ds
_
->
minDataSectionForBits
$
dataSectionBits
ds
SizeInlineComposite
ds
_
->
minDataSectionForBits
$
dataSectionBits
ds
*
size
pointerCount
=
case
fieldSize
element
of
SizeVoid
->
0
SizeData
_
->
0
SizeReference
->
size
SizeInlineComposite
_
pc
->
pc
SizeInlineComposite
_
pc
->
pc
*
size
in
SizeInlineComposite
dataSection
pointerCount
-- Render the type descriptor's name as a string, appropriate for use in the given scope.
...
...
compiler/src/WireFormat.hs
View file @
eab15190
...
...
@@ -29,6 +29,7 @@ import Data.Bits(shiftL, shiftR, Bits, setBit, xor)
import
Data.Function
(
on
)
import
Semantics
import
Data.Binary.IEEE754
(
floatToWord
,
doubleToWord
)
import
Text.Printf
(
printf
)
import
qualified
Codec.Binary.UTF8.String
as
UTF8
byte
::
(
Integral
a
,
Bits
a
)
=>
a
->
Int
->
Word8
...
...
@@ -45,6 +46,7 @@ padToWord b = let
data
EncodedData
=
EncodedBit
Bool
|
EncodedBytes
[
Word8
]
deriving
(
Show
)
xorData
(
EncodedBit
a
)
(
EncodedBit
b
)
=
EncodedBit
(
a
/=
b
)
xorData
(
EncodedBytes
a
)
(
EncodedBytes
b
)
=
EncodedBytes
(
zipWith
xor
a
b
)
...
...
@@ -92,7 +94,7 @@ encodePointerValue _ _ = error "Unknown pointer type."
packBytes
::
Integer
-- Total size of array to pack, in bits.
->
[(
Integer
,
EncodedData
)]
-- (offset, data) pairs to pack. Must be in order.
->
[
Word8
]
packBytes
size
=
padToWord
.
loop
0
where
packBytes
size
items
=
padToWord
$
loop
0
items
where
loop
::
Integer
->
[(
Integer
,
EncodedData
)]
->
[
Word8
]
loop
bit
[]
|
bit
<=
size
=
genericReplicate
(
div
(
size
-
bit
+
7
)
8
)
0
loop
bit
[]
|
bit
>
size
=
error
"Data values overran size."
...
...
@@ -103,7 +105,8 @@ packBytes size = padToWord . loop 0 where
loop
bit
((
_
,
EncodedBit
False
)
:
rest
)
=
loop
bit
rest
loop
bit
((
offset
,
EncodedBytes
encoded
)
:
rest
)
|
offset
==
bit
=
encoded
++
loop
(
bit
+
genericLength
encoded
*
8
)
rest
loop
_
_
=
error
"Data values overlapped."
loop
bit
rest
=
error
(
printf
"Data values overlapped @%d: %s
\n\n
%s"
bit
(
show
rest
)
(
show
items
))
bytesToWords
i
=
if
mod
i
8
==
0
then
div
i
8
else
error
"Byte count did not divide evenly into words."
...
...
compiler/src/c++-header.mustache
View file @
eab15190
...
...
@@ -69,7 +69,8 @@ struct {{typeFullName}} {
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
::capnproto::internal::StructSize(
{{
structDataSize
}}
* ::capnproto::WORDS,
{{
structReferenceCount
}}
* ::capnproto::REFERENCES);
{{
structReferenceCount
}}
* ::capnproto::REFERENCES,
{{
structDataBits
}}
* ::capnproto::BITS);
{{/
typeStruct
}}
{{#
typeUnion
}}
...
...
@@ -172,7 +173,12 @@ public:
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
{{/
fieldIsStruct
}}
{{#
fieldIsNonStructList
}}
{{#
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
();
{{/
fieldIsInlineList
}}
{{^
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
(unsigned int size);
{{/
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
template
<typename
_t
>
inline void set
{{
fieldTitleCase
}}
(const _t
&
other);
...
...
@@ -184,7 +190,12 @@ public:
{{/
fieldIsPrimitiveList
}}
{{/
fieldIsNonStructList
}}
{{#
fieldIsStructList
}}
{{#
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
();
{{/
fieldIsInlineList
}}
{{^
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
(unsigned int size);
{{/
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
{{/
fieldIsStructList
}}
{{/
typeFields
}}
...
...
@@ -356,6 +367,75 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{/
fieldIsStruct
}}
{{! ------------------------------------------------------------------------------------------- }}
{{#
fieldIsNonStructList
}}
{{#
fieldIsInlineList
}}
{{#
fieldIsPrimitiveList
}}
inline
{{
fieldType
}}
::Reader
{{
typeFullName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Reader(_reader.getInlineDataListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::BITS,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::
{{
fieldElementSize
}}
));
}
inline
{{
fieldType
}}
::Builder
{{
typeFullName
}}
::Builder::init
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.initInlineDataListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::BITS,
{{
fieldInlineDataSize
}}
* ::capnproto::BITS,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::
{{
fieldElementSize
}}
));
}
inline
{{
fieldType
}}
::Builder
{{
typeFullName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.getInlineDataListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::BITS,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::
{{
fieldElementSize
}}
));
}
{{/
fieldIsPrimitiveList
}}
{{^
fieldIsPrimitiveList
}}
inline
{{
fieldType
}}
::Reader
{{
typeFullName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Reader(_reader.getInlinePointerListField(
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS));
}
inline
{{
fieldType
}}
::Builder
{{
typeFullName
}}
::Builder::init
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.initInlinePointerListField(
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlinePointerSize
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS));
}
inline
{{
fieldType
}}
::Builder
{{
typeFullName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.getInlinePointerListField(
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS));
}
{{/
fieldIsPrimitiveList
}}
{{/
fieldIsInlineList
}}
{{! --------------------------------- }}
{{^
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Reader
{{
typeFullName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
...
...
@@ -388,15 +468,17 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}
nullptr
{{/
fieldDefaultBytes
}}
));
}
{{/
fieldIsInlineList
}}
{{! --------------------------------- }}
template
<typename
_t
>
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(const _t
&
other) {
{{#
fieldUnion
}}
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
init
{{
fieldTitleCase
}}
(
other.size()
).copyFrom(other);
init
{{
fieldTitleCase
}}
(
{{^
fieldIsInlineList
}}
other.size()
{{/
fieldIsInlineList
}}
).copyFrom(other);
}
{{! ------------------------------------------------------------------------------------------- }}
{{#
fieldIsPrimitiveList
}}
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(
std::initializer_list
<
{{
fieldElementType
}}
>
other) {
...
...
@@ -404,10 +486,9 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
init
{{
fieldTitleCase
}}
(
other.size()
).copyFrom(other);
init
{{
fieldTitleCase
}}
(
{{^
fieldIsInlineList
}}
other.size()
{{/
fieldIsInlineList
}}
).copyFrom(other);
}
{{/
fieldIsPrimitiveList
}}
{{! ------------------------------------------------------------------------------------------- }}
{{^
fieldIsPrimitiveList
}}
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(
std::initializer_list
<
{{
fieldElementType
}}
::Reader>
other) {
...
...
@@ -415,12 +496,49 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
init
{{
fieldTitleCase
}}
(
other.size()
).copyFrom(other);
init
{{
fieldTitleCase
}}
(
{{^
fieldIsInlineList
}}
other.size()
{{/
fieldIsInlineList
}}
).copyFrom(other);
}
{{/
fieldIsPrimitiveList
}}
{{/
fieldIsNonStructList
}}
{{! ------------------------------------------------------------------------------------------- }}
{{#
fieldIsStructList
}}
{{#
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Reader
{{
typeFullName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Reader(_reader.getInlineStructListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::BITS,
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
{{
fieldElementType
}}
::STRUCT_SIZE));
}
inline
{{
fieldType
}}
::Builder
{{
typeFullName
}}
::Builder::init
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.initInlineStructListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::BITS,
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
{{
fieldElementType
}}
::STRUCT_SIZE));
}
inline
{{
fieldType
}}
::Builder
{{
typeFullName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.getInlineStructListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::BITS,
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
{{
fieldElementType
}}
::STRUCT_SIZE));
}
{{/
fieldIsInlineList
}}
{{^
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Reader
{{
typeFullName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
...
...
@@ -452,6 +570,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}
nullptr
{{/
fieldDefaultBytes
}}
));
}
{{/
fieldIsInlineList
}}
{{/
fieldIsStructList
}}
{{/
typeFields
}}
{{/
typeStructOrUnion
}}
...
...
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