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
de33baaf
Commit
de33baaf
authored
May 06, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify more after removing inline types.
parent
7197456b
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
142 additions
and
167 deletions
+142
-167
layout-test.c++
c++/src/capnproto/layout-test.c++
+12
-8
layout.c++
c++/src/capnproto/layout.c++
+68
-73
layout.h
c++/src/capnproto/layout.h
+40
-82
type-safety.h
c++/src/capnproto/type-safety.h
+9
-0
CxxGenerator.hs
compiler/src/CxxGenerator.hs
+9
-1
c++-header.mustache
compiler/src/c++-header.mustache
+4
-3
No files found.
c++/src/capnproto/layout-test.c++
View file @
de33baaf
...
@@ -102,7 +102,8 @@ static const AlignedData<2> SUBSTRUCT_DEFAULT = {{0,0,0,0,1,0,0,0, 0,0,0,0,0,0,
...
@@ -102,7 +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
,
8
*
BYTES
);
static
constexpr
StructSize
STRUCTLIST_ELEMENT_SIZE
(
1
*
WORDS
,
1
*
REFERENCES
,
FieldSize
::
INLINE_COMPOSITE
);
static
void
setupStruct
(
StructBuilder
builder
)
{
static
void
setupStruct
(
StructBuilder
builder
)
{
builder
.
setDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
0x1011121314151617ull
);
builder
.
setDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
0x1011121314151617ull
);
...
@@ -120,7 +121,7 @@ static void setupStruct(StructBuilder builder) {
...
@@ -120,7 +121,7 @@ static void setupStruct(StructBuilder builder) {
{
{
StructBuilder
subStruct
=
builder
.
initStructField
(
StructBuilder
subStruct
=
builder
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
8
*
BYTES
));
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
FieldSize
::
EIGHT_
BYTES
));
subStruct
.
setDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
123
);
subStruct
.
setDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
123
);
}
}
...
@@ -139,7 +140,8 @@ static void setupStruct(StructBuilder builder) {
...
@@ -139,7 +140,8 @@ static void setupStruct(StructBuilder builder) {
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
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
,
8
*
BYTES
))
element
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
FieldSize
::
EIGHT_BYTES
))
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
400
+
i
);
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
400
+
i
);
}
}
}
}
...
@@ -174,7 +176,8 @@ static void checkStruct(StructBuilder builder) {
...
@@ -174,7 +176,8 @@ static void checkStruct(StructBuilder builder) {
{
{
StructBuilder
subStruct
=
builder
.
getStructField
(
StructBuilder
subStruct
=
builder
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
8
*
BYTES
),
SUBSTRUCT_DEFAULT
.
words
);
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
FieldSize
::
EIGHT_BYTES
),
SUBSTRUCT_DEFAULT
.
words
);
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
}
}
...
@@ -193,7 +196,8 @@ static void checkStruct(StructBuilder builder) {
...
@@ -193,7 +196,8 @@ static void checkStruct(StructBuilder builder) {
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
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
,
8
*
BYTES
),
element
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
FieldSize
::
EIGHT_BYTES
),
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
}
}
...
@@ -272,7 +276,7 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
...
@@ -272,7 +276,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
,
16
*
BYTES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
FieldSize
::
INLINE_COMPOSITE
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// word count:
// word count:
...
@@ -308,7 +312,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
...
@@ -308,7 +312,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
,
16
*
BYTES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
FieldSize
::
INLINE_COMPOSITE
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// Verify that we made 15 segments.
// Verify that we made 15 segments.
...
@@ -345,7 +349,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
...
@@ -345,7 +349,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
,
16
*
BYTES
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
FieldSize
::
INLINE_COMPOSITE
));
setupStruct
(
builder
);
setupStruct
(
builder
);
// Verify that we made 6 segments.
// Verify that we made 6 segments.
...
...
c++/src/capnproto/layout.c++
View file @
de33baaf
...
@@ -418,8 +418,7 @@ struct WireHelpers {
...
@@ -418,8 +418,7 @@ 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
),
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
));
size
.
pointers
);
}
}
static
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
getWritableStructReference
(
static
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
getWritableStructReference
(
...
@@ -446,8 +445,7 @@ struct WireHelpers {
...
@@ -446,8 +445,7 @@ 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
),
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
));
size
.
pointers
);
}
}
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initListReference
(
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initListReference
(
...
@@ -456,6 +454,8 @@ struct WireHelpers {
...
@@ -456,6 +454,8 @@ struct WireHelpers {
DPRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
DPRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
"Should have called initStructListReference() instead."
);
"Should have called initStructListReference() instead."
);
// Note: Use bitsPerElement(), not bytesPerElement(), to handle bit lists correctly when
// computing wordCount. After that, the step is not used for bit lists.
auto
step
=
bitsPerElement
(
elementSize
);
auto
step
=
bitsPerElement
(
elementSize
);
// Calculate size of the list.
// Calculate size of the list.
...
@@ -468,30 +468,18 @@ struct WireHelpers {
...
@@ -468,30 +468,18 @@ struct WireHelpers {
ref
->
listRef
.
set
(
elementSize
,
elementCount
);
ref
->
listRef
.
set
(
elementSize
,
elementCount
);
// Build the ListBuilder.
// Build the ListBuilder.
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
),
return
ListBuilder
(
segment
,
ptr
,
step
/
BITS_PER_BYTE
,
elementCount
);
step
/
BITS_PER_BYTE
,
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
)
||
if
(
elementSize
.
preferredListEncoding
!=
FieldSize
::
INLINE_COMPOSITE
)
{
(
elementSize
.
pointers
==
1
*
REFERENCES
&&
elementSize
.
data
==
0
*
WORDS
))
{
// Small data-only struct. Allocate a list of primitives instead. Don't ever pack as
// Small data-only struct. Allocate a list of primitives instead.
// individual bits, though; we don't support that.
FieldSize
primitiveElementSize
=
FieldSize
::
VOID
;
return
initListReference
(
ref
,
segment
,
elementCount
,
if
(
elementSize
.
pointers
==
1
*
REFERENCES
)
{
elementSize
.
preferredListEncoding
==
FieldSize
::
BIT
?
primitiveElementSize
=
FieldSize
::
REFERENCE
;
FieldSize
::
BYTE
:
elementSize
.
preferredListEncoding
);
}
else
{
switch
(
elementSize
.
dataBytes
/
BYTES
)
{
case
0
:
primitiveElementSize
=
FieldSize
::
VOID
;
break
;
case
1
:
primitiveElementSize
=
FieldSize
::
BYTE
;
break
;
case
2
:
primitiveElementSize
=
FieldSize
::
TWO_BYTES
;
break
;
case
4
:
primitiveElementSize
=
FieldSize
::
FOUR_BYTES
;
break
;
case
8
:
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
;
...
@@ -511,9 +499,7 @@ struct WireHelpers {
...
@@ -511,9 +499,7 @@ struct WireHelpers {
ptr
+=
REFERENCE_SIZE_IN_WORDS
;
ptr
+=
REFERENCE_SIZE_IN_WORDS
;
// Build the ListBuilder.
// Build the ListBuilder.
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
elementSize
.
data
),
return
ListBuilder
(
segment
,
ptr
,
wordsPerElement
*
BYTES_PER_WORD
,
elementCount
);
wordsPerElement
*
BYTES_PER_WORD
,
wordsPerElement
/
WORDS_PER_REFERENCE
,
elementCount
);
}
}
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getWritableListReference
(
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getWritableListReference
(
...
@@ -523,8 +509,7 @@ struct WireHelpers {
...
@@ -523,8 +509,7 @@ struct WireHelpers {
if
(
ref
->
isNull
())
{
if
(
ref
->
isNull
())
{
if
(
defaultValue
==
nullptr
)
{
if
(
defaultValue
==
nullptr
)
{
return
ListBuilder
(
segment
,
nullptr
,
nullptr
,
0
*
BYTES
/
ELEMENTS
,
return
ListBuilder
();
0
*
REFERENCES
/
ELEMENTS
,
0
*
ELEMENTS
);
}
}
ptr
=
copyMessage
(
segment
,
ref
,
defaultRef
);
ptr
=
copyMessage
(
segment
,
ref
,
defaultRef
);
}
else
{
}
else
{
...
@@ -541,17 +526,11 @@ struct WireHelpers {
...
@@ -541,17 +526,11 @@ struct WireHelpers {
"INLINE_COMPOSITE list with non-STRUCT elements not supported."
);
"INLINE_COMPOSITE list with non-STRUCT elements not supported."
);
// First list element is at tag + 1 reference.
// First list element is at tag + 1 reference.
word
*
data
=
reinterpret_cast
<
word
*>
(
tag
+
1
);
return
ListBuilder
(
segment
,
tag
+
1
,
tag
->
structRef
.
wordSize
()
*
BYTES_PER_WORD
/
ELEMENTS
,
WireReference
*
pointers
=
reinterpret_cast
<
WireReference
*>
(
data
+
tag
->
structRef
.
dataSize
.
get
());
auto
step
=
tag
->
structRef
.
wordSize
()
/
ELEMENTS
;
return
ListBuilder
(
segment
,
data
,
pointers
,
step
*
BYTES_PER_WORD
,
step
/
WORDS_PER_REFERENCE
,
tag
->
inlineCompositeListElementCount
());
tag
->
inlineCompositeListElementCount
());
}
else
{
}
else
{
auto
step
=
bytesPerElement
(
ref
->
listRef
.
elementSize
());
auto
step
=
bytesPerElement
(
ref
->
listRef
.
elementSize
());
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
),
return
ListBuilder
(
segment
,
ptr
,
step
,
ref
->
listRef
.
elementCount
());
step
,
step
/
BYTES_PER_REFERENCE
,
ref
->
listRef
.
elementCount
());
}
}
}
}
...
@@ -685,9 +664,7 @@ struct WireHelpers {
...
@@ -685,9 +664,7 @@ struct WireHelpers {
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
useDefault
:
if
(
defaultValue
==
nullptr
)
{
if
(
defaultValue
==
nullptr
)
{
return
ListReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
ELEMENTS
,
return
ListReader
();
0
*
BYTES
/
ELEMENTS
,
0
*
REFERENCES
/
ELEMENTS
,
nestingLimit
-
1
);
}
}
segment
=
nullptr
;
segment
=
nullptr
;
ref
=
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
);
ref
=
reinterpret_cast
<
const
WireReference
*>
(
defaultValue
);
...
@@ -795,9 +772,7 @@ struct WireHelpers {
...
@@ -795,9 +772,7 @@ struct WireHelpers {
}
}
return
ListReader
(
return
ListReader
(
segment
,
ptr
,
segment
,
ptr
,
size
,
wordsPerElement
*
BYTES_PER_WORD
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
+
tag
->
structRef
.
dataSize
.
get
()),
size
,
wordsPerElement
*
BYTES_PER_WORD
,
wordsPerElement
/
WORDS_PER_REFERENCE
,
tag
->
structRef
.
dataSize
.
get
()
*
BYTES_PER_WORD
,
tag
->
structRef
.
dataSize
.
get
()
*
BYTES_PER_WORD
,
tag
->
structRef
.
refCount
.
get
(),
nestingLimit
-
1
);
tag
->
structRef
.
refCount
.
get
(),
nestingLimit
-
1
);
...
@@ -814,9 +789,8 @@ struct WireHelpers {
...
@@ -814,9 +789,8 @@ struct WireHelpers {
}
}
if
(
ref
->
listRef
.
elementSize
()
==
expectedElementSize
)
{
if
(
ref
->
listRef
.
elementSize
()
==
expectedElementSize
)
{
return
ListReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
),
return
ListReader
(
segment
,
ptr
,
ref
->
listRef
.
elementCount
(),
step
/
BITS_PER_BYTE
,
ref
->
listRef
.
elementCount
(),
step
/
BITS_PER_BYTE
,
nestingLimit
-
1
);
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
...
@@ -845,9 +819,8 @@ struct WireHelpers {
...
@@ -845,9 +819,8 @@ struct WireHelpers {
break
;
break
;
}
}
return
ListReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
),
return
ListReader
(
segment
,
ptr
,
ref
->
listRef
.
elementCount
(),
step
/
BITS_PER_BYTE
,
ref
->
listRef
.
elementCount
(),
step
/
BITS_PER_BYTE
,
dataSize
,
referenceCount
,
nestingLimit
-
1
);
step
/
BITS_PER_REFERENCE
,
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."
);
goto
useDefault
;
goto
useDefault
;
...
@@ -1080,102 +1053,124 @@ Data::Reader StructReader::getDataField(
...
@@ -1080,102 +1053,124 @@ Data::Reader StructReader::getDataField(
StructBuilder
ListBuilder
::
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
{
StructBuilder
ListBuilder
::
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
{
// TODO: Inline this method?
// TODO: Inline this method?
ByteCount
indexByte
=
ElementCount64
(
index
)
*
stepBytes
;
byte
*
structData
=
ptr
+
index
*
stepBytes
;
byte
*
structData
=
reinterpret_cast
<
byte
*>
(
data
)
+
indexByte
;
return
StructBuilder
(
segment
,
structData
,
WireReference
*
structPointers
=
pointers
+
index
*
stepPointers
;
reinterpret_cast
<
WireReference
*>
(
structData
)
+
elementSize
.
data
/
WORDS_PER_REFERENCE
);
return
StructBuilder
(
segment
,
structData
,
structPointers
,
elementSize
.
pointers
);
}
}
ListBuilder
ListBuilder
::
initListElement
(
ListBuilder
ListBuilder
::
initListElement
(
ElementCount
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
{
ElementCount
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
{
return
WireHelpers
::
initListReference
(
return
WireHelpers
::
initListReference
(
pointers
+
index
*
stepPointers
,
segment
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
elementCount
,
elementSize
);
segment
,
elementCount
,
elementSize
);
}
}
ListBuilder
ListBuilder
::
initStructListElement
(
ListBuilder
ListBuilder
::
initStructListElement
(
ElementCount
index
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
ElementCount
index
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
return
WireHelpers
::
initStructListReference
(
return
WireHelpers
::
initStructListReference
(
pointers
+
index
*
stepPointers
,
segment
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
elementCount
,
elementSize
);
segment
,
elementCount
,
elementSize
);
}
}
ListBuilder
ListBuilder
::
getListElement
(
ElementCount
index
)
const
{
ListBuilder
ListBuilder
::
getListElement
(
ElementCount
index
)
const
{
return
WireHelpers
::
getWritableListReference
(
return
WireHelpers
::
getWritableListReference
(
pointers
+
index
*
stepPointers
,
segment
,
nullptr
);
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
segment
,
nullptr
);
}
}
Text
::
Builder
ListBuilder
::
initTextElement
(
ElementCount
index
,
ByteCount
size
)
const
{
Text
::
Builder
ListBuilder
::
initTextElement
(
ElementCount
index
,
ByteCount
size
)
const
{
return
WireHelpers
::
initTextReference
(
return
WireHelpers
::
initTextReference
(
pointers
+
index
*
stepPointers
,
segment
,
size
);
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
segment
,
size
);
}
}
void
ListBuilder
::
setTextElement
(
ElementCount
index
,
Text
::
Reader
value
)
const
{
void
ListBuilder
::
setTextElement
(
ElementCount
index
,
Text
::
Reader
value
)
const
{
WireHelpers
::
setTextReference
(
WireHelpers
::
setTextReference
(
pointers
+
index
*
stepPointers
,
segment
,
value
);
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
segment
,
value
);
}
}
Text
::
Builder
ListBuilder
::
getTextElement
(
ElementCount
index
)
const
{
Text
::
Builder
ListBuilder
::
getTextElement
(
ElementCount
index
)
const
{
return
WireHelpers
::
getWritableTextReference
(
return
WireHelpers
::
getWritableTextReference
(
pointers
+
index
*
stepPointers
,
segment
,
""
,
0
*
BYTES
);
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
segment
,
""
,
0
*
BYTES
);
}
}
Data
::
Builder
ListBuilder
::
initDataElement
(
ElementCount
index
,
ByteCount
size
)
const
{
Data
::
Builder
ListBuilder
::
initDataElement
(
ElementCount
index
,
ByteCount
size
)
const
{
return
WireHelpers
::
initDataReference
(
return
WireHelpers
::
initDataReference
(
pointers
+
index
*
stepPointers
,
segment
,
size
);
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
segment
,
size
);
}
}
void
ListBuilder
::
setDataElement
(
ElementCount
index
,
Data
::
Reader
value
)
const
{
void
ListBuilder
::
setDataElement
(
ElementCount
index
,
Data
::
Reader
value
)
const
{
WireHelpers
::
setDataReference
(
WireHelpers
::
setDataReference
(
pointers
+
index
*
stepPointers
,
segment
,
value
);
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
segment
,
value
);
}
}
Data
::
Builder
ListBuilder
::
getDataElement
(
ElementCount
index
)
const
{
Data
::
Builder
ListBuilder
::
getDataElement
(
ElementCount
index
)
const
{
return
WireHelpers
::
getWritableDataReference
(
return
WireHelpers
::
getWritableDataReference
(
pointers
+
index
*
stepPointers
,
segment
,
nullptr
,
0
*
BYTES
);
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
stepBytes
)
,
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
,
data
,
pointers
,
elementCount
,
stepBytes
,
stepPointers
,
return
ListReader
(
segment
,
ptr
,
elementCount
,
stepBytes
,
std
::
numeric_limits
<
int
>::
max
());
std
::
numeric_limits
<
int
>::
max
());
}
}
ListReader
ListBuilder
::
asReader
(
StructSize
elementSize
)
const
{
ListReader
ListBuilder
::
asReader
(
StructSize
elementSize
)
const
{
return
ListReader
(
segment
,
data
,
pointers
,
elementCount
,
stepBytes
,
stepPointers
,
DCHECK
(
stepBytes
*
ELEMENTS
>=
elementSize
.
data
*
BYTES_PER_WORD
||
elementSize
.
dataBytes
,
elementSize
.
pointers
,
std
::
numeric_limits
<
int
>::
max
());
(
elementSize
.
data
==
1
*
WORDS
&&
elementSize
.
preferredListEncoding
!=
FieldSize
::
INLINE_COMPOSITE
&&
elementSize
.
preferredListEncoding
!=
FieldSize
::
REFERENCE
&&
stepBytes
==
bytesPerElement
(
elementSize
.
preferredListEncoding
)),
"Assumptions used here did not hold."
);
return
ListReader
(
segment
,
ptr
,
elementCount
,
stepBytes
,
std
::
min
(
stepBytes
*
ELEMENTS
,
elementSize
.
data
*
BYTES_PER_WORD
),
elementSize
.
pointers
,
std
::
numeric_limits
<
int
>::
max
());
}
}
// =======================================================================================
// =======================================================================================
// ListReader
// ListReader
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
();
}
}
ByteCount
indexByte
=
index
*
stepBytes
;
ByteCount
indexByte
=
index
*
stepBytes
;
const
byte
*
structData
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
indexByte
;
const
byte
*
structData
=
ptr
+
indexByte
;
const
WireReference
*
structPointers
=
reinterpret_cast
<
const
WireReference
*>
(
structData
+
structDataSize
);
// This check should pass if there are no bugs in the list pointer validation code.
DCHECK
(
structReferenceCount
==
0
*
REFERENCES
||
(
uintptr_t
)
structPointers
%
sizeof
(
WireReference
)
==
0
,
"Pointer segment of struct list element not aligned."
);
return
StructReader
(
return
StructReader
(
segment
,
structData
,
pointers
+
index
*
step
Pointers
,
segment
,
structData
,
struct
Pointers
,
structDataSize
,
structReferenceCount
,
nestingLimit
-
1
);
structDataSize
,
structReferenceCount
,
nestingLimit
-
1
);
}
}
static
const
WireReference
*
checkAlignment
(
const
void
*
ptr
)
{
DCHECK
((
uintptr_t
)
ptr
%
sizeof
(
WireReference
)
==
0
,
"Pointer segment of struct list element not aligned."
);
return
reinterpret_cast
<
const
WireReference
*>
(
ptr
);
}
ListReader
ListReader
::
getListElement
(
ListReader
ListReader
::
getListElement
(
ElementCount
index
,
FieldSize
expectedElementSize
)
const
{
ElementCount
index
,
FieldSize
expectedElementSize
)
const
{
return
WireHelpers
::
readListReference
(
return
WireHelpers
::
readListReference
(
segment
,
pointers
+
index
*
stepPointers
,
segment
,
checkAlignment
(
ptr
+
index
*
stepBytes
)
,
nullptr
,
expectedElementSize
,
nestingLimit
);
nullptr
,
expectedElementSize
,
nestingLimit
);
}
}
Text
::
Reader
ListReader
::
getTextElement
(
ElementCount
index
)
const
{
Text
::
Reader
ListReader
::
getTextElement
(
ElementCount
index
)
const
{
return
WireHelpers
::
readTextReference
(
return
WireHelpers
::
readTextReference
(
segment
,
pointers
+
index
*
stepPointers
,
""
,
0
*
BYTES
);
segment
,
checkAlignment
(
ptr
+
index
*
stepBytes
),
""
,
0
*
BYTES
);
}
}
Data
::
Reader
ListReader
::
getDataElement
(
ElementCount
index
)
const
{
Data
::
Reader
ListReader
::
getDataElement
(
ElementCount
index
)
const
{
return
WireHelpers
::
readDataReference
(
return
WireHelpers
::
readDataReference
(
segment
,
pointers
+
index
*
stepPointers
,
nullptr
,
0
*
BYTES
);
segment
,
checkAlignment
(
ptr
+
index
*
stepBytes
),
nullptr
,
0
*
BYTES
);
}
}
}
// namespace internal
}
// namespace internal
...
...
c++/src/capnproto/layout.h
View file @
de33baaf
...
@@ -28,11 +28,6 @@
...
@@ -28,11 +28,6 @@
// as does other parts of the Cap'n proto library which provide a higher-level interface for
// as does other parts of the Cap'n proto library which provide a higher-level interface for
// dynamic introspection.
// dynamic introspection.
#ifdef __CDT_PARSER__
// Eclipse keeps thinking this is pre-defined for no apparent reason.
#undef CAPNPROTO_LAYOUT_H_
#endif
#ifndef CAPNPROTO_LAYOUT_H_
#ifndef CAPNPROTO_LAYOUT_H_
#define CAPNPROTO_LAYOUT_H_
#define CAPNPROTO_LAYOUT_H_
...
@@ -137,15 +132,17 @@ struct StructSize {
...
@@ -137,15 +132,17 @@ struct StructSize {
WordCount16
data
;
WordCount16
data
;
WireReferenceCount16
pointers
;
WireReferenceCount16
pointers
;
ByteCount32
dataBytes
;
FieldSize
preferredListEncoding
;
// Number of bytes in the data section. Must be data * 8 except when data == 1 in which case
// Preferred size to use when encoding a list of this struct. This is INLINE_COMPOSITE if and
// this can be 1, 2, 4, or 8.
// only if the struct is larger than one word; otherwise the struct list can be encoded more
// efficiently by encoding it as if it were some primitive type.
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
,
ByteCount
dataBytes
)
inline
constexpr
StructSize
(
WordCount
data
,
WireReferenceCount
pointers
,
:
data
(
data
),
pointers
(
pointers
),
dataBytes
(
dataBytes
)
{}
FieldSize
preferredListEncoding
)
:
data
(
data
),
pointers
(
pointers
),
preferredListEncoding
(
preferredListEncoding
)
{}
};
};
template
<
typename
T
>
template
<
typename
T
>
...
@@ -325,20 +322,13 @@ public:
...
@@ -325,20 +322,13 @@ 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.
WireReference
*
references
;
// Pointer to the encoded references.
WireReference
*
references
;
// Pointer to the encoded references.
WireReferenceCount16
referenceCount
;
inline
StructBuilder
(
SegmentBuilder
*
segment
,
void
*
data
,
WireReference
*
references
)
// Size of the pointer segment, available only for the sake of computing size of List(Inline(T)).
:
segment
(
segment
),
data
(
data
),
references
(
references
)
{}
inline
StructBuilder
(
SegmentBuilder
*
segment
,
void
*
data
,
WireReference
*
references
,
WireReferenceCount
referenceCount
)
:
segment
(
segment
),
data
(
data
),
references
(
references
),
referenceCount
(
referenceCount
)
{}
friend
class
ListBuilder
;
friend
class
ListBuilder
;
friend
struct
WireHelpers
;
friend
struct
WireHelpers
;
...
@@ -393,7 +383,10 @@ private:
...
@@ -393,7 +383,10 @@ private:
const
void
*
data
;
const
void
*
data
;
const
WireReference
*
references
;
const
WireReference
*
references
;
ByteCount32
dataSize
;
// Size of data segment.
ByteCount32
dataSize
;
// Size of data segment. We use a byte count rather than a word count to more easily handle the
// case of struct lists encoded with less than a word per element.
WireReferenceCount16
referenceCount
;
// Size of the reference segment.
WireReferenceCount16
referenceCount
;
// Size of the reference segment.
int
nestingLimit
;
int
nestingLimit
;
...
@@ -417,8 +410,8 @@ private:
...
@@ -417,8 +410,8 @@ private:
class
ListBuilder
{
class
ListBuilder
{
public
:
public
:
inline
ListBuilder
()
inline
ListBuilder
()
:
segment
(
nullptr
),
data
(
nullptr
),
pointers
(
nullptr
),
elementCount
(
0
*
ELEMENTS
),
:
segment
(
nullptr
),
ptr
(
nullptr
),
elementCount
(
0
*
ELEMENTS
),
stepBytes
(
0
*
BYTES
/
ELEMENTS
)
,
stepPointers
(
0
*
REFERENCES
/
ELEMENTS
)
{}
stepBytes
(
0
*
BYTES
/
ELEMENTS
)
{}
inline
ElementCount
size
();
inline
ElementCount
size
();
// The number of elements in the list.
// The number of elements in the list.
...
@@ -449,10 +442,6 @@ public:
...
@@ -449,10 +442,6 @@ public:
// 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.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
slice
(
ElementCount
start
,
ElementCount
length
)
const
);
// Get a list pointing at a slice of this list. WARNING: The second parameter is a length, not
// an end index, because this is what is most convenient at the only call site.
Text
::
Builder
initTextElement
(
ElementCount
index
,
ByteCount
size
)
const
;
Text
::
Builder
initTextElement
(
ElementCount
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.
...
@@ -477,22 +466,18 @@ public:
...
@@ -477,22 +466,18 @@ public:
private
:
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the list resides.
SegmentBuilder
*
segment
;
// Memory segment in which the list resides.
void
*
data
;
byte
*
ptr
;
// Pointer to list content.
WireReference
*
pointers
;
// Pointers to list content.
ElementCount
elementCount
;
// Number of elements in the list.
ElementCount
elementCount
;
// Number of elements in the list.
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
;
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
;
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
;
// The distance between elements.
// The distance between elements. Can be tricky e.g. for inlined struct lists.
// Bit lists ignore stepBytes -- they are always tightly-packed.
// Bit lists ignore stepBytes -- they are always tightly-packed.
inline
ListBuilder
(
SegmentBuilder
*
segment
,
void
*
data
,
WireReference
*
pointers
,
inline
ListBuilder
(
SegmentBuilder
*
segment
,
void
*
ptr
,
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
,
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
,
ElementCount
size
)
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
ElementCount
size
)
:
segment
(
segment
),
ptr
(
reinterpret_cast
<
byte
*>
(
ptr
)),
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
size
),
elementCount
(
size
),
stepBytes
(
stepBytes
)
{}
stepBytes
(
stepBytes
),
stepPointers
(
stepPointers
)
{}
friend
class
StructBuilder
;
friend
class
StructBuilder
;
friend
struct
WireHelpers
;
friend
struct
WireHelpers
;
...
@@ -501,8 +486,7 @@ private:
...
@@ -501,8 +486,7 @@ private:
class
ListReader
{
class
ListReader
{
public
:
public
:
inline
ListReader
()
inline
ListReader
()
:
segment
(
nullptr
),
data
(
nullptr
),
pointers
(
nullptr
),
elementCount
(
0
),
:
segment
(
nullptr
),
ptr
(
nullptr
),
elementCount
(
0
),
stepBytes
(
0
*
BYTES
/
ELEMENTS
),
stepBytes
(
0
*
BYTES
/
ELEMENTS
),
stepPointers
(
0
*
REFERENCES
/
ELEMENTS
),
structDataSize
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
0
)
{}
structDataSize
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
0
)
{}
inline
ElementCount
size
();
inline
ElementCount
size
();
...
@@ -518,10 +502,6 @@ public:
...
@@ -518,10 +502,6 @@ public:
ListReader
getListElement
(
ElementCount
index
,
FieldSize
expectedElementSize
)
const
;
ListReader
getListElement
(
ElementCount
index
,
FieldSize
expectedElementSize
)
const
;
// Get the list element at the given index.
// Get the list element at the given index.
CAPNPROTO_ALWAYS_INLINE
(
ListReader
slice
(
ElementCount
start
,
ElementCount
length
)
const
);
// Get a list pointing at a slice of this list. WARNING: The second parameter is a length, not
// an end index, because this is what is most convenient at the only call site.
Text
::
Reader
getTextElement
(
ElementCount
index
)
const
;
Text
::
Reader
getTextElement
(
ElementCount
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.
...
@@ -531,15 +511,12 @@ public:
...
@@ -531,15 +511,12 @@ public:
private
:
private
:
SegmentReader
*
segment
;
// Memory segment in which the list resides.
SegmentReader
*
segment
;
// Memory segment in which the list resides.
const
void
*
data
;
const
byte
*
ptr
;
// Pointer to list content.
const
WireReference
*
pointers
;
// Pointers to list content.
ElementCount
elementCount
;
// Number of elements in the list.
ElementCount
elementCount
;
// Number of elements in the list.
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
;
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
;
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
;
// The distance between elements.
// The distance between elements. Can be tricky e.g. for inlined struct lists.
// Bit lists ignore stepBytes -- they are always tightly-packed.
// Bit lists ignore stepBytes -- they are always tightly-packed.
ByteCount
structDataSize
;
ByteCount
structDataSize
;
...
@@ -550,18 +527,18 @@ private:
...
@@ -550,18 +527,18 @@ private:
// 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
*
data
,
const
WireReference
*
pointers
,
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
ptr
,
ElementCount
elementCount
,
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
,
ElementCount
elementCount
,
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
int
nestingLimit
)
int
nestingLimit
)
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
elementCount
),
:
segment
(
segment
),
ptr
(
reinterpret_cast
<
const
byte
*>
(
ptr
)
),
elementCount
(
elementCount
),
stepBytes
(
stepBytes
),
st
epPointers
(
stepPointers
),
structDataSize
(
0
),
stepBytes
(
stepBytes
),
st
ructDataSize
(
0
),
structReferenceCount
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
nestingLimit
)
{}
nestingLimit
(
nestingLimit
)
{}
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
data
,
const
WireReference
*
pointers
,
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
ptr
,
ElementCount
elementCount
,
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
,
ElementCount
elementCount
,
decltype
(
BYTES
/
ELEMENTS
)
stepBytes
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
ByteCount
structDataSize
,
ByteCount
structDataSize
,
WireReferenceCount
structReferenceCount
,
WireReferenceCount
structReferenceCount
,
int
nestingLimit
)
int
nestingLimit
)
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
elementCount
),
:
segment
(
segment
),
ptr
(
reinterpret_cast
<
const
byte
*>
(
ptr
)
),
elementCount
(
elementCount
),
stepBytes
(
stepBytes
),
st
epPointers
(
stepPointers
),
st
ructDataSize
(
structDataSize
),
stepBytes
(
stepBytes
),
structDataSize
(
structDataSize
),
structReferenceCount
(
structReferenceCount
),
nestingLimit
(
nestingLimit
)
{}
structReferenceCount
(
structReferenceCount
),
nestingLimit
(
nestingLimit
)
{}
friend
class
StructReader
;
friend
class
StructReader
;
...
@@ -656,15 +633,14 @@ inline ElementCount ListBuilder::size() { return elementCount; }
...
@@ -656,15 +633,14 @@ 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
>*>
(
return
reinterpret_cast
<
WireValue
<
T
>*>
(
ptr
+
index
*
stepBytes
)
->
get
();
reinterpret_cast
<
byte
*>
(
data
)
+
index
*
stepBytes
)
->
get
();
}
}
template
<>
template
<>
inline
bool
ListBuilder
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
inline
bool
ListBuilder
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
byte
*
b
=
ptr
+
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
;
}
}
...
@@ -675,15 +651,14 @@ inline Void ListBuilder::getDataElement<Void>(ElementCount index) const {
...
@@ -675,15 +651,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
>*>
(
reinterpret_cast
<
WireValue
<
T
>*>
(
ptr
+
index
*
stepBytes
)
->
set
(
value
);
reinterpret_cast
<
byte
*>
(
data
)
+
index
*
stepBytes
)
->
set
(
value
);
}
}
template
<>
template
<>
inline
void
ListBuilder
::
setDataElement
<
bool
>
(
ElementCount
index
,
bool
value
)
const
{
inline
void
ListBuilder
::
setDataElement
<
bool
>
(
ElementCount
index
,
bool
value
)
const
{
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
byte
*
b
=
ptr
+
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
);
...
@@ -692,29 +667,20 @@ inline void ListBuilder::setDataElement<bool>(ElementCount index, bool value) co
...
@@ -692,29 +667,20 @@ inline void ListBuilder::setDataElement<bool>(ElementCount index, bool value) co
template
<>
template
<>
inline
void
ListBuilder
::
setDataElement
<
Void
>
(
ElementCount
index
,
Void
value
)
const
{}
inline
void
ListBuilder
::
setDataElement
<
Void
>
(
ElementCount
index
,
Void
value
)
const
{}
inline
ListBuilder
ListBuilder
::
slice
(
ElementCount
start
,
ElementCount
length
)
const
{
return
ListBuilder
(
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
start
*
stepBytes
,
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
word
*>
(
pointers
)
+
start
*
stepPointers
*
WORDS_PER_REFERENCE
),
stepBytes
,
stepPointers
,
length
);
}
// -------------------------------------------------------------------
// -------------------------------------------------------------------
inline
ElementCount
ListReader
::
size
()
{
return
elementCount
;
}
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
WireValue
<
T
>*>
(
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
ptr
+
index
*
stepBytes
)
->
get
();
reinterpret_cast
<
const
byte
*>
(
data
)
+
index
*
stepBytes
)
->
get
();
}
}
template
<>
template
<>
inline
bool
ListReader
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
inline
bool
ListReader
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
const
byte
*
b
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
const
byte
*
b
=
ptr
+
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
;
}
}
...
@@ -723,14 +689,6 @@ inline Void ListReader::getDataElement<Void>(ElementCount index) const {
...
@@ -723,14 +689,6 @@ inline Void ListReader::getDataElement<Void>(ElementCount index) const {
return
Void
::
VOID
;
return
Void
::
VOID
;
}
}
inline
ListReader
ListReader
::
slice
(
ElementCount
start
,
ElementCount
length
)
const
{
return
ListReader
(
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
start
*
stepBytes
,
reinterpret_cast
<
const
WireReference
*>
(
reinterpret_cast
<
const
word
*>
(
pointers
)
+
start
*
stepPointers
*
WORDS_PER_REFERENCE
),
length
,
stepBytes
,
stepPointers
,
structDataSize
,
structReferenceCount
,
nestingLimit
);
}
}
// namespace internal
}
// namespace internal
}
// namespace capnproto
}
// namespace capnproto
...
...
c++/src/capnproto/type-safety.h
View file @
de33baaf
...
@@ -353,6 +353,15 @@ public:
...
@@ -353,6 +353,15 @@ public:
unit1PerUnit2
/
other
.
unit1PerUnit2
);
unit1PerUnit2
/
other
.
unit1PerUnit2
);
}
}
template
<
typename
OtherNumber
>
inline
decltype
(
Number
(
1
)
/
OtherNumber
(
1
))
operator
/
(
UnitRatio
<
OtherNumber
,
Unit1
,
Unit2
>
other
)
const
{
return
unit1PerUnit2
/
other
.
unit1PerUnit2
;
}
inline
bool
operator
==
(
UnitRatio
other
)
const
{
return
unit1PerUnit2
==
other
.
unit1PerUnit2
;
}
inline
bool
operator
!=
(
UnitRatio
other
)
const
{
return
unit1PerUnit2
!=
other
.
unit1PerUnit2
;
}
private
:
private
:
Number
unit1PerUnit2
;
Number
unit1PerUnit2
;
...
...
compiler/src/CxxGenerator.hs
View file @
de33baaf
...
@@ -379,8 +379,16 @@ structContext parent desc = mkStrContext context where
...
@@ -379,8 +379,16 @@ 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
"structDataBytes"
=
MuVariable
(
div
(
dataSectionBits
(
structDataSize
desc
))
8
)
context
"structReferenceCount"
=
MuVariable
$
structPointerCount
desc
context
"structReferenceCount"
=
MuVariable
$
structPointerCount
desc
context
"structPreferredListEncoding"
=
case
(
structDataSize
desc
,
structPointerCount
desc
)
of
(
DataSectionWords
0
,
0
)
->
MuVariable
"VOID"
(
DataSection1
,
0
)
->
MuVariable
"BYTE"
(
DataSection8
,
0
)
->
MuVariable
"BYTE"
(
DataSection16
,
0
)
->
MuVariable
"TWO_BYTES"
(
DataSection32
,
0
)
->
MuVariable
"FOUR_BYTES"
(
DataSectionWords
1
,
0
)
->
MuVariable
"EIGHT_BYTES"
(
DataSectionWords
0
,
1
)
->
MuVariable
"REFERENCE"
_
->
MuVariable
"INLINE_COMPOSITE"
context
"structNestedEnums"
=
context
"structNestedEnums"
=
MuList
$
map
(
enumContext
context
)
[
m
|
DescEnum
m
<-
structMembers
desc
]
MuList
$
map
(
enumContext
context
)
[
m
|
DescEnum
m
<-
structMembers
desc
]
context
"structNestedStructs"
=
context
"structNestedStructs"
=
...
...
compiler/src/c++-header.mustache
View file @
de33baaf
...
@@ -68,9 +68,10 @@ struct {{typeFullName}} {
...
@@ -68,9 +68,10 @@ struct {{typeFullName}} {
{{/
structNestedEnums
}}
{{/
structNestedEnums
}}
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
::capnproto::internal::StructSize(
{{
structDataSize
}}
* ::capnproto::WORDS,
::capnproto::internal::StructSize(
{{
structReferenceCount
}}
* ::capnproto::REFERENCES,
{{
structDataSize
}}
* ::capnproto::WORDS,
{{
structDataBytes
}}
* ::capnproto::BYTES);
{{
structReferenceCount
}}
* ::capnproto::REFERENCES,
::capnproto::internal::FieldSize::
{{
structPreferredListEncoding
}}
);
{{/
typeStruct
}}
{{/
typeStruct
}}
{{#
typeUnion
}}
{{#
typeUnion
}}
...
...
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