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
9c54bce6
Commit
9c54bce6
authored
Nov 09, 2014
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix problems with AnyStruct / AnyList change.
parent
fff8e987
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
147 additions
and
87 deletions
+147
-87
any.h
c++/src/capnp/any.h
+44
-32
common.h
c++/src/capnp/common.h
+15
-0
layout.c++
c++/src/capnp/layout.c++
+72
-7
layout.h
c++/src/capnp/layout.h
+16
-47
pointer-helpers.h
c++/src/capnp/pointer-helpers.h
+0
-1
No files found.
c++/src/capnp/any.h
View file @
9c54bce6
...
@@ -177,10 +177,11 @@ struct AnyPointer {
...
@@ -177,10 +177,11 @@ struct AnyPointer {
inline
BuilderFor
<
T
>
initAs
(
ListSchema
schema
,
uint
elementCount
);
inline
BuilderFor
<
T
>
initAs
(
ListSchema
schema
,
uint
elementCount
);
// Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
// Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
inline
AnyList
::
Builder
initAsAnyList
(
_
::
Field
Size
elementSize
,
uint
elementCount
);
inline
AnyList
::
Builder
initAsAnyList
(
Element
Size
elementSize
,
uint
elementCount
);
// Note: Does not accept INLINE_COMPOSITE for elementSize.
// Note: Does not accept INLINE_COMPOSITE for elementSize.
inline
List
<
AnyStruct
>::
Builder
initAsListOfAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
,
uint
elementCount
);
inline
List
<
AnyStruct
>::
Builder
initAsListOfAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
,
uint
elementCount
);
inline
AnyStruct
::
Builder
initAsAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
);
inline
AnyStruct
::
Builder
initAsAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
);
...
@@ -540,10 +541,8 @@ public:
...
@@ -540,10 +541,8 @@ public:
Reader
()
=
default
;
Reader
()
=
default
;
inline
Reader
(
_
::
ListReader
reader
)
:
_reader
(
reader
)
{}
inline
Reader
(
_
::
ListReader
reader
)
:
_reader
(
reader
)
{}
_
::
FieldSize
getElementSize
();
inline
ElementSize
getElementSize
()
{
return
_reader
.
getElementSize
();
}
ElementCount
size
()
{
inline
uint
size
()
{
return
_reader
.
size
()
/
ELEMENTS
;
}
return
_reader
.
size
();
}
template
<
typename
T
>
ReaderFor
<
T
>
as
()
{
template
<
typename
T
>
ReaderFor
<
T
>
as
()
{
// T must be List<U>.
// T must be List<U>.
...
@@ -556,13 +555,10 @@ private:
...
@@ -556,13 +555,10 @@ private:
class
AnyList
::
Builder
{
class
AnyList
::
Builder
{
public
:
public
:
inline
Builder
(
decltype
(
nullptr
))
{}
inline
Builder
(
decltype
(
nullptr
))
{}
inline
Builder
(
_
::
PointerBuilder
builder
,
_
::
FieldSize
size
,
const
word
*
defaultValue
=
nullptr
)
:
_builder
(
builder
.
getList
(
size
,
defaultValue
))
{}
inline
Builder
(
_
::
ListBuilder
builder
)
:
_builder
(
builder
)
{}
inline
Builder
(
_
::
ListBuilder
builder
)
:
_builder
(
builder
)
{}
_
::
FieldSize
getElementSize
();
inline
ElementSize
getElementSize
()
{
return
_builder
.
getElementSize
();
}
ElementCount
size
()
{
inline
uint
size
()
{
return
_builder
.
size
()
/
ELEMENTS
;
}
return
_builder
.
size
();
}
template
<
typename
T
>
BuilderFor
<
T
>
as
()
{
template
<
typename
T
>
BuilderFor
<
T
>
as
()
{
// T must be List<U>.
// T must be List<U>.
...
@@ -577,38 +573,48 @@ private:
...
@@ -577,38 +573,48 @@ private:
};
};
namespace
_
{
// (private)
namespace
_
{
// (private)
template
<>
template
<>
struct
PointerHelpers
<
AnyStruct
,
Kind
::
OTHER
>
{
struct
PointerHelpers
<
AnyStruct
,
Kind
::
OTHER
>
{
static
inline
typename
AnyStruct
::
Reader
get
(
PointerReader
reader
,
const
word
*
defaultValue
=
nullptr
)
{
static
inline
typename
AnyStruct
::
Reader
get
(
PointerReader
reader
,
const
word
*
defaultValue
=
nullptr
)
{
return
typename
AnyStruct
::
Reader
(
reader
.
getStruct
(
defaultValue
));
return
typename
AnyStruct
::
Reader
(
reader
.
getStruct
(
defaultValue
));
}
}
static
inline
typename
AnyStruct
::
Builder
get
(
PointerBuilder
builder
,
static
inline
typename
AnyStruct
::
Builder
get
(
const
word
*
defaultValue
=
nullptr
)
{
PointerBuilder
builder
,
const
word
*
defaultValue
=
nullptr
)
{
return
typename
AnyStruct
::
Builder
(
builder
,
/* TODO: allow specifying the size! */
_
::
StructSize
(
0
,
0
),
defaultValue
);
// TODO(someday): allow specifying the size
return
typename
AnyStruct
::
Builder
(
builder
,
_
::
StructSize
(
0
*
WORDS
,
0
*
POINTERS
),
defaultValue
);
}
}
static
inline
typename
AnyStruct
::
Builder
init
(
PointerBuilder
builder
,
uint
dataWordCount
,
uint
pointerCount
)
{
static
inline
typename
AnyStruct
::
Builder
init
(
return
typename
AnyStruct
::
Builder
(
builder
.
initStruct
(
StructSize
(
dataWordCount
,
pointerCount
)));
PointerBuilder
builder
,
uint
dataWordCount
,
uint
pointerCount
)
{
return
typename
AnyStruct
::
Builder
(
builder
.
initStruct
(
StructSize
(
dataWordCount
*
WORDS
,
pointerCount
*
POINTERS
)));
}
}
};
};
template
<>
template
<>
struct
PointerHelpers
<
AnyList
,
Kind
::
OTHER
>
{
struct
PointerHelpers
<
AnyList
,
Kind
::
OTHER
>
{
static
inline
typename
AnyList
::
Reader
get
(
PointerReader
reader
,
const
word
*
defaultValue
=
nullptr
)
{
static
inline
typename
AnyList
::
Reader
get
(
return
typename
AnyList
::
Reader
(
reader
.
getList
(
/* TODO: allow specifying the size! */
FieldSize
::
VOID
,
defaultValue
));
PointerReader
reader
,
const
word
*
defaultValue
=
nullptr
)
{
return
typename
AnyList
::
Reader
(
reader
.
getListAnySize
(
defaultValue
));
}
}
static
inline
typename
AnyList
::
Builder
get
(
PointerBuilder
builder
,
static
inline
typename
AnyList
::
Builder
get
(
const
word
*
defaultValue
=
nullptr
)
{
PointerBuilder
builder
,
const
word
*
defaultValue
=
nullptr
)
{
return
typename
AnyList
::
Builder
(
builder
,
/* TODO: allow specifying the size! */
FieldSize
::
VOID
,
defaultValue
);
return
typename
AnyList
::
Builder
(
builder
.
getListAnySize
(
defaultValue
)
);
}
}
static
inline
typename
AnyList
::
Builder
init
(
PointerBuilder
builder
,
FieldSize
elementSize
,
uint
elementCount
)
{
static
inline
typename
AnyList
::
Builder
init
(
return
typename
AnyList
::
Builder
(
builder
.
initList
(
elementSize
,
elementCount
));
PointerBuilder
builder
,
ElementSize
elementSize
,
uint
elementCount
)
{
return
typename
AnyList
::
Builder
(
builder
.
initList
(
elementSize
,
elementCount
*
ELEMENTS
));
}
}
static
inline
typename
AnyList
::
Builder
init
(
PointerBuilder
builder
,
uint
dataWordCount
,
uint
pointerCount
,
uint
elementCount
)
{
static
inline
typename
AnyList
::
Builder
init
(
PointerBuilder
builder
,
uint
dataWordCount
,
uint
pointerCount
,
uint
elementCount
)
{
return
typename
AnyList
::
Builder
(
builder
.
initStructList
(
return
typename
AnyList
::
Builder
(
builder
.
initStructList
(
elementCount
,
elementCount
*
ELEMENTS
,
StructSize
(
dataWordCount
*
WORDS
,
pointerCount
*
POINTERS
)));
StructSize
(
dataWordCount
,
pointerCount
)));
}
}
};
};
}
// end namespace _ (private)
}
// namespace _ (private)
// =======================================================================================
// =======================================================================================
// Pipeline helpers
// Pipeline helpers
...
@@ -701,14 +707,20 @@ inline BuilderFor<T> AnyPointer::Builder::initAs(uint elementCount) {
...
@@ -701,14 +707,20 @@ inline BuilderFor<T> AnyPointer::Builder::initAs(uint elementCount) {
return
_
::
PointerHelpers
<
T
>::
init
(
builder
,
elementCount
);
return
_
::
PointerHelpers
<
T
>::
init
(
builder
,
elementCount
);
}
}
inline
AnyList
::
Builder
AnyPointer
::
Builder
::
initAsAnyList
(
_
::
FieldSize
elementSize
,
uint
elementCount
)
{
inline
AnyList
::
Builder
AnyPointer
::
Builder
::
initAsAnyList
(
return
_
::
PointerHelpers
<
AnyList
>::
init
(
builder
,
elementSize
,
elementCount
);
ElementSize
elementSize
,
uint
elementCount
)
{
return
AnyList
::
Builder
(
builder
.
initList
(
elementSize
,
elementCount
*
ELEMENTS
));
}
}
// inline List<AnyStruct>::Builder AnyPointer::Builder::initAsListOfAnyStruct(uint dataWordCount, uint pointerCount, uint elementCount);
inline
List
<
AnyStruct
>::
Builder
AnyPointer
::
Builder
::
initAsListOfAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
,
uint
elementCount
)
{
return
List
<
AnyStruct
>::
Builder
(
builder
.
initStructList
(
elementCount
*
ELEMENTS
,
_
::
StructSize
(
dataWordCount
*
WORDS
,
pointerCount
*
POINTERS
)));
}
inline
AnyStruct
::
Builder
AnyPointer
::
Builder
::
initAsAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
)
{
inline
AnyStruct
::
Builder
AnyPointer
::
Builder
::
initAsAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
)
{
return
_
::
PointerHelpers
<
AnyStruct
>::
init
(
builder
,
dataWordCount
,
pointerCount
);
return
AnyStruct
::
Builder
(
builder
.
initStruct
(
_
::
StructSize
(
dataWordCount
*
WORDS
,
pointerCount
*
POINTERS
)));
}
}
template
<
typename
T
>
template
<
typename
T
>
...
...
c++/src/capnp/common.h
View file @
9c54bce6
...
@@ -80,6 +80,21 @@ enum class Kind: uint8_t {
...
@@ -80,6 +80,21 @@ enum class Kind: uint8_t {
// special handling. This includes types like AnyPointer, Dynamic*, etc.
// special handling. This includes types like AnyPointer, Dynamic*, etc.
};
};
enum
class
ElementSize
:
uint8_t
{
// Size of a list element.
VOID
=
0
,
BIT
=
1
,
BYTE
=
2
,
TWO_BYTES
=
3
,
FOUR_BYTES
=
4
,
EIGHT_BYTES
=
5
,
POINTER
=
6
,
INLINE_COMPOSITE
=
7
};
namespace
schemas
{
namespace
schemas
{
template
<
typename
T
>
template
<
typename
T
>
...
...
c++/src/capnp/layout.c++
View file @
9c54bce6
...
@@ -1172,6 +1172,58 @@ struct WireHelpers {
...
@@ -1172,6 +1172,58 @@ struct WireHelpers {
}
}
}
}
static
KJ_ALWAYS_INLINE
(
ListBuilder
getWritableListPointerAnySize
(
WirePointer
*
origRef
,
SegmentBuilder
*
origSegment
,
const
word
*
defaultValue
))
{
return
getWritableListPointerAnySize
(
origRef
,
origRef
->
target
(),
origSegment
,
defaultValue
);
}
static
KJ_ALWAYS_INLINE
(
ListBuilder
getWritableListPointerAnySize
(
WirePointer
*
origRef
,
word
*
origRefTarget
,
SegmentBuilder
*
origSegment
,
const
word
*
defaultValue
,
BuilderArena
*
orphanArena
=
nullptr
))
{
if
(
origRef
->
isNull
())
{
useDefault
:
if
(
defaultValue
==
nullptr
||
reinterpret_cast
<
const
WirePointer
*>
(
defaultValue
)
->
isNull
())
{
return
ListBuilder
();
}
origRefTarget
=
copyMessage
(
origSegment
,
origRef
,
reinterpret_cast
<
const
WirePointer
*>
(
defaultValue
));
defaultValue
=
nullptr
;
// If the default value is itself invalid, don't use it again.
}
WirePointer
*
ref
=
origRef
;
SegmentBuilder
*
segment
=
origSegment
;
word
*
ptr
=
followFars
(
ref
,
origRefTarget
,
segment
);
KJ_REQUIRE
(
ref
->
kind
()
==
WirePointer
::
LIST
,
"Called getList{Field,Element}() but existing pointer is not a list."
)
{
goto
useDefault
;
}
FieldSize
elementSize
=
ref
->
listRef
.
elementSize
();
if
(
elementSize
==
FieldSize
::
INLINE_COMPOSITE
)
{
// Read the tag to get the actual element count.
WirePointer
*
tag
=
reinterpret_cast
<
WirePointer
*>
(
ptr
);
KJ_REQUIRE
(
tag
->
kind
()
==
WirePointer
::
STRUCT
,
"INLINE_COMPOSITE list with non-STRUCT elements not supported."
);
ptr
+=
POINTER_SIZE_IN_WORDS
;
return
ListBuilder
(
segment
,
ptr
,
tag
->
structRef
.
wordSize
()
*
BITS_PER_WORD
/
ELEMENTS
,
tag
->
inlineCompositeListElementCount
(),
tag
->
structRef
.
dataSize
.
get
()
*
BITS_PER_WORD
,
tag
->
structRef
.
ptrCount
.
get
(),
FieldSize
::
INLINE_COMPOSITE
);
}
else
{
BitCount
dataSize
=
dataBitsPerElement
(
elementSize
)
*
ELEMENTS
;
WirePointerCount
pointerCount
=
pointersPerElement
(
elementSize
)
*
ELEMENTS
;
auto
step
=
(
dataSize
+
pointerCount
*
BITS_PER_POINTER
)
/
ELEMENTS
;
return
ListBuilder
(
segment
,
ptr
,
step
,
ref
->
listRef
.
elementCount
(),
dataSize
,
pointerCount
,
elementSize
);
}
}
static
KJ_ALWAYS_INLINE
(
ListBuilder
getWritableStructListPointer
(
static
KJ_ALWAYS_INLINE
(
ListBuilder
getWritableStructListPointer
(
WirePointer
*
origRef
,
SegmentBuilder
*
origSegment
,
StructSize
elementSize
,
WirePointer
*
origRef
,
SegmentBuilder
*
origSegment
,
StructSize
elementSize
,
const
word
*
defaultValue
))
{
const
word
*
defaultValue
))
{
...
@@ -1810,14 +1862,15 @@ struct WireHelpers {
...
@@ -1810,14 +1862,15 @@ struct WireHelpers {
static
KJ_ALWAYS_INLINE
(
ListReader
readListPointer
(
static
KJ_ALWAYS_INLINE
(
ListReader
readListPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
defaultValue
,
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
defaultValue
,
FieldSize
expectedElementSize
,
int
nestingLimit
))
{
FieldSize
expectedElementSize
,
int
nestingLimit
,
bool
checkElementSize
=
true
))
{
return
readListPointer
(
segment
,
ref
,
ref
->
target
(),
defaultValue
,
return
readListPointer
(
segment
,
ref
,
ref
->
target
(),
defaultValue
,
expectedElementSize
,
nestingLimit
);
expectedElementSize
,
nestingLimit
,
checkElementSize
);
}
}
static
KJ_ALWAYS_INLINE
(
ListReader
readListPointer
(
static
KJ_ALWAYS_INLINE
(
ListReader
readListPointer
(
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
refTarget
,
SegmentReader
*
segment
,
const
WirePointer
*
ref
,
const
word
*
refTarget
,
const
word
*
defaultValue
,
FieldSize
expectedElementSize
,
int
nestingLimit
))
{
const
word
*
defaultValue
,
FieldSize
expectedElementSize
,
int
nestingLimit
,
bool
checkElementSize
=
true
))
{
if
(
ref
->
isNull
())
{
if
(
ref
->
isNull
())
{
useDefault
:
useDefault
:
if
(
defaultValue
==
nullptr
||
if
(
defaultValue
==
nullptr
||
...
@@ -1875,6 +1928,7 @@ struct WireHelpers {
...
@@ -1875,6 +1928,7 @@ struct WireHelpers {
goto
useDefault
;
goto
useDefault
;
}
}
if
(
checkElementSize
)
{
// If a struct list was not expected, then presumably a non-struct list was upgraded to a
// If a struct list was not expected, then presumably a non-struct list was upgraded to a
// struct list. We need to manipulate the pointer to point at the first field of the
// struct list. We need to manipulate the pointer to point at the first field of the
// struct. Together with the "stepBits", this will allow the struct list to be accessed as
// struct. Together with the "stepBits", this will allow the struct list to be accessed as
...
@@ -1917,6 +1971,7 @@ struct WireHelpers {
...
@@ -1917,6 +1971,7 @@ struct WireHelpers {
case
FieldSize
:
:
INLINE_COMPOSITE
:
case
FieldSize
:
:
INLINE_COMPOSITE
:
break
;
break
;
}
}
}
return
ListReader
(
return
ListReader
(
segment
,
ptr
,
size
,
wordsPerElement
*
BITS_PER_WORD
,
segment
,
ptr
,
size
,
wordsPerElement
*
BITS_PER_WORD
,
...
@@ -1938,6 +1993,7 @@ struct WireHelpers {
...
@@ -1938,6 +1993,7 @@ struct WireHelpers {
goto
useDefault
;
goto
useDefault
;
}
}
if
(
checkElementSize
)
{
if
(
elementSize
==
FieldSize
::
BIT
&&
expectedElementSize
!=
FieldSize
::
BIT
)
{
if
(
elementSize
==
FieldSize
::
BIT
&&
expectedElementSize
!=
FieldSize
::
BIT
)
{
KJ_FAIL_REQUIRE
(
KJ_FAIL_REQUIRE
(
"Found bit list where struct list was expected; upgrading boolean lists to structs "
"Found bit list where struct list was expected; upgrading boolean lists to structs "
...
@@ -1964,6 +2020,7 @@ struct WireHelpers {
...
@@ -1964,6 +2020,7 @@ struct WireHelpers {
"Message contained list with incompatible element type."
)
{
"Message contained list with incompatible element type."
)
{
goto
useDefault
;
goto
useDefault
;
}
}
}
return
ListReader
(
segment
,
ptr
,
ref
->
listRef
.
elementCount
(),
step
,
return
ListReader
(
segment
,
ptr
,
ref
->
listRef
.
elementCount
(),
step
,
dataSize
,
pointerCount
,
elementSize
,
nestingLimit
-
1
);
dataSize
,
pointerCount
,
elementSize
,
nestingLimit
-
1
);
...
@@ -2094,6 +2151,10 @@ ListBuilder PointerBuilder::getStructList(StructSize elementSize, const word* de
...
@@ -2094,6 +2151,10 @@ ListBuilder PointerBuilder::getStructList(StructSize elementSize, const word* de
return
WireHelpers
::
getWritableStructListPointer
(
pointer
,
segment
,
elementSize
,
defaultValue
);
return
WireHelpers
::
getWritableStructListPointer
(
pointer
,
segment
,
elementSize
,
defaultValue
);
}
}
ListBuilder
PointerBuilder
::
getListAnySize
(
const
word
*
defaultValue
)
{
return
WireHelpers
::
getWritableListPointerAnySize
(
pointer
,
segment
,
defaultValue
);
}
template
<>
template
<>
Text
::
Builder
PointerBuilder
::
initBlob
<
Text
>
(
ByteCount
size
)
{
Text
::
Builder
PointerBuilder
::
initBlob
<
Text
>
(
ByteCount
size
)
{
return
WireHelpers
::
initTextPointer
(
pointer
,
segment
,
size
).
value
;
return
WireHelpers
::
initTextPointer
(
pointer
,
segment
,
size
).
value
;
...
@@ -2157,16 +2218,14 @@ bool PointerBuilder::isNull() {
...
@@ -2157,16 +2218,14 @@ bool PointerBuilder::isNull() {
}
}
bool
PointerBuilder
::
isStruct
()
{
bool
PointerBuilder
::
isStruct
()
{
word
*
refTarget
;
WirePointer
*
ptr
=
pointer
;
WirePointer
*
ptr
=
pointer
;
WireHelpers
::
followFars
(
ptr
,
refTarget
,
segment
);
WireHelpers
::
followFars
(
ptr
,
ptr
->
target
()
,
segment
);
return
ptr
->
kind
()
==
WirePointer
::
Kind
::
STRUCT
;
return
ptr
->
kind
()
==
WirePointer
::
Kind
::
STRUCT
;
}
}
bool
PointerBuilder
::
isList
()
{
bool
PointerBuilder
::
isList
()
{
word
*
refTarget
;
WirePointer
*
ptr
=
pointer
;
WirePointer
*
ptr
=
pointer
;
WireHelpers
::
followFars
(
ptr
,
refTarget
,
segment
);
WireHelpers
::
followFars
(
ptr
,
ptr
->
target
()
,
segment
);
return
ptr
->
kind
()
==
WirePointer
::
Kind
::
LIST
;
return
ptr
->
kind
()
==
WirePointer
::
Kind
::
LIST
;
}
}
...
@@ -2220,6 +2279,12 @@ ListReader PointerReader::getList(FieldSize expectedElementSize, const word* def
...
@@ -2220,6 +2279,12 @@ ListReader PointerReader::getList(FieldSize expectedElementSize, const word* def
segment
,
ref
,
defaultValue
,
expectedElementSize
,
nestingLimit
);
segment
,
ref
,
defaultValue
,
expectedElementSize
,
nestingLimit
);
}
}
ListReader
PointerReader
::
getListAnySize
(
const
word
*
defaultValue
)
const
{
const
WirePointer
*
ref
=
pointer
==
nullptr
?
&
zero
.
pointer
:
pointer
;
return
WireHelpers
::
readListPointer
(
segment
,
ref
,
defaultValue
,
FieldSize
::
VOID
/* dummy */
,
nestingLimit
,
false
);
}
template
<>
template
<>
Text
::
Reader
PointerReader
::
getBlob
<
Text
>
(
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
{
Text
::
Reader
PointerReader
::
getBlob
<
Text
>
(
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
{
const
WirePointer
*
ref
=
pointer
==
nullptr
?
&
zero
.
pointer
:
pointer
;
const
WirePointer
*
ref
=
pointer
==
nullptr
?
&
zero
.
pointer
:
pointer
;
...
...
c++/src/capnp/layout.h
View file @
9c54bce6
...
@@ -78,51 +78,10 @@ class BuilderArena;
...
@@ -78,51 +78,10 @@ class BuilderArena;
// =============================================================================
// =============================================================================
enum
class
FieldSize
:
uint8_t
{
using
FieldSize
=
capnp
::
ElementSize
;
// TODO(cleanup): Rename to FieldLayout or maybe ValueLayout.
// Legacy typedef.
//
// Notice that each member of this enum, when representing a list element size, represents a
// TODO(cleanup): Replace all uses.
// size that is greater than or equal to the previous members, since INLINE_COMPOSITE is used
// only for multi-word structs. This is important because it allows us to compare FieldSize
// values for the purpose of deciding when we need to upgrade a list.
VOID
=
0
,
BIT
=
1
,
BYTE
=
2
,
TWO_BYTES
=
3
,
FOUR_BYTES
=
4
,
EIGHT_BYTES
=
5
,
POINTER
=
6
,
// Indicates that the field lives in the pointer section, not the data section.
INLINE_COMPOSITE
=
7
// A composite type of fixed width. This serves two purposes:
// 1) For lists of composite types where all the elements would have the exact same width,
// allocating a list of pointers which in turn point at the elements would waste space. We
// can avoid a layer of indirection by placing all the elements in a flat sequence, and only
// indicating the element properties (e.g. field count for structs) once.
//
// Specifically, a list pointer indicating INLINE_COMPOSITE element size actually points to
// a "tag" describing one element. This tag is formatted like a wire pointer, but the
// "offset" instead stores the element count of the list. The flat list of elements appears
// immediately after the tag. In the list pointer itself, the element count is replaced with
// a word count for the whole list (excluding tag). This allows the tag and elements to be
// precached in a single step rather than two sequential steps.
//
// It is NOT intended to be possible to substitute an INLINE_COMPOSITE list for a POINTER
// list or vice-versa without breaking recipients. Recipients expect one or the other
// depending on the message definition.
//
// However, it IS allowed to substitute an INLINE_COMPOSITE list -- specifically, of structs --
// when a list was expected, or vice versa, with the assumption that the first field of the
// struct (field number zero) correspond to the element type. This allows a list of
// primitives to be upgraded to a list of structs, avoiding the need to use parallel arrays
// when you realize that you need to attach some extra information to each element of some
// primitive list.
//
// 2) At one point there was a notion of "inline" struct fields, but it was deemed too much of
// an implementation burden for too little gain, and so was deleted.
};
typedef
decltype
(
BITS
/
ELEMENTS
)
BitsPerElement
;
typedef
decltype
(
BITS
/
ELEMENTS
)
BitsPerElement
;
typedef
decltype
(
POINTERS
/
ELEMENTS
)
PointersPerElement
;
typedef
decltype
(
POINTERS
/
ELEMENTS
)
PointersPerElement
;
...
@@ -330,6 +289,7 @@ public:
...
@@ -330,6 +289,7 @@ public:
StructBuilder
getStruct
(
StructSize
size
,
const
word
*
defaultValue
);
StructBuilder
getStruct
(
StructSize
size
,
const
word
*
defaultValue
);
ListBuilder
getList
(
FieldSize
elementSize
,
const
word
*
defaultValue
);
ListBuilder
getList
(
FieldSize
elementSize
,
const
word
*
defaultValue
);
ListBuilder
getStructList
(
StructSize
elementSize
,
const
word
*
defaultValue
);
ListBuilder
getStructList
(
StructSize
elementSize
,
const
word
*
defaultValue
);
ListBuilder
getListAnySize
(
const
word
*
defaultValue
);
template
<
typename
T
>
typename
T
::
Builder
getBlob
(
const
void
*
defaultValue
,
ByteCount
defaultSize
);
template
<
typename
T
>
typename
T
::
Builder
getBlob
(
const
void
*
defaultValue
,
ByteCount
defaultSize
);
#if !CAPNP_LITE
#if !CAPNP_LITE
kj
::
Own
<
ClientHook
>
getCapability
();
kj
::
Own
<
ClientHook
>
getCapability
();
...
@@ -409,6 +369,7 @@ public:
...
@@ -409,6 +369,7 @@ public:
StructReader
getStruct
(
const
word
*
defaultValue
)
const
;
StructReader
getStruct
(
const
word
*
defaultValue
)
const
;
ListReader
getList
(
FieldSize
expectedElementSize
,
const
word
*
defaultValue
)
const
;
ListReader
getList
(
FieldSize
expectedElementSize
,
const
word
*
defaultValue
)
const
;
ListReader
getListAnySize
(
const
word
*
defaultValue
)
const
;
template
<
typename
T
>
template
<
typename
T
>
typename
T
::
Reader
getBlob
(
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
typename
T
::
Reader
getBlob
(
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
#if !CAPNP_LITE
#if !CAPNP_LITE
...
@@ -612,6 +573,8 @@ public:
...
@@ -612,6 +573,8 @@ public:
}
}
}
}
inline
ElementSize
getElementSize
()
const
{
return
elementSize
;
}
inline
ElementCount
size
()
const
;
inline
ElementCount
size
()
const
;
// The number of elements in the list.
// The number of elements in the list.
...
@@ -680,6 +643,8 @@ public:
...
@@ -680,6 +643,8 @@ public:
inline
ElementCount
size
()
const
;
inline
ElementCount
size
()
const
;
// The number of elements in the list.
// The number of elements in the list.
inline
ElementSize
getElementSize
()
const
{
return
elementSize
;
}
Text
::
Reader
asText
();
Text
::
Reader
asText
();
Data
::
Reader
asData
();
Data
::
Reader
asData
();
// Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized.
// Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized.
...
@@ -854,7 +819,9 @@ inline Data::Builder StructBuilder::getDataSectionAsBlob() {
...
@@ -854,7 +819,9 @@ inline Data::Builder StructBuilder::getDataSectionAsBlob() {
}
}
inline
_
::
ListBuilder
StructBuilder
::
getPointerSectionAsList
()
{
inline
_
::
ListBuilder
StructBuilder
::
getPointerSectionAsList
()
{
return
_
::
ListBuilder
(
segment
,
pointers
,
pointerCount
*
BITS_PER_WORD
/
ELEMENTS
,
pointerCount
,
0
,
1
,
FieldSize
::
POINTER
);
return
_
::
ListBuilder
(
segment
,
pointers
,
pointerCount
*
BITS_PER_POINTER
/
ELEMENTS
,
pointerCount
*
(
1
*
ELEMENTS
/
POINTERS
),
0
*
BITS
,
1
*
POINTERS
,
FieldSize
::
POINTER
);
}
}
template
<
typename
T
>
template
<
typename
T
>
...
@@ -936,7 +903,9 @@ inline Data::Reader StructReader::getDataSectionAsBlob() {
...
@@ -936,7 +903,9 @@ inline Data::Reader StructReader::getDataSectionAsBlob() {
}
}
inline
_
::
ListReader
StructReader
::
getPointerSectionAsList
()
{
inline
_
::
ListReader
StructReader
::
getPointerSectionAsList
()
{
return
_
::
ListReader
(
segment
,
pointers
,
pointerCount
,
pointerCount
*
BITS_PER_WORD
/
ELEMENTS
,
0
,
1
,
FieldSize
::
POINTER
,
nestingLimit
);
return
_
::
ListReader
(
segment
,
pointers
,
pointerCount
*
(
1
*
ELEMENTS
/
POINTERS
),
pointerCount
*
BITS_PER_POINTER
/
ELEMENTS
,
0
*
BITS
,
1
*
POINTERS
,
FieldSize
::
POINTER
,
nestingLimit
);
}
}
template
<
typename
T
>
template
<
typename
T
>
...
...
c++/src/capnp/pointer-helpers.h
View file @
9c54bce6
...
@@ -24,7 +24,6 @@
...
@@ -24,7 +24,6 @@
#include "layout.h"
#include "layout.h"
#include "list.h"
#include "list.h"
// #include "any.h"
namespace
capnp
{
namespace
capnp
{
namespace
_
{
// private
namespace
_
{
// private
...
...
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