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) {
...
@@ -594,6 +594,184 @@ TEST(Encoding, InlineDefaults) {
EXPECT_EQ
(
"qux"
,
unions
.
getUnion3
().
getF16p
().
getP0
());
EXPECT_EQ
(
"qux"
,
unions
.
getUnion3
().
getF16p
().
getP0
());
EXPECT_EQ
(
"quux"
,
unions
.
getUnion3
().
getF16p
().
getP1
());
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,
...
@@ -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
=
static
const
AlignedData
<
2
>
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
=
{{
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}};
{{
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
)
{
static
void
setupStruct
(
StructBuilder
builder
)
{
builder
.
setDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
0x1011121314151617ull
);
builder
.
setDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
0x1011121314151617ull
);
builder
.
setDataField
<
uint32_t
>
(
2
*
ELEMENTS
,
0x20212223u
);
builder
.
setDataField
<
uint32_t
>
(
2
*
ELEMENTS
,
0x20212223u
);
...
@@ -118,7 +120,7 @@ static void setupStruct(StructBuilder builder) {
...
@@ -118,7 +120,7 @@ static void setupStruct(StructBuilder builder) {
{
{
StructBuilder
subStruct
=
builder
.
initStructField
(
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
);
subStruct
.
setDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
123
);
}
}
...
@@ -132,12 +134,12 @@ static void setupStruct(StructBuilder builder) {
...
@@ -132,12 +134,12 @@ static void setupStruct(StructBuilder builder) {
{
{
ListBuilder
list
=
builder
.
initStructListField
(
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
());
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
,
STRUCTLIST_ELEMENT_SIZE
);
element
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
300
+
i
);
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
);
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
400
+
i
);
}
}
}
}
...
@@ -147,7 +149,7 @@ static void setupStruct(StructBuilder builder) {
...
@@ -147,7 +149,7 @@ static void setupStruct(StructBuilder builder) {
EXPECT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
EXPECT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
for
(
uint
i
=
0
;
i
<
5
;
i
++
)
{
for
(
uint
i
=
0
;
i
<
5
;
i
++
)
{
ListBuilder
element
=
list
.
initListElement
(
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
());
EXPECT_EQ
((
i
+
1
)
*
ELEMENTS
,
element
.
size
());
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
element
.
setDataElement
<
uint16_t
>
(
j
*
ELEMENTS
,
500
+
j
);
element
.
setDataElement
<
uint16_t
>
(
j
*
ELEMENTS
,
500
+
j
);
...
@@ -172,7 +174,7 @@ static void checkStruct(StructBuilder builder) {
...
@@ -172,7 +174,7 @@ static void checkStruct(StructBuilder builder) {
{
{
StructBuilder
subStruct
=
builder
.
getStructField
(
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
));
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
}
}
...
@@ -188,10 +190,10 @@ static void checkStruct(StructBuilder builder) {
...
@@ -188,10 +190,10 @@ static void checkStruct(StructBuilder builder) {
ListBuilder
list
=
builder
.
getListField
(
2
*
REFERENCES
,
nullptr
);
ListBuilder
list
=
builder
.
getListField
(
2
*
REFERENCES
,
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
++
)
{
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
(
300
+
i
,
element
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
400
+
i
,
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
)
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
}
}
...
@@ -201,7 +203,7 @@ static void checkStruct(StructBuilder builder) {
...
@@ -201,7 +203,7 @@ static void checkStruct(StructBuilder builder) {
ListBuilder
list
=
builder
.
getListField
(
3
*
REFERENCES
,
nullptr
);
ListBuilder
list
=
builder
.
getListField
(
3
*
REFERENCES
,
nullptr
);
ASSERT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
ASSERT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
for
(
uint
i
=
0
;
i
<
5
;
i
++
)
{
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
());
ASSERT_EQ
((
i
+
1
)
*
ELEMENTS
,
element
.
size
());
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
EXPECT_EQ
(
500u
+
j
,
element
.
getDataElement
<
uint16_t
>
(
j
*
ELEMENTS
));
EXPECT_EQ
(
500u
+
j
,
element
.
getDataElement
<
uint16_t
>
(
j
*
ELEMENTS
));
...
@@ -254,7 +256,7 @@ static void checkStruct(StructReader reader) {
...
@@ -254,7 +256,7 @@ static void checkStruct(StructReader reader) {
ListReader
list
=
reader
.
getListField
(
3
*
REFERENCES
,
FieldSize
::
REFERENCE
,
nullptr
);
ListReader
list
=
reader
.
getListField
(
3
*
REFERENCES
,
FieldSize
::
REFERENCE
,
nullptr
);
ASSERT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
ASSERT_EQ
(
5
*
ELEMENTS
,
list
.
size
());
for
(
uint
i
=
0
;
i
<
5
;
i
++
)
{
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
());
ASSERT_EQ
((
i
+
1
)
*
ELEMENTS
,
element
.
size
());
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
for
(
uint
j
=
0
;
j
<=
i
;
j
++
)
{
EXPECT_EQ
(
500u
+
j
,
element
.
getDataElement
<
uint16_t
>
(
j
*
ELEMENTS
));
EXPECT_EQ
(
500u
+
j
,
element
.
getDataElement
<
uint16_t
>
(
j
*
ELEMENTS
));
...
@@ -270,7 +272,7 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
...
@@ -270,7 +272,7 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
128
*
BITS
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// word count:
// word count:
...
@@ -306,7 +308,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
...
@@ -306,7 +308,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
128
*
BITS
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// Verify that we made 15 segments.
// Verify that we made 15 segments.
...
@@ -343,7 +345,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
...
@@ -343,7 +345,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
128
*
BITS
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// Verify that we made 6 segments.
// Verify that we made 6 segments.
...
...
c++/src/capnproto/layout.c++
View file @
eab15190
...
@@ -415,7 +415,8 @@ struct WireHelpers {
...
@@ -415,7 +415,8 @@ struct WireHelpers {
ref
->
structRef
.
set
(
size
);
ref
->
structRef
.
set
(
size
);
// Build the StructBuilder.
// 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
(
static
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
getWritableStructReference
(
...
@@ -442,7 +443,8 @@ struct WireHelpers {
...
@@ -442,7 +443,8 @@ struct WireHelpers {
"Trying to update struct with incorrect reference count."
);
"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
(
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initListReference
(
...
@@ -451,9 +453,10 @@ struct WireHelpers {
...
@@ -451,9 +453,10 @@ struct WireHelpers {
DPRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
DPRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
"Should have called initStructListReference() instead."
);
"Should have called initStructListReference() instead."
);
auto
step
=
bitsPerElement
(
elementSize
);
// Calculate size of the list.
// Calculate size of the list.
WordCount
wordCount
=
roundUpToWords
(
WordCount
wordCount
=
roundUpToWords
(
ElementCount64
(
elementCount
)
*
step
);
ElementCount64
(
elementCount
)
*
bitsPerElement
(
elementSize
));
// Allocate the list.
// Allocate the list.
word
*
ptr
=
allocate
(
ref
,
segment
,
wordCount
,
WireReference
::
LIST
);
word
*
ptr
=
allocate
(
ref
,
segment
,
wordCount
,
WireReference
::
LIST
);
...
@@ -462,12 +465,33 @@ struct WireHelpers {
...
@@ -462,12 +465,33 @@ struct WireHelpers {
ref
->
listRef
.
set
(
elementSize
,
elementCount
);
ref
->
listRef
.
set
(
elementSize
,
elementCount
);
// Build the ListBuilder.
// 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
(
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initStructListReference
(
WireReference
*
ref
,
SegmentBuilder
*
segment
,
ElementCount
elementCount
,
WireReference
*
ref
,
SegmentBuilder
*
segment
,
ElementCount
elementCount
,
StructSize
elementSize
))
{
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
;
auto
wordsPerElement
=
elementSize
.
total
()
/
ELEMENTS
;
// Allocate the list, prefixed by a single WireReference.
// Allocate the list, prefixed by a single WireReference.
...
@@ -485,7 +509,9 @@ struct WireHelpers {
...
@@ -485,7 +509,9 @@ struct WireHelpers {
ptr
+=
REFERENCE_SIZE_IN_WORDS
;
ptr
+=
REFERENCE_SIZE_IN_WORDS
;
// Build the ListBuilder.
// 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
(
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getWritableListReference
(
...
@@ -495,7 +521,8 @@ struct WireHelpers {
...
@@ -495,7 +521,8 @@ struct WireHelpers {
if
(
ref
->
isNull
())
{
if
(
ref
->
isNull
())
{
if
(
defaultValue
==
nullptr
)
{
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
);
ptr
=
copyMessage
(
segment
,
ref
,
defaultRef
);
}
else
{
}
else
{
...
@@ -510,12 +537,19 @@ struct WireHelpers {
...
@@ -510,12 +537,19 @@ struct WireHelpers {
WireReference
*
tag
=
reinterpret_cast
<
WireReference
*>
(
ptr
);
WireReference
*
tag
=
reinterpret_cast
<
WireReference
*>
(
ptr
);
PRECOND
(
tag
->
kind
()
==
WireReference
::
STRUCT
,
PRECOND
(
tag
->
kind
()
==
WireReference
::
STRUCT
,
"INLINE_COMPOSITE list with non-STRUCT elements not supported."
);
"INLINE_COMPOSITE list with non-STRUCT elements not supported."
);
ElementCount
elementCount
=
tag
->
inlineCompositeListElementCount
();
// First list element is at tag + 1 reference.
// 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
{
}
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 {
...
@@ -649,7 +683,9 @@ struct WireHelpers {
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
useDefault
:
if
(
defaultValue
==
nullptr
)
{
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
;
segment
=
nullptr
;
ref
=
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
);
ref
=
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
);
...
@@ -751,7 +787,10 @@ struct WireHelpers {
...
@@ -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
.
dataSize
.
get
()
*
BITS_PER_WORD
,
tag
->
structRef
.
refCount
.
get
(),
nestingLimit
-
1
);
tag
->
structRef
.
refCount
.
get
(),
nestingLimit
-
1
);
...
@@ -768,7 +807,9 @@ struct WireHelpers {
...
@@ -768,7 +807,9 @@ struct WireHelpers {
}
}
if
(
ref
->
listRef
.
elementSize
()
==
expectedElementSize
)
{
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
)
{
}
else
if
(
expectedElementSize
==
FieldSize
::
INLINE_COMPOSITE
)
{
// We were expecting a struct list, but we received a list of some other type. Perhaps a
// 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
// non-struct list was recently upgraded to a struct list, but the sender is using the
...
@@ -792,7 +833,8 @@ struct WireHelpers {
...
@@ -792,7 +833,8 @@ struct WireHelpers {
break
;
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
);
dataSize
,
referenceCount
,
nestingLimit
-
1
);
}
else
{
}
else
{
PRECOND
(
segment
!=
nullptr
,
"Trusted message had incompatible list element type."
);
PRECOND
(
segment
!=
nullptr
,
"Trusted message had incompatible list element type."
);
...
@@ -1017,101 +1059,102 @@ Data::Reader StructReader::getDataField(
...
@@ -1017,101 +1059,102 @@ Data::Reader StructReader::getDataField(
return
WireHelpers
::
readDataReference
(
segment
,
ref
,
defaultValue
,
defaultSize
);
return
WireHelpers
::
readDataReference
(
segment
,
ref
,
defaultValue
,
defaultSize
);
}
}
StructBuilder
ListBuilder
::
getStructElement
(
StructBuilder
ListBuilder
::
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
{
ElementCount
index
,
decltype
(
WORDS
/
ELEMENTS
)
elementSize
,
WordCount
structDataSize
)
const
{
// TODO: Inline this method?
word
*
structPtr
=
ptr
+
elementSize
*
index
;
BitCount64
indexBit
=
ElementCount64
(
index
)
*
stepBits
;
return
StructBuilder
(
segment
,
structPtr
,
byte
*
structData
=
reinterpret_cast
<
byte
*>
(
data
)
+
indexBit
/
BITS_PER_BYTE
;
reinterpret_cast
<
WireReference
*>
(
structPtr
+
structDataSize
),
0
*
BITS
);
WireReference
*
structPointers
=
pointers
+
index
*
stepPointers
;
return
StructBuilder
(
segment
,
structData
,
structPointers
,
indexBit
%
BITS_PER_BYTE
,
elementSize
.
pointers
);
}
}
ListBuilder
ListBuilder
::
initListElement
(
ListBuilder
ListBuilder
::
initListElement
(
WireReference
Count
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
{
Element
Count
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
{
return
WireHelpers
::
initListReference
(
return
WireHelpers
::
initListReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
pointers
+
index
*
stepPointers
,
segment
,
elementCount
,
elementSize
);
elementCount
,
elementSize
);
}
}
ListBuilder
ListBuilder
::
initStructListElement
(
ListBuilder
ListBuilder
::
initStructListElement
(
WireReference
Count
index
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
Element
Count
index
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
return
WireHelpers
::
initStructListReference
(
return
WireHelpers
::
initStructListReference
(
reinterpret_cast
<
WireReference
*>
(
ptr
)
+
index
,
segment
,
pointers
+
index
*
stepPointers
,
segment
,
elementCount
,
elementSize
);
elementCount
,
elementSize
);
}
}
ListBuilder
ListBuilder
::
getListElement
(
WireReference
Count
index
)
const
{
ListBuilder
ListBuilder
::
getListElement
(
Element
Count
index
)
const
{
return
WireHelpers
::
getWritableListReference
(
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
(
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
(
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
(
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
(
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
(
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
(
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
{
ListReader
ListBuilder
::
asReader
(
FieldSize
elementSize
)
const
{
// TODO: For INLINE_COMPOSITE I suppose we could just check the tag?
// TODO: For INLINE_COMPOSITE I suppose we could just check the tag?
PRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
PRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
"Need to call the other asReader() overload for INLINE_COMPOSITE lists."
);
"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
());
std
::
numeric_limits
<
int
>::
max
());
}
}
ListReader
ListBuilder
::
asReader
(
BitCount
dataSize
,
WireReferenceCount
referenceCount
)
const
{
ListReader
ListBuilder
::
asReader
(
StructSize
elementSize
)
const
{
return
ListReader
(
segment
,
ptr
,
elementCount
,
return
ListReader
(
segment
,
data
,
pointers
,
elementCount
,
stepBits
,
stepPointers
,
(
dataSize
+
referenceCount
*
WORDS_PER_REFERENCE
*
BITS_PER_WORD
)
/
ELEMENTS
,
elementSize
.
dataBits
,
elementSize
.
pointers
,
std
::
numeric_limits
<
int
>::
max
());
dataSize
,
referenceCount
,
std
::
numeric_limits
<
int
>::
max
());
}
}
StructReader
ListReader
::
getStructElement
(
ElementCount
index
)
const
{
StructReader
ListReader
::
getStructElement
(
ElementCount
index
)
const
{
// TODO: Inline this method?
VALIDATE_INPUT
((
segment
==
nullptr
)
|
(
nestingLimit
>
0
),
VALIDATE_INPUT
((
segment
==
nullptr
)
|
(
nestingLimit
>
0
),
"Message is too deeply-nested or contains cycles. See capnproto::ReadOptions."
)
{
"Message is too deeply-nested or contains cycles. See capnproto::ReadOptions."
)
{
return
StructReader
::
readEmpty
();
return
StructReader
::
readEmpty
();
}
}
BitCount64
indexBit
=
ElementCount64
(
index
)
*
stepBits
;
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
(
return
StructReader
(
segment
,
structPtr
,
segment
,
structData
,
pointers
+
index
*
stepPointers
,
reinterpret_cast
<
const
WireReference
*>
(
structPtr
+
structDataSize
/
BITS_PER_BYTE
),
structDataSize
,
structReferenceCount
,
indexBit
%
BITS_PER_BYTE
,
nestingLimit
-
1
);
structDataSize
,
structReferenceCount
,
indexBit
%
BITS_PER_BYTE
,
nestingLimit
-
1
);
}
}
ListReader
ListReader
::
getListElement
(
ListReader
ListReader
::
getListElement
(
WireReference
Count
index
,
FieldSize
expectedElementSize
)
const
{
Element
Count
index
,
FieldSize
expectedElementSize
)
const
{
return
WireHelpers
::
readListReference
(
return
WireHelpers
::
readListReference
(
segment
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
)
+
index
,
segment
,
pointers
+
index
*
stepPointers
,
nullptr
,
expectedElementSize
,
nestingLimit
);
nullptr
,
expectedElementSize
,
nestingLimit
);
}
}
Text
::
Reader
ListReader
::
getTextElement
(
WireReference
Count
index
)
const
{
Text
::
Reader
ListReader
::
getTextElement
(
Element
Count
index
)
const
{
return
WireHelpers
::
readTextReference
(
segment
,
return
WireHelpers
::
readTextReference
(
reinterpret_cast
<
const
WireReference
*>
(
ptr
)
+
index
,
""
,
0
*
BYTES
);
segment
,
pointers
+
index
*
stepPointers
,
""
,
0
*
BYTES
);
}
}
Data
::
Reader
ListReader
::
getDataElement
(
WireReference
Count
index
)
const
{
Data
::
Reader
ListReader
::
getDataElement
(
Element
Count
index
)
const
{
return
WireHelpers
::
readDataReference
(
segment
,
return
WireHelpers
::
readDataReference
(
reinterpret_cast
<
const
WireReference
*>
(
ptr
)
+
index
,
nullptr
,
0
*
BYTES
);
segment
,
pointers
+
index
*
stepPointers
,
nullptr
,
0
*
BYTES
);
}
}
}
// namespace internal
}
// namespace internal
...
...
c++/src/capnproto/layout.h
View file @
eab15190
...
@@ -132,11 +132,15 @@ struct StructSize {
...
@@ -132,11 +132,15 @@ struct StructSize {
WordCount16
data
;
WordCount16
data
;
WireReferenceCount16
pointers
;
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
;
}
inline
constexpr
WordCount
total
()
const
{
return
data
+
pointers
*
WORDS_PER_REFERENCE
;
}
StructSize
()
=
default
;
StructSize
()
=
default
;
inline
constexpr
StructSize
(
WordCount
data
,
WireReferenceCount
pointers
)
inline
constexpr
StructSize
(
WordCount
data
,
WireReferenceCount
pointers
,
BitCount
dataBits
)
:
data
(
data
),
pointers
(
pointers
)
{}
:
data
(
data
),
pointers
(
pointers
)
,
dataBits
(
dataBits
)
{}
};
};
template
<
typename
T
>
template
<
typename
T
>
...
@@ -307,6 +311,34 @@ public:
...
@@ -307,6 +311,34 @@ public:
// already allocated, it is allocated as a deep copy of the given default value (a trusted
// 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.
// 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
;
Text
::
Builder
initTextField
(
WireReferenceCount
refIndex
,
ByteCount
size
)
const
;
// Initialize the text field to the given size in bytes (not including NUL terminator) and return
// 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.
// a Text::Builder which can be used to fill in the content.
...
@@ -327,6 +359,8 @@ public:
...
@@ -327,6 +359,8 @@ public:
StructReader
asReader
()
const
;
StructReader
asReader
()
const
;
// Gets a StructReader pointing at the same memory.
// Gets a StructReader pointing at the same memory.
WireReferenceCount
getReferenceCount
()
{
return
referenceCount
;
}
private
:
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the struct resides.
SegmentBuilder
*
segment
;
// Memory segment in which the struct resides.
void
*
data
;
// Pointer to the encoded data.
void
*
data
;
// Pointer to the encoded data.
...
@@ -336,9 +370,13 @@ private:
...
@@ -336,9 +370,13 @@ private:
// A special hack: When accessing a boolean with field number zero, pretend its offset is this
// 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.
// 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
,
inline
StructBuilder
(
SegmentBuilder
*
segment
,
void
*
data
,
WireReference
*
references
,
BitCount8
bit0Offset
)
BitCount8
bit0Offset
,
WireReferenceCount
referenceCount
)
:
segment
(
segment
),
data
(
data
),
references
(
references
),
bit0Offset
(
bit0Offset
)
{}
:
segment
(
segment
),
data
(
data
),
references
(
references
),
bit0Offset
(
bit0Offset
),
referenceCount
(
referenceCount
)
{}
friend
class
ListBuilder
;
friend
class
ListBuilder
;
friend
struct
WireHelpers
;
friend
struct
WireHelpers
;
...
@@ -382,6 +420,19 @@ public:
...
@@ -382,6 +420,19 @@ public:
// Get the list field at the given index in the reference segment, or the default value if not
// 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.
// 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
,
Text
::
Reader
getTextField
(
WireReferenceCount
refIndex
,
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
// Gets the text field, or the given default value if not initialized.
// Gets the text field, or the given default value if not initialized.
...
@@ -390,6 +441,8 @@ public:
...
@@ -390,6 +441,8 @@ public:
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
// Gets the data field, or the given default value if not initialized.
// Gets the data field, or the given default value if not initialized.
WireReferenceCount
getReferenceCount
()
{
return
referenceCount
;
}
private
:
private
:
SegmentReader
*
segment
;
// Memory segment in which the struct resides.
SegmentReader
*
segment
;
// Memory segment in which the struct resides.
...
@@ -425,7 +478,9 @@ private:
...
@@ -425,7 +478,9 @@ private:
class
ListBuilder
{
class
ListBuilder
{
public
:
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
();
inline
ElementCount
size
();
// The number of elements in the list.
// The number of elements in the list.
...
@@ -439,52 +494,61 @@ public:
...
@@ -439,52 +494,61 @@ public:
ElementCount
index
,
typename
NoInfer
<
T
>::
Type
value
)
const
);
ElementCount
index
,
typename
NoInfer
<
T
>::
Type
value
)
const
);
// Set the element at the given index.
// Set the element at the given index.
StructBuilder
getStructElement
(
StructBuilder
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
;
ElementCount
index
,
decltype
(
WORDS
/
ELEMENTS
)
elementSize
,
WordCount
structDataSize
)
const
;
// Get the struct element at the given index.
// Get the struct element at the given index. elementSize is the size, in 64-bit words, of
// each element.
ListBuilder
initListElement
(
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
// Create a new list element of the given size at the given index. All elements are initialized
// to zero.
// to zero.
ListBuilder
initStructListElement
(
WireReference
Count
index
,
ElementCount
elementCount
,
ListBuilder
initStructListElement
(
Element
Count
index
,
ElementCount
elementCount
,
StructSize
size
)
const
;
StructSize
size
)
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 to its empty state.
// 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
// Get the existing list element at the given index. Returns an empty list if the element is
// not initialized.
// 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
// 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.
// 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.
// 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.
// Get the text element. If it is not initialized, returns an empty Text::Builder.
Data
::
Builder
initDataElement
(
WireReference
Count
index
,
ByteCount
size
)
const
;
Data
::
Builder
initDataElement
(
Element
Count
index
,
ByteCount
size
)
const
;
void
setDataElement
(
WireReference
Count
index
,
Data
::
Reader
value
)
const
;
void
setDataElement
(
Element
Count
index
,
Data
::
Reader
value
)
const
;
Data
::
Builder
getDataElement
(
WireReference
Count
index
)
const
;
Data
::
Builder
getDataElement
(
Element
Count
index
)
const
;
ListReader
asReader
(
FieldSize
elementSize
)
const
;
ListReader
asReader
(
FieldSize
elementSize
)
const
;
// Get a ListReader pointing at the same memory. Use this version only for non-struct lists.
// 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.
// Get a ListReader pointing at the same memory. Use this version only for struct lists.
private
:
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the list resides.
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.
ElementCount
elementCount
;
// Number of elements in the list.
inline
ListBuilder
(
SegmentBuilder
*
segment
,
word
*
ptr
,
ElementCount
size
)
decltype
(
BITS
/
ELEMENTS
)
stepBits
;
:
segment
(
segment
),
ptr
(
ptr
),
elementCount
(
size
)
{}
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
class
StructBuilder
;
friend
struct
WireHelpers
;
friend
struct
WireHelpers
;
...
@@ -493,9 +557,9 @@ private:
...
@@ -493,9 +557,9 @@ private:
class
ListReader
{
class
ListReader
{
public
:
public
:
inline
ListReader
()
inline
ListReader
()
:
segment
(
nullptr
),
ptr
(
nullptr
),
elementCount
(
0
),
:
segment
(
nullptr
),
data
(
nullptr
),
pointers
(
nullptr
),
elementCount
(
0
),
stepBits
(
0
*
BITS
/
ELEMENTS
),
st
ructDataSize
(
0
),
stepBits
(
0
*
BITS
/
ELEMENTS
),
st
epPointers
(
0
*
REFERENCES
/
ELEMENTS
),
structReferenceCount
(
0
),
nestingLimit
(
0
)
{}
struct
DataSize
(
0
),
struct
ReferenceCount
(
0
),
nestingLimit
(
0
)
{}
inline
ElementCount
size
();
inline
ElementCount
size
();
// The number of elements in the list.
// The number of elements in the list.
...
@@ -507,50 +571,49 @@ public:
...
@@ -507,50 +571,49 @@ public:
StructReader
getStructElement
(
ElementCount
index
)
const
;
StructReader
getStructElement
(
ElementCount
index
)
const
;
// Get the struct element at the given index.
// 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.
// 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.
// 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.
// Get the data element. If it is not initialized, returns an empty Data::Reader.
private
:
private
:
SegmentReader
*
segment
;
// Memory segment in which the list resides.
SegmentReader
*
segment
;
// Memory segment in which the list resides.
const
void
*
ptr
;
const
void
*
data
;
// Pointer to the data. If null, use defaultReferences. (Never null for data lists.)
const
WireReference
*
pointers
;
//
Must be aligned appropriately for the elements
.
//
Pointers to list content
.
ElementCount
elementCount
;
// Number of elements in the list.
ElementCount
elementCount
;
// Number of elements in the list.
decltype
(
BITS
/
ELEMENTS
)
stepBits
;
decltype
(
BITS
/
ELEMENTS
)
stepBits
;
// The distance between elements, in bits. This is usually the element size, but can be larger
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
;
// if the sender upgraded a data list to a struct list. It will always be aligned properly for
// The distance between elements. Can be tricky e.g. for inlined struct lists.
// the type. Unsigned so that division by a constant power of 2 is efficient.
BitCount
structDataSize
;
BitCount
structDataSize
;
WireReferenceCount
structReferenceCount
;
WireReferenceCount
structReferenceCount
;
// If the elements are structs, the properties of the struct. The reference count is
// If the elements are structs, the properties of the struct.
// only used to check for field presence; the data size is also used to compute the reference
// pointer.
int
nestingLimit
;
int
nestingLimit
;
// Limits the depth of message structures to guard against stack-overflow-based DoS attacks.
// Limits the depth of message structures to guard against stack-overflow-based DoS attacks.
// Once this reaches zero, further pointers will be pruned.
// Once this reaches zero, further pointers will be pruned.
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
ptr
,
ElementCount
elementCount
,
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
data
,
const
WireReference
*
pointers
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
int
nestingLimit
)
ElementCount
elementCount
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
:
segment
(
segment
),
ptr
(
ptr
),
elementCount
(
elementCount
),
stepBits
(
stepBits
),
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
int
nestingLimit
)
structDataSize
(
0
),
structReferenceCount
(
0
),
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
elementCount
),
stepBits
(
stepBits
),
stepPointers
(
stepPointers
),
structDataSize
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
nestingLimit
)
{}
nestingLimit
(
nestingLimit
)
{}
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
ptr
,
ElementCount
elementCount
,
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
data
,
const
WireReference
*
pointers
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
BitCount
structDataSize
,
ElementCount
elementCount
,
decltype
(
BITS
/
ELEMENTS
)
stepBits
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
BitCount
structDataSize
,
WireReferenceCount
structReferenceCount
,
int
nestingLimit
)
WireReferenceCount
structReferenceCount
,
int
nestingLimit
)
:
segment
(
segment
),
ptr
(
ptr
),
elementCount
(
elementCount
),
stepBits
(
stepBits
),
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
elementCount
),
st
ructDataSize
(
structDataSize
),
structReferenceCount
(
structReferenceCount
),
st
epBits
(
stepBits
),
stepPointers
(
stepPointers
),
structDataSize
(
structDataSize
),
nestingLimit
(
nestingLimit
)
{}
structReferenceCount
(
structReferenceCount
),
nestingLimit
(
nestingLimit
)
{}
friend
class
StructReader
;
friend
class
StructReader
;
friend
class
ListBuilder
;
friend
class
ListBuilder
;
...
@@ -637,14 +700,68 @@ inline StructBuilder StructBuilder::getInlineStructField(
...
@@ -637,14 +700,68 @@ inline StructBuilder StructBuilder::getInlineStructField(
// WireReference is incomplete here so we have to cast around... Bah.
// WireReference is incomplete here so we have to cast around... Bah.
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
word
*>
(
references
)
+
refIndex
*
WORDS_PER_REFERENCE
),
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
>
template
<
typename
T
>
T
StructReader
::
getDataField
(
ElementCount
offset
)
const
{
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
();
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
data
)[
offset
/
ELEMENTS
].
get
();
}
else
{
}
else
{
return
static_cast
<
T
>
(
0
);
return
static_cast
<
T
>
(
0
);
...
@@ -689,19 +806,49 @@ inline StructReader StructReader::getInlineStructField(
...
@@ -689,19 +806,49 @@ inline StructReader StructReader::getInlineStructField(
nestingLimit
);
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
;
}
inline
ElementCount
ListBuilder
::
size
()
{
return
elementCount
;
}
template
<
typename
T
>
template
<
typename
T
>
inline
T
ListBuilder
::
getDataElement
(
ElementCount
index
)
const
{
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
<>
template
<>
inline
bool
ListBuilder
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
inline
bool
ListBuilder
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
)
;
BitCount
bindex
=
index
*
stepBits
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
ptr
)
+
bindex
/
BITS_PER_BYTE
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
(
1
<<
(
bindex
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
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 {
...
@@ -712,13 +859,14 @@ inline Void ListBuilder::getDataElement<Void>(ElementCount index) const {
template
<
typename
T
>
template
<
typename
T
>
inline
void
ListBuilder
::
setDataElement
(
ElementCount
index
,
typename
NoInfer
<
T
>::
Type
value
)
const
{
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
<>
template
<>
inline
void
ListBuilder
::
setDataElement
<
bool
>
(
ElementCount
index
,
bool
value
)
const
{
inline
void
ListBuilder
::
setDataElement
<
bool
>
(
ElementCount
index
,
bool
value
)
const
{
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
)
;
BitCount
bindex
=
index
*
stepBits
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
ptr
)
+
bindex
/
BITS_PER_BYTE
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
uint
bitnum
=
bindex
%
BITS_PER_BYTE
/
BITS
;
uint
bitnum
=
bindex
%
BITS_PER_BYTE
/
BITS
;
*
reinterpret_cast
<
uint8_t
*>
(
b
)
=
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
~
(
1
<<
bitnum
))
*
reinterpret_cast
<
uint8_t
*>
(
b
)
=
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
~
(
1
<<
bitnum
))
|
(
static_cast
<
uint8_t
>
(
value
)
<<
bitnum
);
|
(
static_cast
<
uint8_t
>
(
value
)
<<
bitnum
);
...
@@ -733,14 +881,14 @@ inline ElementCount ListReader::size() { return elementCount; }
...
@@ -733,14 +881,14 @@ inline ElementCount ListReader::size() { return elementCount; }
template
<
typename
T
>
template
<
typename
T
>
inline
T
ListReader
::
getDataElement
(
ElementCount
index
)
const
{
inline
T
ListReader
::
getDataElement
(
ElementCount
index
)
const
{
return
*
reinterpret_cast
<
const
T
*>
(
return
reinterpret_cast
<
const
WireValue
<
T
>
*>
(
reinterpret_cast
<
const
byte
*>
(
ptr
)
+
index
*
stepBits
/
BITS_PER_BYTE
);
reinterpret_cast
<
const
byte
*>
(
data
)
+
index
*
stepBits
/
BITS_PER_BYTE
)
->
get
(
);
}
}
template
<>
template
<>
inline
bool
ListReader
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
inline
bool
ListReader
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
BitCount
bindex
=
index
*
stepBits
;
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
;
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> {
...
@@ -236,8 +236,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
::
STRUCT_SIZE
));
T
::
STRUCT_SIZE
.
total
()
/
ELEMENTS
,
T
::
STRUCT_SIZE
.
data
));
}
}
typedef
internal
::
IndexingIterator
<
Builder
,
typename
T
::
Builder
>
iterator
;
typedef
internal
::
IndexingIterator
<
Builder
,
typename
T
::
Builder
>
iterator
;
...
@@ -282,11 +281,11 @@ struct List<List<T>, true> {
...
@@ -282,11 +281,11 @@ struct List<List<T>, true> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
List
<
T
>::
Builder
operator
[](
uint
index
)
{
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
)
{
inline
typename
List
<
T
>::
Builder
init
(
uint
index
,
uint
size
)
{
return
typename
List
<
T
>::
Builder
(
builder
.
initListElement
(
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
;
typedef
internal
::
IndexingIterator
<
Builder
,
typename
List
<
T
>::
Builder
>
iterator
;
...
@@ -312,7 +311,7 @@ struct List<List<T>, false> {
...
@@ -312,7 +311,7 @@ struct List<List<T>, false> {
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
typename
List
<
T
>::
Reader
operator
[](
uint
index
)
{
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
));
internal
::
FieldSizeForType
<
T
>::
value
));
}
}
...
@@ -331,11 +330,11 @@ struct List<List<T>, false> {
...
@@ -331,11 +330,11 @@ struct List<List<T>, false> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
List
<
T
>::
Builder
operator
[](
uint
index
)
{
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
)
{
inline
typename
List
<
T
>::
Builder
init
(
uint
index
,
uint
size
)
{
return
typename
List
<
T
>::
Builder
(
builder
.
initStructListElement
(
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
;
typedef
internal
::
IndexingIterator
<
Builder
,
typename
List
<
T
>::
Builder
>
iterator
;
...
@@ -361,7 +360,7 @@ struct List<Data, false> {
...
@@ -361,7 +360,7 @@ struct List<Data, false> {
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
Data
::
Reader
operator
[](
uint
index
)
{
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
;
typedef
internal
::
IndexingIterator
<
Reader
,
Data
::
Reader
>
iterator
;
...
@@ -379,13 +378,13 @@ struct List<Data, false> {
...
@@ -379,13 +378,13 @@ struct List<Data, false> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
Data
::
Builder
operator
[](
uint
index
)
{
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
)
{
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
)
{
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
;
typedef
internal
::
IndexingIterator
<
Builder
,
Data
::
Builder
>
iterator
;
...
@@ -425,7 +424,7 @@ struct List<Text, false> {
...
@@ -425,7 +424,7 @@ struct List<Text, false> {
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
Text
::
Reader
operator
[](
uint
index
)
{
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
;
typedef
internal
::
IndexingIterator
<
Reader
,
Text
::
Reader
>
iterator
;
...
@@ -443,13 +442,13 @@ struct List<Text, false> {
...
@@ -443,13 +442,13 @@ struct List<Text, false> {
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
Text
::
Builder
operator
[](
uint
index
)
{
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
)
{
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
)
{
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
;
typedef
internal
::
IndexingIterator
<
Builder
,
Text
::
Builder
>
iterator
;
...
...
c++/src/capnproto/test.capnp
View file @
eab15190
...
@@ -276,7 +276,7 @@ struct TestUsing {
...
@@ -276,7 +276,7 @@ struct TestUsing {
innerNestedEnum @0 :NestedEnum = quux;
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 TestInline1 fixed(1 bits) { f @0: Bool; }
struct TestInline8 fixed(8 bits) { f0 @0: Bool; f1 @1: Bool; f2 @2: 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; }
struct TestInline16 fixed(16 bits) { f0 @0: UInt8; f1 @1: UInt8; }
...
@@ -384,9 +384,37 @@ struct TestInlineUnions {
...
@@ -384,9 +384,37 @@ struct TestInlineUnions {
byte0 @39: UInt8;
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 {
struct TestInlineDefaults {
normal @0 :TestInlineLayout = (
normal @0 :TestInlineLayout = (
f0 = (),
f0 = (
f = void
),
f1 = (f = true),
f1 = (f = true),
f8 = (f0 = true, f1 = false, f2 = true),
f8 = (f0 = true, f1 = false, f2 = true),
f16 = (f0 = 123, f1 = 45),
f16 = (f0 = 123, f1 = 45),
...
@@ -411,4 +439,52 @@ struct TestInlineDefaults {
...
@@ -411,4 +439,52 @@ struct TestInlineDefaults {
union1 = f128(f0 = 1234567890123, f1 = 4567890123456),
union1 = f128(f0 = 1234567890123, f1 = 4567890123456),
union2 = f1p(p0 = "foo"),
union2 = f1p(p0 = "foo"),
union3 = f16p(f = (f0 = 98, f1 = 76), p0 = "qux", p1 = "quux"));
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:
...
@@ -326,6 +326,21 @@ public:
unit1PerUnit2
*
other
.
unit1PerUnit2
);
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
:
private
:
Number
unit1PerUnit2
;
Number
unit1PerUnit2
;
...
...
compiler/src/Compiler.hs
View file @
eab15190
...
@@ -295,7 +295,13 @@ compileType scope (TypeExpression n params) = do
...
@@ -295,7 +295,13 @@ compileType scope (TypeExpression n params) = do
desc
<-
lookupDesc
scope
n
desc
<-
lookupDesc
scope
n
case
desc
of
case
desc
of
DescBuiltinList
->
case
params
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."
_
->
makeError
(
declNamePos
n
)
"'List' requires exactly one type parameter."
DescBuiltinInline
->
case
params
of
DescBuiltinInline
->
case
params
of
[
TypeParameterType
param
]
->
do
[
TypeParameterType
param
]
->
do
...
@@ -311,7 +317,18 @@ compileType scope (TypeExpression n params) = do
...
@@ -311,7 +317,18 @@ compileType scope (TypeExpression n params) = do
DescBuiltinInlineList
->
case
params
of
DescBuiltinInlineList
->
case
params
of
[
TypeParameterType
param
,
TypeParameterInteger
size
]
->
do
[
TypeParameterType
param
,
TypeParameterInteger
size
]
->
do
inner
<-
compileType
scope
param
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
)
_
->
makeError
(
declNamePos
n
)
"'InlineList' requires exactly two type parameters: a type and a size."
"'InlineList' requires exactly two type parameters: a type and a size."
_
->
case
params
of
_
->
case
params
of
...
...
compiler/src/CxxGenerator.hs
View file @
eab15190
...
@@ -105,17 +105,24 @@ isInlineStruct (InlineStructType _) = True
...
@@ -105,17 +105,24 @@ isInlineStruct (InlineStructType _) = True
isInlineStruct
_
=
False
isInlineStruct
_
=
False
isList
(
ListType
_
)
=
True
isList
(
ListType
_
)
=
True
isList
(
InlineListType
_
_
)
=
True
isList
_
=
False
isList
_
=
False
isNonStructList
(
ListType
t
)
=
not
$
isStruct
t
isNonStructList
(
ListType
t
)
=
not
$
isStruct
t
isNonStructList
(
InlineListType
t
_
)
=
not
$
isStruct
t
isNonStructList
_
=
False
isNonStructList
_
=
False
isPrimitiveList
(
ListType
t
)
=
isPrimitive
t
isPrimitiveList
(
ListType
t
)
=
isPrimitive
t
isPrimitiveList
(
InlineListType
t
_
)
=
isPrimitive
t
isPrimitiveList
_
=
False
isPrimitiveList
_
=
False
isStructList
(
ListType
t
)
=
isStruct
t
isStructList
(
ListType
t
)
=
isStruct
t
isStructList
(
InlineListType
t
_
)
=
isStruct
t
isStructList
_
=
False
isStructList
_
=
False
isInlineList
(
InlineListType
_
_
)
=
True
isInlineList
_
=
False
blobTypeString
(
BuiltinType
BuiltinText
)
=
"Text"
blobTypeString
(
BuiltinType
BuiltinText
)
=
"Text"
blobTypeString
(
BuiltinType
BuiltinData
)
=
"Data"
blobTypeString
(
BuiltinType
BuiltinData
)
=
"Data"
blobTypeString
_
=
error
"Not a blob."
blobTypeString
_
=
error
"Not a blob."
...
@@ -139,6 +146,7 @@ cxxTypeString (StructType desc) = globalName $ DescStruct desc
...
@@ -139,6 +146,7 @@ cxxTypeString (StructType desc) = globalName $ DescStruct desc
cxxTypeString
(
InlineStructType
desc
)
=
globalName
$
DescStruct
desc
cxxTypeString
(
InlineStructType
desc
)
=
globalName
$
DescStruct
desc
cxxTypeString
(
InterfaceType
desc
)
=
globalName
$
DescInterface
desc
cxxTypeString
(
InterfaceType
desc
)
=
globalName
$
DescInterface
desc
cxxTypeString
(
ListType
t
)
=
concat
[
" ::capnproto::List<"
,
cxxTypeString
t
,
">"
]
cxxTypeString
(
ListType
t
)
=
concat
[
" ::capnproto::List<"
,
cxxTypeString
t
,
">"
]
cxxTypeString
(
InlineListType
t
_
)
=
concat
[
" ::capnproto::List<"
,
cxxTypeString
t
,
">"
]
cxxFieldSizeString
SizeVoid
=
"VOID"
;
cxxFieldSizeString
SizeVoid
=
"VOID"
;
cxxFieldSizeString
(
SizeData
Size1
)
=
"BIT"
;
cxxFieldSizeString
(
SizeData
Size1
)
=
"BIT"
;
...
@@ -203,6 +211,7 @@ defaultValueBytes t v@(ListDesc _) = Just $ encodeMessage t v
...
@@ -203,6 +211,7 @@ defaultValueBytes t v@(ListDesc _) = Just $ encodeMessage t v
defaultValueBytes
_
_
=
Nothing
defaultValueBytes
_
_
=
Nothing
elementType
(
ListType
t
)
=
t
elementType
(
ListType
t
)
=
t
elementType
(
InlineListType
t
_
)
=
t
elementType
_
=
error
"Called elementType on non-list."
elementType
_
=
error
"Called elementType on non-list."
repeatedlyTake
_
[]
=
[]
repeatedlyTake
_
[]
=
[]
...
@@ -244,6 +253,7 @@ fieldContext parent desc = mkStrContext context where
...
@@ -244,6 +253,7 @@ fieldContext parent desc = mkStrContext context where
context
"fieldIsNonStructList"
=
MuBool
$
isNonStructList
$
fieldType
desc
context
"fieldIsNonStructList"
=
MuBool
$
isNonStructList
$
fieldType
desc
context
"fieldIsPrimitiveList"
=
MuBool
$
isPrimitiveList
$
fieldType
desc
context
"fieldIsPrimitiveList"
=
MuBool
$
isPrimitiveList
$
fieldType
desc
context
"fieldIsStructList"
=
MuBool
$
isStructList
$
fieldType
desc
context
"fieldIsStructList"
=
MuBool
$
isStructList
$
fieldType
desc
context
"fieldIsInlineList"
=
MuBool
$
isInlineList
$
fieldType
desc
context
"fieldDefaultBytes"
=
context
"fieldDefaultBytes"
=
case
fieldDefaultValue
desc
>>=
defaultValueBytes
(
fieldType
desc
)
of
case
fieldDefaultValue
desc
>>=
defaultValueBytes
(
fieldType
desc
)
of
Just
v
->
muJust
$
defaultBytesContext
context
(
fieldType
desc
)
v
Just
v
->
muJust
$
defaultBytesContext
context
(
fieldType
desc
)
v
...
@@ -251,6 +261,23 @@ fieldContext parent desc = mkStrContext context where
...
@@ -251,6 +261,23 @@ 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
$
fieldOffsetInteger
$
fieldOffset
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
context
"fieldDefaultMask"
=
case
fieldDefaultValue
desc
of
Nothing
->
MuVariable
""
Nothing
->
MuVariable
""
Just
v
->
MuVariable
(
if
isDefaultZero
v
then
""
else
", "
++
defaultMask
v
)
Just
v
->
MuVariable
(
if
isDefaultZero
v
then
""
else
", "
++
defaultMask
v
)
...
@@ -303,6 +330,7 @@ structContext parent desc = mkStrContext context where
...
@@ -303,6 +330,7 @@ structContext parent desc = mkStrContext context where
context
"structFields"
=
MuList
$
map
(
fieldContext
context
)
$
structFields
desc
context
"structFields"
=
MuList
$
map
(
fieldContext
context
)
$
structFields
desc
context
"structUnions"
=
MuList
$
map
(
unionContext
context
)
$
structUnions
desc
context
"structUnions"
=
MuList
$
map
(
unionContext
context
)
$
structUnions
desc
context
"structDataSize"
=
MuVariable
$
dataSectionWordSize
$
structDataSize
desc
context
"structDataSize"
=
MuVariable
$
dataSectionWordSize
$
structDataSize
desc
context
"structDataBits"
=
MuVariable
$
dataSectionBits
$
structDataSize
desc
context
"structReferenceCount"
=
MuVariable
$
structPointerCount
desc
context
"structReferenceCount"
=
MuVariable
$
structPointerCount
desc
context
"structNestedEnums"
=
context
"structNestedEnums"
=
MuList
$
map
(
enumContext
context
)
[
m
|
DescEnum
m
<-
structMembers
desc
]
MuList
$
map
(
enumContext
context
)
[
m
|
DescEnum
m
<-
structMembers
desc
]
...
...
compiler/src/Semantics.hs
View file @
eab15190
...
@@ -320,6 +320,7 @@ fieldSize (InterfaceType _) = SizeReference
...
@@ -320,6 +320,7 @@ fieldSize (InterfaceType _) = SizeReference
fieldSize
(
ListType
_
)
=
SizeReference
fieldSize
(
ListType
_
)
=
SizeReference
fieldSize
(
InlineListType
element
size
)
=
let
fieldSize
(
InlineListType
element
size
)
=
let
minDataSectionForBits
bits
minDataSectionForBits
bits
|
bits
<=
0
=
DataSectionWords
0
|
bits
<=
1
=
DataSection1
|
bits
<=
1
=
DataSection1
|
bits
<=
8
=
DataSection8
|
bits
<=
8
=
DataSection8
|
bits
<=
16
=
DataSection16
|
bits
<=
16
=
DataSection16
...
@@ -329,12 +330,12 @@ fieldSize (InlineListType element size) = let
...
@@ -329,12 +330,12 @@ fieldSize (InlineListType element size) = let
SizeVoid
->
DataSectionWords
0
SizeVoid
->
DataSectionWords
0
SizeData
s
->
minDataSectionForBits
$
dataSizeInBits
s
*
size
SizeData
s
->
minDataSectionForBits
$
dataSizeInBits
s
*
size
SizeReference
->
DataSectionWords
0
SizeReference
->
DataSectionWords
0
SizeInlineComposite
ds
_
->
minDataSectionForBits
$
dataSectionBits
ds
SizeInlineComposite
ds
_
->
minDataSectionForBits
$
dataSectionBits
ds
*
size
pointerCount
=
case
fieldSize
element
of
pointerCount
=
case
fieldSize
element
of
SizeVoid
->
0
SizeVoid
->
0
SizeData
_
->
0
SizeData
_
->
0
SizeReference
->
size
SizeReference
->
size
SizeInlineComposite
_
pc
->
pc
SizeInlineComposite
_
pc
->
pc
*
size
in
SizeInlineComposite
dataSection
pointerCount
in
SizeInlineComposite
dataSection
pointerCount
-- Render the type descriptor's name as a string, appropriate for use in the given scope.
-- 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)
...
@@ -29,6 +29,7 @@ import Data.Bits(shiftL, shiftR, Bits, setBit, xor)
import
Data.Function
(
on
)
import
Data.Function
(
on
)
import
Semantics
import
Semantics
import
Data.Binary.IEEE754
(
floatToWord
,
doubleToWord
)
import
Data.Binary.IEEE754
(
floatToWord
,
doubleToWord
)
import
Text.Printf
(
printf
)
import
qualified
Codec.Binary.UTF8.String
as
UTF8
import
qualified
Codec.Binary.UTF8.String
as
UTF8
byte
::
(
Integral
a
,
Bits
a
)
=>
a
->
Int
->
Word8
byte
::
(
Integral
a
,
Bits
a
)
=>
a
->
Int
->
Word8
...
@@ -45,6 +46,7 @@ padToWord b = let
...
@@ -45,6 +46,7 @@ padToWord b = let
data
EncodedData
=
EncodedBit
Bool
data
EncodedData
=
EncodedBit
Bool
|
EncodedBytes
[
Word8
]
|
EncodedBytes
[
Word8
]
deriving
(
Show
)
xorData
(
EncodedBit
a
)
(
EncodedBit
b
)
=
EncodedBit
(
a
/=
b
)
xorData
(
EncodedBit
a
)
(
EncodedBit
b
)
=
EncodedBit
(
a
/=
b
)
xorData
(
EncodedBytes
a
)
(
EncodedBytes
b
)
=
EncodedBytes
(
zipWith
xor
a
b
)
xorData
(
EncodedBytes
a
)
(
EncodedBytes
b
)
=
EncodedBytes
(
zipWith
xor
a
b
)
...
@@ -92,7 +94,7 @@ encodePointerValue _ _ = error "Unknown pointer type."
...
@@ -92,7 +94,7 @@ encodePointerValue _ _ = error "Unknown pointer type."
packBytes
::
Integer
-- Total size of array to pack, in bits.
packBytes
::
Integer
-- Total size of array to pack, in bits.
->
[(
Integer
,
EncodedData
)]
-- (offset, data) pairs to pack. Must be in order.
->
[(
Integer
,
EncodedData
)]
-- (offset, data) pairs to pack. Must be in order.
->
[
Word8
]
->
[
Word8
]
packBytes
size
=
padToWord
.
loop
0
where
packBytes
size
items
=
padToWord
$
loop
0
items
where
loop
::
Integer
->
[(
Integer
,
EncodedData
)]
->
[
Word8
]
loop
::
Integer
->
[(
Integer
,
EncodedData
)]
->
[
Word8
]
loop
bit
[]
|
bit
<=
size
=
genericReplicate
(
div
(
size
-
bit
+
7
)
8
)
0
loop
bit
[]
|
bit
<=
size
=
genericReplicate
(
div
(
size
-
bit
+
7
)
8
)
0
loop
bit
[]
|
bit
>
size
=
error
"Data values overran size."
loop
bit
[]
|
bit
>
size
=
error
"Data values overran size."
...
@@ -103,7 +105,8 @@ packBytes size = padToWord . loop 0 where
...
@@ -103,7 +105,8 @@ packBytes size = padToWord . loop 0 where
loop
bit
((
_
,
EncodedBit
False
)
:
rest
)
=
loop
bit
rest
loop
bit
((
_
,
EncodedBit
False
)
:
rest
)
=
loop
bit
rest
loop
bit
((
offset
,
EncodedBytes
encoded
)
:
rest
)
|
offset
==
bit
=
loop
bit
((
offset
,
EncodedBytes
encoded
)
:
rest
)
|
offset
==
bit
=
encoded
++
loop
(
bit
+
genericLength
encoded
*
8
)
rest
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
bytesToWords
i
=
if
mod
i
8
==
0
then
div
i
8
else
error
"Byte count did not divide evenly into words."
else
error
"Byte count did not divide evenly into words."
...
...
compiler/src/c++-header.mustache
View file @
eab15190
...
@@ -69,7 +69,8 @@ struct {{typeFullName}} {
...
@@ -69,7 +69,8 @@ struct {{typeFullName}} {
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
::capnproto::internal::StructSize(
{{
structDataSize
}}
* ::capnproto::WORDS,
::capnproto::internal::StructSize(
{{
structDataSize
}}
* ::capnproto::WORDS,
{{
structReferenceCount
}}
* ::capnproto::REFERENCES);
{{
structReferenceCount
}}
* ::capnproto::REFERENCES,
{{
structDataBits
}}
* ::capnproto::BITS);
{{/
typeStruct
}}
{{/
typeStruct
}}
{{#
typeUnion
}}
{{#
typeUnion
}}
...
@@ -172,7 +173,12 @@ public:
...
@@ -172,7 +173,12 @@ public:
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
{{/
fieldIsStruct
}}
{{/
fieldIsStruct
}}
{{#
fieldIsNonStructList
}}
{{#
fieldIsNonStructList
}}
{{#
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
();
{{/
fieldIsInlineList
}}
{{^
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
(unsigned int size);
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
(unsigned int size);
{{/
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
template
<typename
_t
>
template
<typename
_t
>
inline void set
{{
fieldTitleCase
}}
(const _t
&
other);
inline void set
{{
fieldTitleCase
}}
(const _t
&
other);
...
@@ -184,7 +190,12 @@ public:
...
@@ -184,7 +190,12 @@ public:
{{/
fieldIsPrimitiveList
}}
{{/
fieldIsPrimitiveList
}}
{{/
fieldIsNonStructList
}}
{{/
fieldIsNonStructList
}}
{{#
fieldIsStructList
}}
{{#
fieldIsStructList
}}
{{#
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
();
{{/
fieldIsInlineList
}}
{{^
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
(unsigned int size);
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
(unsigned int size);
{{/
fieldIsInlineList
}}
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
{{/
fieldIsStructList
}}
{{/
fieldIsStructList
}}
{{/
typeFields
}}
{{/
typeFields
}}
...
@@ -356,6 +367,75 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
...
@@ -356,6 +367,75 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{/
fieldIsStruct
}}
{{/
fieldIsStruct
}}
{{! ------------------------------------------------------------------------------------------- }}
{{! ------------------------------------------------------------------------------------------- }}
{{#
fieldIsNonStructList
}}
{{#
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
}}
() {
inline
{{
fieldType
}}
::Reader
{{
typeFullName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
...
@@ -388,15 +468,17 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
...
@@ -388,15 +468,17 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}
nullptr
{{/
fieldDefaultBytes
}}
));
{{^
fieldDefaultBytes
}}
nullptr
{{/
fieldDefaultBytes
}}
));
}
}
{{/
fieldIsInlineList
}}
{{! --------------------------------- }}
template
<typename
_t
>
template
<typename
_t
>
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(const _t
&
other) {
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(const _t
&
other) {
{{#
fieldUnion
}}
{{#
fieldUnion
}}
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
{{/
fieldUnion
}}
init
{{
fieldTitleCase
}}
(
other.size()
).copyFrom(other);
init
{{
fieldTitleCase
}}
(
{{^
fieldIsInlineList
}}
other.size()
{{/
fieldIsInlineList
}}
).copyFrom(other);
}
}
{{! ------------------------------------------------------------------------------------------- }}
{{#
fieldIsPrimitiveList
}}
{{#
fieldIsPrimitiveList
}}
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(
std::initializer_list
<
{{
fieldElementType
}}
>
other) {
std::initializer_list
<
{{
fieldElementType
}}
>
other) {
...
@@ -404,10 +486,9 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
...
@@ -404,10 +486,9 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
{{/
fieldUnion
}}
init
{{
fieldTitleCase
}}
(
other.size()
).copyFrom(other);
init
{{
fieldTitleCase
}}
(
{{^
fieldIsInlineList
}}
other.size()
{{/
fieldIsInlineList
}}
).copyFrom(other);
}
}
{{/
fieldIsPrimitiveList
}}
{{/
fieldIsPrimitiveList
}}
{{! ------------------------------------------------------------------------------------------- }}
{{^
fieldIsPrimitiveList
}}
{{^
fieldIsPrimitiveList
}}
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(
inline void
{{
typeFullName
}}
::Builder::set
{{
fieldTitleCase
}}
(
std::initializer_list
<
{{
fieldElementType
}}
::Reader>
other) {
std::initializer_list
<
{{
fieldElementType
}}
::Reader>
other) {
...
@@ -415,12 +496,49 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
...
@@ -415,12 +496,49 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
{{/
fieldUnion
}}
init
{{
fieldTitleCase
}}
(
other.size()
).copyFrom(other);
init
{{
fieldTitleCase
}}
(
{{^
fieldIsInlineList
}}
other.size()
{{/
fieldIsInlineList
}}
).copyFrom(other);
}
}
{{/
fieldIsPrimitiveList
}}
{{/
fieldIsPrimitiveList
}}
{{/
fieldIsNonStructList
}}
{{/
fieldIsNonStructList
}}
{{! ------------------------------------------------------------------------------------------- }}
{{! ------------------------------------------------------------------------------------------- }}
{{#
fieldIsStructList
}}
{{#
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
}}
() {
inline
{{
fieldType
}}
::Reader
{{
typeFullName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
{{#
fieldUnion
}}
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
...
@@ -452,6 +570,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
...
@@ -452,6 +570,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}
nullptr
{{/
fieldDefaultBytes
}}
));
{{^
fieldDefaultBytes
}}
nullptr
{{/
fieldDefaultBytes
}}
));
}
}
{{/
fieldIsInlineList
}}
{{/
fieldIsStructList
}}
{{/
fieldIsStructList
}}
{{/
typeFields
}}
{{/
typeFields
}}
{{/
typeStructOrUnion
}}
{{/
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