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
b2edb433
Commit
b2edb433
authored
May 11, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More dynamic API WIP.
parent
18cfa132
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
988 additions
and
175 deletions
+988
-175
arena.h
c++/src/capnproto/arena.h
+3
-0
dynamic.c++
c++/src/capnproto/dynamic.c++
+640
-61
dynamic.h
c++/src/capnproto/dynamic.h
+246
-89
generated-header-support.h
c++/src/capnproto/generated-header-support.h
+3
-1
layout-test.c++
c++/src/capnproto/layout-test.c++
+2
-2
layout.c++
c++/src/capnproto/layout.c++
+6
-6
layout.h
c++/src/capnproto/layout.h
+3
-3
list.h
c++/src/capnproto/list.h
+1
-2
message.c++
c++/src/capnproto/message.c++
+3
-3
message.h
c++/src/capnproto/message.h
+26
-2
schema.capnp
c++/src/capnproto/schema.capnp
+5
-0
WireFormat.hs
compiler/src/WireFormat.hs
+7
-6
c++-header.mustache
compiler/src/c++-header.mustache
+43
-0
No files found.
c++/src/capnproto/arena.h
View file @
b2edb433
...
...
@@ -45,6 +45,9 @@ class ReaderArena;
class
BuilderArena
;
class
ReadLimiter
;
class
Segment
;
typedef
Id
<
uint32_t
,
Segment
>
SegmentId
;
class
ReadLimiter
{
// Used to keep track of how much data has been processed from a message, and cut off further
// processing if and when a particular limit is reached. This is primarily intended to guard
...
...
c++/src/capnproto/dynamic.c++
View file @
b2edb433
...
...
@@ -30,7 +30,7 @@
namespace
capnproto
{
struct
IdTextHash
{
s
tatic
size_t
hash
(
std
::
pair
<
uint64_t
,
Text
::
Reader
>
p
)
{
s
ize_t
operator
()(
std
::
pair
<
uint64_t
,
Text
::
Reader
>
p
)
const
{
// djb2a hash, but seeded with ID.
size_t
result
=
p
.
first
;
int
c
;
...
...
@@ -46,10 +46,10 @@ struct IdTextHash {
struct
SchemaPool
::
Impl
{
std
::
unordered_map
<
uint64_t
,
schema
::
Node
::
Reader
>
nodeMap
;
std
::
unordered_map
<
std
::
pair
<
uint64_t
,
std
::
string
>
,
schema
::
StructNode
::
Member
::
Reader
,
std
::
unordered_map
<
std
::
pair
<
uint64_t
,
Text
::
Reader
>
,
schema
::
StructNode
::
Member
::
Reader
,
IdTextHash
>
memberMap
;
std
::
unordered_map
<
std
::
pair
<
uint64_t
,
std
::
string
>
,
schema
::
EnumNode
::
Enumerant
::
Reader
,
std
::
unordered_map
<
std
::
pair
<
uint64_t
,
Text
::
Reader
>
,
schema
::
EnumNode
::
Enumerant
::
Reader
,
IdTextHash
>
enumerantMap
;
};
...
...
@@ -58,9 +58,10 @@ SchemaPool::~SchemaPool() {
delete
impl
;
}
// TODO(soon): Implement this. Need to copy, ick.
//void add(schema::Node::Reader node) {
//}
// TODO(now): Implement this. Need to copy, ick.
void
add
(
schema
::
Node
::
Reader
node
)
{
FAIL_CHECK
(
"Not implemented: copying/validating schemas."
);
}
void
SchemaPool
::
addNoCopy
(
schema
::
Node
::
Reader
node
)
{
if
(
impl
==
nullptr
)
{
...
...
@@ -82,14 +83,6 @@ bool SchemaPool::has(uint64_t id) const {
return
(
impl
!=
nullptr
&&
impl
->
nodeMap
.
count
(
id
)
!=
0
)
||
(
base
!=
nullptr
&&
base
->
has
(
id
));
}
DynamicStruct
::
Reader
SchemaPool
::
getRoot
(
MessageReader
&
message
,
uint64_t
typeId
)
const
{
}
DynamicStruct
::
Builder
SchemaPool
::
getRoot
(
MessageBuilder
&
message
,
uint64_t
typeId
)
const
{
}
// =======================================================================================
namespace
{
...
...
@@ -127,8 +120,8 @@ inline uint64_t bitCast<uint64_t, double>(double value) {
return
result
;
}
internal
::
FieldSize
elementSizeFor
(
schema
::
Type
::
Reader
elementType
)
{
switch
(
elementType
.
getBody
().
which
()
)
{
internal
::
FieldSize
elementSizeFor
(
schema
::
Type
::
Body
::
Which
elementType
)
{
switch
(
elementType
)
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
return
internal
::
FieldSize
::
VOID
;
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
return
internal
::
FieldSize
::
BIT
;
case
schema
:
:
Type
::
Body
::
INT8_TYPE
:
return
internal
::
FieldSize
::
BYTE
;
...
...
@@ -154,6 +147,13 @@ internal::FieldSize elementSizeFor(schema::Type::Reader elementType) {
return
internal
::
FieldSize
::
VOID
;
}
inline
internal
::
StructSize
structSizeFromSchema
(
schema
::
StructNode
::
Reader
schema
)
{
return
internal
::
StructSize
(
schema
.
getDataSectionWordSize
()
*
WORDS
,
schema
.
getPointerSectionSize
()
*
REFERENCES
,
static_cast
<
internal
::
FieldSize
>
(
schema
.
getPreferredListEncoding
()));
}
}
// namespace
// =======================================================================================
...
...
@@ -180,8 +180,8 @@ Maybe<schema::EnumNode::Enumerant::Reader> DynamicEnum::findEnumerantByName(Text
}
}
uint16_t
DynamicEnum
::
to
Impl
(
uint64_t
requestedTypeId
)
{
VALIDATE_INPUT
(
requestedTypeId
==
schema
.
getId
(),
"Type mismatch in DynamicEnum.
to
()."
)
{
uint16_t
DynamicEnum
::
as
Impl
(
uint64_t
requestedTypeId
)
{
VALIDATE_INPUT
(
requestedTypeId
==
schema
.
getId
(),
"Type mismatch in DynamicEnum.
as
()."
)
{
// Go on with value.
}
return
value
;
...
...
@@ -247,17 +247,9 @@ DynamicList::Builder DynamicObject::Builder::toList(internal::ListSchema schema)
// =======================================================================================
schema
::
StructNode
::
Union
::
Reader
DynamicUnion
::
Reader
::
getSchema
()
{
return
schema
.
getBody
().
getUnionMember
();
}
schema
::
StructNode
::
Union
::
Reader
DynamicUnion
::
Builder
::
getSchema
()
{
return
schema
.
getBody
().
getUnionMember
();
}
Maybe
<
schema
::
StructNode
::
Member
::
Reader
>
DynamicUnion
::
Reader
::
which
()
{
auto
uschema
=
getSchema
();
auto
members
=
uschema
.
getMembers
();
uint16_t
discrim
=
reader
.
getDataField
<
uint32_t
>
(
uschema
.
getDiscriminantOffset
()
*
ELEMENTS
);
auto
members
=
schema
.
getMembers
();
uint16_t
discrim
=
reader
.
getDataField
<
uint32_t
>
(
schema
.
getDiscriminantOffset
()
*
ELEMENTS
);
if
(
discrim
<
members
.
size
())
{
return
members
[
discrim
];
...
...
@@ -266,9 +258,8 @@ Maybe<schema::StructNode::Member::Reader> DynamicUnion::Reader::which() {
}
}
Maybe
<
schema
::
StructNode
::
Member
::
Reader
>
DynamicUnion
::
Builder
::
which
()
{
auto
uschema
=
getSchema
();
auto
members
=
uschema
.
getMembers
();
uint16_t
discrim
=
builder
.
getDataField
<
uint32_t
>
(
uschema
.
getDiscriminantOffset
()
*
ELEMENTS
);
auto
members
=
schema
.
getMembers
();
uint16_t
discrim
=
builder
.
getDataField
<
uint32_t
>
(
schema
.
getDiscriminantOffset
()
*
ELEMENTS
);
if
(
discrim
<
members
.
size
())
{
return
members
[
discrim
];
...
...
@@ -280,7 +271,7 @@ Maybe<schema::StructNode::Member::Reader> DynamicUnion::Builder::which() {
DynamicValue
::
Reader
DynamicUnion
::
Reader
::
get
()
{
auto
w
=
which
();
RECOVERABLE_PRECOND
(
w
!=
nullptr
,
"Can't get() unknown union value."
)
{
return
DynamicValue
::
Reader
(
Void
::
VOID
);
return
DynamicValue
::
Reader
();
}
auto
body
=
w
->
getBody
();
CHECK
(
body
.
which
()
==
schema
::
StructNode
::
Member
::
Body
::
FIELD_MEMBER
,
...
...
@@ -292,7 +283,7 @@ DynamicValue::Reader DynamicUnion::Reader::get() {
DynamicValue
::
Builder
DynamicUnion
::
Builder
::
get
()
{
auto
w
=
which
();
RECOVERABLE_PRECOND
(
w
!=
nullptr
,
"Can't get() unknown union value."
)
{
return
DynamicValue
::
Builder
(
Void
::
VOID
);
return
DynamicValue
::
Builder
();
}
auto
body
=
w
->
getBody
();
CHECK
(
body
.
which
()
==
schema
::
StructNode
::
Member
::
Body
::
FIELD_MEMBER
,
...
...
@@ -303,13 +294,94 @@ DynamicValue::Builder DynamicUnion::Builder::get() {
void
DynamicUnion
::
Builder
::
set
(
schema
::
StructNode
::
Field
::
Reader
field
,
DynamicValue
::
Reader
value
)
{
auto
uschema
=
getSchema
();
builder
.
setDataField
<
uint16_t
>
(
uschema
.
getTagOffset
(),
field
.
getIndex
());
builder
.
setDataField
<
uint16_t
>
(
schema
.
getDiscriminantOffset
()
*
ELEMENTS
,
field
.
getIndex
());
DynamicStruct
::
Builder
::
setFieldImpl
(
pool
,
builder
,
field
,
value
);
}
DynamicValue
::
Builder
DynamicUnion
::
Builder
::
init
(
schema
::
StructNode
::
Field
::
Reader
field
)
{
builder
.
setDataField
<
uint16_t
>
(
schema
.
getDiscriminantOffset
()
*
ELEMENTS
,
field
.
getIndex
());
return
DynamicStruct
::
Builder
::
initFieldImpl
(
pool
,
builder
,
field
);
}
DynamicValue
::
Builder
DynamicUnion
::
Builder
::
init
(
schema
::
StructNode
::
Field
::
Reader
field
,
uint
size
)
{
builder
.
setDataField
<
uint16_t
>
(
schema
.
getDiscriminantOffset
()
*
ELEMENTS
,
field
.
getIndex
());
return
DynamicStruct
::
Builder
::
initFieldImpl
(
pool
,
builder
,
field
,
size
);
}
// =======================================================================================
void
DynamicStruct
::
Reader
::
verifyTypeId
(
uint64_t
id
)
{
VALIDATE_INPUT
(
id
==
schema
.
getId
(),
"Type mismatch when using DynamicStruct::Reader::as()."
)
{
// Go on with bad type ID.
}
}
void
DynamicStruct
::
Builder
::
verifyTypeId
(
uint64_t
id
)
{
VALIDATE_INPUT
(
id
==
schema
.
getId
(),
"Type mismatch when using DynamicStruct::Builder::as()."
)
{
// Go on with bad type ID.
}
}
schema
::
StructNode
::
Reader
DynamicStruct
::
Reader
::
getSchema
()
{
return
schema
.
getBody
().
getStructNode
();
}
schema
::
StructNode
::
Reader
DynamicStruct
::
Builder
::
getSchema
()
{
return
schema
.
getBody
().
getStructNode
();
}
Maybe
<
schema
::
StructNode
::
Member
::
Reader
>
DynamicStruct
::
Reader
::
findMemberByName
(
Text
::
Reader
name
)
{
auto
iter
=
pool
->
impl
->
memberMap
.
find
(
std
::
make_pair
(
schema
.
getId
(),
name
));
if
(
iter
==
pool
->
impl
->
memberMap
.
end
())
{
return
nullptr
;
}
else
{
return
iter
->
second
;
}
}
Maybe
<
schema
::
StructNode
::
Member
::
Reader
>
DynamicStruct
::
Builder
::
findMemberByName
(
Text
::
Reader
name
)
{
auto
iter
=
pool
->
impl
->
memberMap
.
find
(
std
::
make_pair
(
schema
.
getId
(),
name
));
if
(
iter
==
pool
->
impl
->
memberMap
.
end
())
{
return
nullptr
;
}
else
{
return
iter
->
second
;
}
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
initObjectField
(
schema
::
StructNode
::
Field
::
Reader
field
,
schema
::
Type
::
Reader
type
)
{
VALIDATE_INPUT
(
field
.
getType
().
getBody
().
which
()
==
schema
::
Type
::
Body
::
OBJECT_TYPE
,
"Expected an Object. (To dynamically initialize a non-Object field, do not "
"pass an element type to initObjectField().)"
)
{
return
initFieldImpl
(
pool
,
builder
,
field
);
}
return
initFieldImpl
(
pool
,
builder
,
field
,
type
);
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
initObjectField
(
schema
::
StructNode
::
Field
::
Reader
field
,
schema
::
Type
::
Reader
type
,
uint
size
)
{
VALIDATE_INPUT
(
field
.
getType
().
getBody
().
which
()
==
schema
::
Type
::
Body
::
OBJECT_TYPE
,
"Expected an Object. (To dynamically initialize a non-Object field, do not "
"pass a struct schema to initObjectField().)"
)
{
return
initFieldImpl
(
pool
,
builder
,
field
,
size
);
}
return
initFieldImpl
(
pool
,
builder
,
field
,
type
,
size
);
}
DynamicUnion
::
Reader
DynamicStruct
::
Reader
::
getUnion
(
schema
::
StructNode
::
Union
::
Reader
un
)
{
return
DynamicUnion
::
Reader
(
pool
,
un
,
reader
);
}
DynamicUnion
::
Builder
DynamicStruct
::
Builder
::
getUnion
(
schema
::
StructNode
::
Union
::
Reader
un
)
{
return
DynamicUnion
::
Builder
(
pool
,
un
,
builder
);
}
void
DynamicStruct
::
Builder
::
copyFrom
(
Reader
other
)
{
// TODO(now): copyFrom on StructBuilder.
// TODO(now): don't forget to check types match.
FAIL_CHECK
(
"Unimplemented: copyFrom()"
);
}
DynamicValue
::
Reader
DynamicStruct
::
Reader
::
getFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructReader
reader
,
schema
::
StructNode
::
Field
::
Reader
field
)
{
...
...
@@ -367,7 +439,7 @@ DynamicValue::Reader DynamicStruct::Reader::getFieldImpl(
return
DynamicValue
::
Reader
(
DynamicList
::
Reader
(
pool
,
elementType
,
reader
.
getListField
(
field
.
getOffset
()
*
REFERENCES
,
elementSizeFor
(
elementType
),
elementSizeFor
(
elementType
.
getBody
().
which
()
),
dval
.
getListValue
<
internal
::
TrustedMessage
>
())));
}
...
...
@@ -389,7 +461,7 @@ DynamicValue::Reader DynamicStruct::Reader::getFieldImpl(
break
;
}
FAIL_CHECK
(
"
Can't get here."
);
FAIL_CHECK
(
"
switch() missing case."
,
type
.
which
()
);
return
DynamicValue
::
Reader
();
}
...
...
@@ -478,7 +550,7 @@ DynamicValue::Builder DynamicStruct::Builder::getFieldImpl(
break
;
}
FAIL_CHECK
(
"
Can't get here."
);
FAIL_CHECK
(
"
switch() missing case."
,
type
.
which
()
);
return
DynamicValue
::
Builder
();
}
...
...
@@ -490,13 +562,13 @@ void DynamicStruct::Builder::setFieldImpl(
switch
(
type
.
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
builder
.
setDataField
<
Void
>
(
field
.
getOffset
()
*
ELEMENTS
,
value
.
to
<
Void
>
());
builder
.
setDataField
<
Void
>
(
field
.
getOffset
()
*
ELEMENTS
,
value
.
as
<
Void
>
());
break
;
#define HANDLE_TYPE(discrim, titleCase, type) \
case schema::Type::Body::discrim##_TYPE: \
builder.setDataField<type>( \
field.getOffset() * ELEMENTS, value.
to
<type>(), \
field.getOffset() * ELEMENTS, value.
as
<type>(), \
bitCast<internal::Mask<type> >(dval.get##titleCase##Value()));
break
;
...
...
@@ -516,35 +588,35 @@ void DynamicStruct::Builder::setFieldImpl(
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
builder
.
setDataField
<
uint16_t
>
(
field
.
getOffset
()
*
ELEMENTS
,
value
.
to
<
DynamicEnum
>
().
getRaw
(),
field
.
getOffset
()
*
ELEMENTS
,
value
.
as
<
DynamicEnum
>
().
getRaw
(),
dval
.
getEnumValue
());
break
;
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
builder
.
setBlobField
<
Text
>
(
field
.
getOffset
()
*
REFERENCES
,
value
.
to
<
Text
>
());
builder
.
setBlobField
<
Text
>
(
field
.
getOffset
()
*
REFERENCES
,
value
.
as
<
Text
>
());
break
;
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
builder
.
setBlobField
<
Data
>
(
field
.
getOffset
()
*
REFERENCES
,
value
.
to
<
Data
>
());
builder
.
setBlobField
<
Data
>
(
field
.
getOffset
()
*
REFERENCES
,
value
.
as
<
Data
>
());
break
;
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
{
// TODO(
soon
): We need to do a schemaless copy to avoid losing information if the values are
// TODO(
now
): We need to do a schemaless copy to avoid losing information if the values are
// larger than what the schema defines.
auto
listValue
=
value
.
to
<
DynamicList
>
();
init
ListFieldImpl
(
pool
,
builder
,
field
,
listValue
.
size
()
).
copyFrom
(
listValue
);
auto
listValue
=
value
.
as
<
DynamicList
>
();
init
FieldImpl
(
pool
,
builder
,
field
,
listValue
.
size
()).
as
<
DynamicList
>
(
).
copyFrom
(
listValue
);
break
;
}
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
{
// TODO(
soon
): We need to do a schemaless copy to avoid losing information if the values are
// TODO(
now
): We need to do a schemaless copy to avoid losing information if the values are
// larger than what the schema defines.
init
StructFieldImpl
(
pool
,
builder
,
field
).
copyFrom
(
value
.
to
<
DynamicStruct
>
());
init
FieldImpl
(
pool
,
builder
,
field
).
as
<
DynamicStruct
>
().
copyFrom
(
value
.
as
<
DynamicStruct
>
());
break
;
}
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
{
// TODO(
soon
): Perform schemaless copy.
// TODO(
now
): Perform schemaless copy.
FAIL_CHECK
(
"TODO"
);
break
;
}
...
...
@@ -555,21 +627,447 @@ void DynamicStruct::Builder::setFieldImpl(
}
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
initFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
,
uint
size
)
{
return
initFieldImpl
(
pool
,
builder
,
field
,
field
.
getType
(),
size
);
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
initFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
)
{
return
initFieldImpl
(
pool
,
builder
,
field
,
field
.
getType
());
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
initFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
,
schema
::
Type
::
Reader
type
,
uint
size
)
{
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
case
schema
:
:
Type
::
Body
::
INT8_TYPE
:
case
schema
:
:
Type
::
Body
::
INT16_TYPE
:
case
schema
:
:
Type
::
Body
::
INT32_TYPE
:
case
schema
:
:
Type
::
Body
::
INT64_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT8_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT16_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT32_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT64_TYPE
:
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
FAIL_VALIDATE_INPUT
(
"Expected a list or blob."
);
return
getFieldImpl
(
pool
,
builder
,
field
);
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
return
DynamicValue
::
Builder
(
builder
.
initBlobField
<
Text
>
(
field
.
getOffset
()
*
REFERENCES
,
size
*
BYTES
));
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
return
DynamicValue
::
Builder
(
builder
.
initBlobField
<
Data
>
(
field
.
getOffset
()
*
REFERENCES
,
size
*
BYTES
));
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
{
auto
elementType
=
type
.
getBody
().
getListType
();
if
(
elementType
.
getBody
().
which
()
==
schema
::
Type
::
Body
::
STRUCT_TYPE
)
{
auto
structType
=
pool
->
getStruct
(
elementType
.
getBody
().
getStructType
());
return
DynamicValue
::
Builder
(
DynamicList
::
Builder
(
pool
,
schema
::
Type
::
Body
::
STRUCT_TYPE
,
0
,
structType
,
builder
.
initStructListField
(
field
.
getOffset
()
*
REFERENCES
,
size
*
ELEMENTS
,
structSizeFromSchema
(
structType
.
getBody
().
getStructNode
()))));
}
else
{
return
DynamicValue
::
Builder
(
DynamicList
::
Builder
(
pool
,
elementType
,
builder
.
initListField
(
field
.
getOffset
()
*
REFERENCES
,
elementSizeFor
(
elementType
.
getBody
().
which
()),
size
*
ELEMENTS
)));
}
}
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
{
FAIL_VALIDATE_INPUT
(
"Expected a list or blob, but found Object. (To dynamically initialize an object "
"field, you must pass an element type to initField().)"
);
return
DynamicValue
::
Builder
();
}
}
FAIL_CHECK
(
"switch() missing case."
,
type
.
getBody
().
which
());
return
DynamicValue
::
Builder
();
}
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
initFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
,
schema
::
Type
::
Reader
type
)
{
switch
(
type
.
getBody
().
which
())
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
case
schema
:
:
Type
::
Body
::
INT8_TYPE
:
case
schema
:
:
Type
::
Body
::
INT16_TYPE
:
case
schema
:
:
Type
::
Body
::
INT32_TYPE
:
case
schema
:
:
Type
::
Body
::
INT64_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT8_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT16_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT32_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT64_TYPE
:
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
FAIL_VALIDATE_INPUT
(
"Expected a list or blob."
);
return
getFieldImpl
(
pool
,
builder
,
field
);
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
{
auto
structType
=
pool
->
getStruct
(
type
.
getBody
().
getStructType
());
return
DynamicValue
::
Builder
(
DynamicStruct
::
Builder
(
pool
,
structType
,
builder
.
initStructField
(
field
.
getOffset
()
*
REFERENCES
,
structSizeFromSchema
(
structType
.
getBody
().
getStructNode
()))));
}
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
{
FAIL_VALIDATE_INPUT
(
"Expected a struct, but found Object. (To dynamically initialize an object "
"field, you must pass an element type to initField().)"
);
return
DynamicValue
::
Builder
();
}
}
FAIL_CHECK
(
"switch() missing case."
,
type
.
getBody
().
which
());
return
DynamicValue
::
Builder
();
}
// =======================================================================================
DynamicValue
::
Reader
DynamicList
::
Reader
::
operator
[](
uint
index
)
{
PRECOND
(
index
<
size
(),
"List index out-of-bounds."
);
if
(
depth
==
0
)
{
switch
(
elementType
)
{
#define HANDLE_TYPE(name, discrim, typeName) \
case schema::Type::Body::discrim##_TYPE: \
return DynamicValue::Reader(reader.getDataElement<typeName>(index * ELEMENTS));
HANDLE_TYPE
(
void
,
VOID
,
Void
)
HANDLE_TYPE
(
bool
,
BOOL
,
bool
)
HANDLE_TYPE
(
int8
,
INT8
,
int8_t
)
HANDLE_TYPE
(
int16
,
INT16
,
int16_t
)
HANDLE_TYPE
(
int32
,
INT32
,
int32_t
)
HANDLE_TYPE
(
int64
,
INT64
,
int64_t
)
HANDLE_TYPE
(
uint8
,
UINT8
,
uint8_t
)
HANDLE_TYPE
(
uint16
,
UINT16
,
uint16_t
)
HANDLE_TYPE
(
uint32
,
UINT32
,
uint32_t
)
HANDLE_TYPE
(
uint64
,
UINT64
,
uint64_t
)
HANDLE_TYPE
(
float32
,
FLOAT32
,
float
)
HANDLE_TYPE
(
float64
,
FLOAT64
,
double
)
#undef HANDLE_TYPE
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
return
DynamicValue
::
Reader
(
reader
.
getBlobElement
<
Text
>
(
index
*
ELEMENTS
));
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
return
DynamicValue
::
Reader
(
reader
.
getBlobElement
<
Data
>
(
index
*
ELEMENTS
));
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
FAIL_CHECK
(
"elementType should not be LIST_TYPE when depth == 0."
);
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
return
DynamicValue
::
Reader
(
DynamicStruct
::
Reader
(
pool
,
elementSchema
,
reader
.
getStructElement
(
index
*
ELEMENTS
)));
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
return
DynamicValue
::
Reader
(
DynamicEnum
(
pool
,
elementSchema
,
reader
.
getDataElement
<
uint16_t
>
(
index
*
ELEMENTS
)));
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
return
DynamicValue
::
Reader
(
DynamicObject
::
Reader
(
pool
,
reader
.
getObjectElement
(
index
*
ELEMENTS
)));
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
FAIL_RECOVERABLE_CHECK
(
"Interfaces not implemented."
)
{}
return
DynamicValue
::
Reader
();
}
FAIL_CHECK
(
"switch() missing case."
,
elementType
);
return
DynamicValue
::
Reader
();
}
else
{
// List of lists.
return
DynamicValue
::
Reader
(
DynamicList
::
Reader
(
pool
,
elementType
,
depth
-
1
,
elementSchema
,
reader
.
getListElement
(
index
*
ELEMENTS
,
depth
==
1
?
elementSizeFor
(
elementType
)
:
internal
::
FieldSize
::
REFERENCE
)));
}
}
DynamicValue
::
Builder
DynamicList
::
Builder
::
operator
[](
uint
index
)
{
PRECOND
(
index
<
size
(),
"List index out-of-bounds."
);
if
(
depth
==
0
)
{
switch
(
elementType
)
{
#define HANDLE_TYPE(name, discrim, typeName) \
case schema::Type::Body::discrim##_TYPE: \
return DynamicValue::Builder(builder.getDataElement<typeName>(index * ELEMENTS));
HANDLE_TYPE
(
void
,
VOID
,
Void
)
HANDLE_TYPE
(
bool
,
BOOL
,
bool
)
HANDLE_TYPE
(
int8
,
INT8
,
int8_t
)
HANDLE_TYPE
(
int16
,
INT16
,
int16_t
)
HANDLE_TYPE
(
int32
,
INT32
,
int32_t
)
HANDLE_TYPE
(
int64
,
INT64
,
int64_t
)
HANDLE_TYPE
(
uint8
,
UINT8
,
uint8_t
)
HANDLE_TYPE
(
uint16
,
UINT16
,
uint16_t
)
HANDLE_TYPE
(
uint32
,
UINT32
,
uint32_t
)
HANDLE_TYPE
(
uint64
,
UINT64
,
uint64_t
)
HANDLE_TYPE
(
float32
,
FLOAT32
,
float
)
HANDLE_TYPE
(
float64
,
FLOAT64
,
double
)
#undef HANDLE_TYPE
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
return
DynamicValue
::
Builder
(
builder
.
getBlobElement
<
Text
>
(
index
*
ELEMENTS
));
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
return
DynamicValue
::
Builder
(
builder
.
getBlobElement
<
Data
>
(
index
*
ELEMENTS
));
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
FAIL_CHECK
(
"elementType should not be LIST_TYPE when depth == 0."
);
return
DynamicValue
::
Builder
();
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
return
DynamicValue
::
Builder
(
DynamicStruct
::
Builder
(
pool
,
elementSchema
,
builder
.
getStructElement
(
index
*
ELEMENTS
)));
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
return
DynamicValue
::
Builder
(
DynamicEnum
(
pool
,
elementSchema
,
builder
.
getDataElement
<
uint16_t
>
(
index
*
ELEMENTS
)));
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
FAIL_CHECK
(
"List(Object) not supported."
);
break
;
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
FAIL_RECOVERABLE_CHECK
(
"Interfaces not implemented."
)
{}
return
DynamicValue
::
Builder
();
}
FAIL_CHECK
(
"switch() missing case."
,
elementType
);
return
DynamicValue
::
Builder
();
}
else
{
// List of lists.
return
DynamicValue
::
Builder
(
DynamicList
::
Builder
(
pool
,
elementType
,
depth
-
1
,
elementSchema
,
builder
.
getListElement
(
index
*
ELEMENTS
)));
}
}
void
DynamicList
::
Builder
::
set
(
uint
index
,
DynamicValue
::
Reader
value
)
{
PRECOND
(
index
<
size
(),
"List index out-of-bounds."
);
if
(
depth
==
0
)
{
switch
(
elementType
)
{
#define HANDLE_TYPE(name, discrim, typeName) \
case schema::Type::Body::discrim##_TYPE: \
builder.setDataElement<typeName>(index * ELEMENTS, value.as<typeName>()); \
break;
HANDLE_TYPE
(
void
,
VOID
,
Void
)
HANDLE_TYPE
(
bool
,
BOOL
,
bool
)
HANDLE_TYPE
(
int8
,
INT8
,
int8_t
)
HANDLE_TYPE
(
int16
,
INT16
,
int16_t
)
HANDLE_TYPE
(
int32
,
INT32
,
int32_t
)
HANDLE_TYPE
(
int64
,
INT64
,
int64_t
)
HANDLE_TYPE
(
uint8
,
UINT8
,
uint8_t
)
HANDLE_TYPE
(
uint16
,
UINT16
,
uint16_t
)
HANDLE_TYPE
(
uint32
,
UINT32
,
uint32_t
)
HANDLE_TYPE
(
uint64
,
UINT64
,
uint64_t
)
HANDLE_TYPE
(
float32
,
FLOAT32
,
float
)
HANDLE_TYPE
(
float64
,
FLOAT64
,
double
)
#undef HANDLE_TYPE
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
builder
.
setBlobElement
<
Text
>
(
index
*
ELEMENTS
,
value
.
as
<
Text
>
());
break
;
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
builder
.
setBlobElement
<
Data
>
(
index
*
ELEMENTS
,
value
.
as
<
Data
>
());
break
;
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
FAIL_CHECK
(
"elementType should not be LIST_TYPE when depth == 0."
);
break
;
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
// Note we can't do a schemaless copy here because the space is already allocated.
DynamicStruct
::
Builder
(
pool
,
elementSchema
,
builder
.
getStructElement
(
index
*
ELEMENTS
))
.
copyFrom
(
value
.
as
<
DynamicStruct
>
());
break
;
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
{
auto
enumValue
=
value
.
as
<
DynamicEnum
>
();
VALIDATE_INPUT
(
elementSchema
.
getId
()
==
enumValue
.
getSchemaNode
().
getId
(),
"Type mismatch when using DynamicList::Builder::set()."
);
builder
.
setDataElement
<
uint16_t
>
(
index
*
ELEMENTS
,
value
.
as
<
DynamicEnum
>
().
getRaw
());
break
;
}
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
FAIL_CHECK
(
"List(Object) not supported."
);
break
;
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
FAIL_RECOVERABLE_CHECK
(
"Interfaces not implemented."
)
{}
break
;
}
}
else
{
// List of lists.
// TODO(now): Perform schemaless copy.
auto
listValue
=
value
.
as
<
DynamicList
>
();
init
(
index
,
listValue
.
size
()).
as
<
DynamicList
>
().
copyFrom
(
listValue
);
}
}
DynamicValue
::
Builder
DynamicList
::
Builder
::
init
(
uint
index
,
uint
size
)
{
PRECOND
(
index
<
this
->
size
(),
"List index out-of-bounds."
);
if
(
depth
==
0
)
{
switch
(
elementType
)
{
case
schema
:
:
Type
::
Body
::
VOID_TYPE
:
case
schema
:
:
Type
::
Body
::
BOOL_TYPE
:
case
schema
:
:
Type
::
Body
::
INT8_TYPE
:
case
schema
:
:
Type
::
Body
::
INT16_TYPE
:
case
schema
:
:
Type
::
Body
::
INT32_TYPE
:
case
schema
:
:
Type
::
Body
::
INT64_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT8_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT16_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT32_TYPE
:
case
schema
:
:
Type
::
Body
::
UINT64_TYPE
:
case
schema
:
:
Type
::
Body
::
FLOAT32_TYPE
:
case
schema
:
:
Type
::
Body
::
FLOAT64_TYPE
:
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
FAIL_VALIDATE_INPUT
(
"Expected a list or blob."
);
return
DynamicValue
::
Builder
();
case
schema
:
:
Type
::
Body
::
TEXT_TYPE
:
return
DynamicValue
::
Builder
(
builder
.
initBlobElement
<
Text
>
(
index
*
ELEMENTS
,
size
*
BYTES
));
case
schema
:
:
Type
::
Body
::
DATA_TYPE
:
return
DynamicValue
::
Builder
(
builder
.
initBlobElement
<
Data
>
(
index
*
ELEMENTS
,
size
*
BYTES
));
case
schema
:
:
Type
::
Body
::
LIST_TYPE
:
FAIL_CHECK
(
"elementType should not be LIST_TYPE when depth == 0."
);
return
DynamicValue
::
Builder
();
case
schema
:
:
Type
::
Body
::
OBJECT_TYPE
:
{
FAIL_CHECK
(
"List(Object) not supported."
);
return
DynamicValue
::
Builder
();
}
}
FAIL_CHECK
(
"switch() missing case."
,
elementType
);
return
DynamicValue
::
Builder
();
}
else
{
// List of lists.
internal
::
FieldSize
elementSize
=
depth
==
1
?
elementSizeFor
(
elementType
)
:
internal
::
FieldSize
::
REFERENCE
;
if
(
elementSize
==
internal
::
FieldSize
::
INLINE_COMPOSITE
)
{
return
DynamicValue
::
Builder
(
DynamicList
::
Builder
(
pool
,
elementType
,
depth
-
1
,
elementSchema
,
builder
.
initStructListElement
(
index
*
ELEMENTS
,
size
*
ELEMENTS
,
structSizeFromSchema
(
elementSchema
.
getBody
().
getStructNode
()))));
}
else
{
return
DynamicValue
::
Builder
(
DynamicList
::
Builder
(
pool
,
elementType
,
depth
-
1
,
elementSchema
,
builder
.
initListElement
(
index
*
ELEMENTS
,
elementSizeFor
(
elementType
),
size
*
ELEMENTS
)));
}
}
}
void
DynamicList
::
Builder
::
copyFrom
(
Reader
other
)
{
// TODO(now): copyFrom on ListBuilder.
// TODO(now): don't forget to check types match.
FAIL_CHECK
(
"Unimplemented: copyFrom()"
);
}
DynamicList
::
Reader
DynamicList
::
Builder
::
asReader
()
{
return
DynamicList
::
Reader
(
pool
,
elementType
,
depth
,
elementSchema
,
builder
.
asReader
());
}
DynamicList
::
Reader
::
Reader
(
const
SchemaPool
*
pool
,
schema
::
Type
::
Reader
elementType
,
internal
::
ListReader
reader
)
:
Reader
(
pool
,
internal
::
ListSchema
(
elementType
),
reader
)
{}
DynamicList
::
Reader
::
Reader
(
const
SchemaPool
*
pool
,
internal
::
ListSchema
schema
,
internal
::
ListReader
reader
)
:
pool
(
pool
),
elementType
(
schema
.
elementType
),
depth
(
schema
.
nestingDepth
),
reader
(
reader
)
{
switch
(
elementType
)
{
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
elementSchema
=
pool
->
getEnum
(
schema
.
elementTypeId
);
break
;
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
elementSchema
=
pool
->
getStruct
(
schema
.
elementTypeId
);
break
;
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
elementSchema
=
pool
->
getInterface
(
schema
.
elementTypeId
);
break
;
default
:
// Leave schema default-initialized.
break
;
}
}
DynamicList
::
Builder
::
Builder
(
const
SchemaPool
*
pool
,
schema
::
Type
::
Reader
elementType
,
internal
::
ListBuilder
builder
)
:
Builder
(
pool
,
internal
::
ListSchema
(
elementType
),
builder
)
{}
DynamicList
::
Builder
::
Builder
(
const
SchemaPool
*
pool
,
internal
::
ListSchema
schema
,
internal
::
ListBuilder
builder
)
:
pool
(
pool
),
elementType
(
schema
.
elementType
),
depth
(
schema
.
nestingDepth
),
builder
(
builder
)
{
switch
(
elementType
)
{
case
schema
:
:
Type
::
Body
::
ENUM_TYPE
:
elementSchema
=
pool
->
getEnum
(
schema
.
elementTypeId
);
break
;
case
schema
:
:
Type
::
Body
::
STRUCT_TYPE
:
elementSchema
=
pool
->
getStruct
(
schema
.
elementTypeId
);
break
;
case
schema
:
:
Type
::
Body
::
INTERFACE_TYPE
:
elementSchema
=
pool
->
getInterface
(
schema
.
elementTypeId
);
break
;
default
:
// Leave schema default-initialized.
break
;
}
}
void
DynamicList
::
Reader
::
verifySchema
(
internal
::
ListSchema
schema
)
{
VALIDATE_INPUT
(
schema
.
elementType
==
elementType
&&
schema
.
nestingDepth
==
depth
&&
schema
.
elementTypeId
==
elementSchema
.
getId
(),
"Type mismatch when using DynamicList::Reader::as()."
);
}
void
DynamicList
::
Builder
::
verifySchema
(
internal
::
ListSchema
schema
)
{
VALIDATE_INPUT
(
schema
.
elementType
==
elementType
&&
schema
.
nestingDepth
==
depth
&&
schema
.
elementTypeId
==
elementSchema
.
getId
(),
"Type mismatch when using DynamicList::Reader::as()."
);
}
// =======================================================================================
#if 0
#define HANDLE_TYPE(name, discrim, typeName) \
ReaderFor<typeName> DynamicValue::Reader::
To
Impl<typeName>::apply(Reader reader) { \
ReaderFor<typeName> DynamicValue::Reader::
as
Impl<typeName>::apply(Reader reader) { \
VALIDATE_INPUT(reader.type == schema::Type::Body::discrim##_TYPE, \
"Type mismatch when using DynamicValue::
to
().") { \
return
typeName
(); \
"Type mismatch when using DynamicValue::
Reader::as
().") { \
return
ReaderFor<typeName>
(); \
} \
return reader.name##Value; \
} \
BuilderFor<typeName> DynamicValue::Builder::
To
Impl<typeName>::apply(Builder builder) { \
BuilderFor<typeName> DynamicValue::Builder::
as
Impl<typeName>::apply(Builder builder) { \
VALIDATE_INPUT(builder.type == schema::Type::Body::discrim##_TYPE, \
"Type mismatch when using DynamicValue::
to
().") { \
return
typeName
(); \
"Type mismatch when using DynamicValue::
Builder::as
().") { \
return
BuilderFor<typeName>
(); \
} \
return builder.name##Value; \
}
...
...
@@ -595,22 +1093,103 @@ HANDLE_TYPE(enum, ENUM, DynamicEnum)
HANDLE_TYPE
(
object
,
OBJECT
,
DynamicObject
)
#undef HANDLE_TYPE
#endif
// As in the header, HANDLE_TYPE(void, VOID, Void) crashes GCC 4.7.
Void
DynamicValue
::
Reader
::
To
Impl
<
Void
>::
apply
(
Reader
reader
)
{
Void
DynamicValue
::
Reader
::
as
Impl
<
Void
>::
apply
(
Reader
reader
)
{
VALIDATE_INPUT
(
reader
.
type
==
schema
::
Type
::
Body
::
VOID_TYPE
,
"Type mismatch when using DynamicValue::
to
()."
)
{
"Type mismatch when using DynamicValue::
Reader::as
()."
)
{
return
Void
();
}
return
reader
.
voidValue
;
}
Void
DynamicValue
::
Builder
::
To
Impl
<
Void
>::
apply
(
Builder
builder
)
{
Void
DynamicValue
::
Builder
::
as
Impl
<
Void
>::
apply
(
Builder
builder
)
{
VALIDATE_INPUT
(
builder
.
type
==
schema
::
Type
::
Body
::
VOID_TYPE
,
"Type mismatch when using DynamicValue::
to
()."
)
{
"Type mismatch when using DynamicValue::
Builder::as
()."
)
{
return
Void
();
}
return
builder
.
voidValue
;
}
// =======================================================================================
template
<>
DynamicStruct
::
Reader
MessageReader
::
getRoot
<
DynamicStruct
>
(
const
SchemaPool
&
pool
,
uint64_t
typeId
)
{
return
DynamicStruct
::
Reader
(
&
pool
,
pool
.
getStruct
(
typeId
),
getRootInternal
());
}
template
<>
DynamicStruct
::
Builder
MessageBuilder
::
initRoot
<
DynamicStruct
>
(
const
SchemaPool
&
pool
,
uint64_t
typeId
)
{
auto
schema
=
pool
.
getStruct
(
typeId
);
return
DynamicStruct
::
Builder
(
&
pool
,
schema
,
initRoot
(
structSizeFromSchema
(
schema
.
getBody
().
getStructNode
())));
}
template
<>
DynamicStruct
::
Builder
MessageBuilder
::
getRoot
<
DynamicStruct
>
(
const
SchemaPool
&
pool
,
uint64_t
typeId
)
{
auto
schema
=
pool
.
getStruct
(
typeId
);
return
DynamicStruct
::
Builder
(
&
pool
,
schema
,
getRoot
(
structSizeFromSchema
(
schema
.
getBody
().
getStructNode
())));
}
namespace
internal
{
DynamicStruct
::
Reader
PointerHelpers
<
DynamicStruct
,
Kind
::
UNKNOWN
>::
get
(
StructReader
reader
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
uint64_t
typeId
)
{
return
DynamicStruct
::
Reader
(
&
pool
,
pool
.
getStruct
(
typeId
),
reader
.
getStructField
(
index
,
nullptr
));
}
DynamicStruct
::
Builder
PointerHelpers
<
DynamicStruct
,
Kind
::
UNKNOWN
>::
get
(
StructBuilder
builder
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
uint64_t
typeId
)
{
auto
schema
=
pool
.
getStruct
(
typeId
);
return
DynamicStruct
::
Builder
(
&
pool
,
schema
,
builder
.
getStructField
(
index
,
structSizeFromSchema
(
schema
.
getBody
().
getStructNode
()),
nullptr
));
}
void
PointerHelpers
<
DynamicStruct
,
Kind
::
UNKNOWN
>::
set
(
StructBuilder
builder
,
WireReferenceCount
index
,
DynamicStruct
::
Reader
value
)
{
// TODO(now): schemaless copy
FAIL_CHECK
(
"Unimplemented: copyFrom()"
);
}
DynamicStruct
::
Builder
PointerHelpers
<
DynamicStruct
,
Kind
::
UNKNOWN
>::
init
(
StructBuilder
builder
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
uint64_t
typeId
)
{
auto
schema
=
pool
.
getStruct
(
typeId
);
return
DynamicStruct
::
Builder
(
&
pool
,
schema
,
builder
.
initStructField
(
index
,
structSizeFromSchema
(
schema
.
getBody
().
getStructNode
())));
}
DynamicList
::
Reader
PointerHelpers
<
DynamicList
,
Kind
::
UNKNOWN
>::
get
(
StructReader
reader
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
schema
::
Type
::
Reader
elementType
)
{
return
DynamicList
::
Reader
(
&
pool
,
elementType
,
reader
.
getListField
(
index
,
elementSizeFor
(
elementType
.
getBody
().
which
()),
nullptr
));
}
DynamicList
::
Builder
PointerHelpers
<
DynamicList
,
Kind
::
UNKNOWN
>::
get
(
StructBuilder
builder
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
schema
::
Type
::
Reader
elementType
)
{
return
DynamicList
::
Builder
(
&
pool
,
elementType
,
builder
.
getListField
(
index
,
nullptr
));
}
void
PointerHelpers
<
DynamicList
,
Kind
::
UNKNOWN
>::
set
(
StructBuilder
builder
,
WireReferenceCount
index
,
DynamicList
::
Reader
value
)
{
// TODO(now): schemaless copy
FAIL_CHECK
(
"Unimplemented: copyFrom()"
);
}
DynamicList
::
Builder
PointerHelpers
<
DynamicList
,
Kind
::
UNKNOWN
>::
init
(
StructBuilder
builder
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
schema
::
Type
::
Reader
elementType
,
uint
size
)
{
auto
elementSize
=
elementSizeFor
(
elementType
.
getBody
().
which
());
if
(
elementSize
==
FieldSize
::
INLINE_COMPOSITE
)
{
auto
elementSchema
=
pool
.
getStruct
(
elementType
.
getBody
().
getStructType
());
return
DynamicList
::
Builder
(
&
pool
,
schema
::
Type
::
Body
::
STRUCT_TYPE
,
0
,
elementSchema
,
builder
.
initStructListField
(
index
,
size
*
ELEMENTS
,
structSizeFromSchema
(
elementSchema
.
getBody
().
getStructNode
())));
}
else
{
return
DynamicList
::
Builder
(
&
pool
,
elementType
,
builder
.
initListField
(
index
,
elementSize
,
size
*
ELEMENTS
));
}
}
}
// namespace internal
}
// namespace capnproto
c++/src/capnproto/dynamic.h
View file @
b2edb433
...
...
@@ -37,6 +37,7 @@
#include "schema.capnp.h"
#include "layout.h"
#include "message.h"
namespace
capnproto
{
...
...
@@ -111,8 +112,13 @@ public:
template
<
typename
T
>
DynamicList
::
Reader
fromListReader
(
T
&&
reader
);
template
<
typename
T
>
DynamicList
::
Builder
fromListBuilder
(
T
&&
builder
);
DynamicStruct
::
Reader
getRoot
(
MessageReader
&
message
,
uint64_t
typeId
)
const
;
DynamicStruct
::
Builder
getRoot
(
MessageBuilder
&
message
,
uint64_t
typeId
)
const
;
schema
::
Node
::
Reader
getNode
(
uint64_t
id
)
const
;
// Look up the node with the given ID, throwing an exception if not found.
schema
::
Node
::
Reader
getStruct
(
uint64_t
id
)
const
;
schema
::
Node
::
Reader
getEnum
(
uint64_t
id
)
const
;
schema
::
Node
::
Reader
getInterface
(
uint64_t
id
)
const
;
// Like getNode() but also throws if the kind is not as requested.
private
:
struct
Impl
;
...
...
@@ -124,14 +130,10 @@ private:
void
addNoCopy
(
schema
::
Node
::
Reader
node
);
schema
::
Node
::
Reader
getStruct
(
uint64_t
id
)
const
;
schema
::
Node
::
Reader
getEnum
(
uint64_t
id
)
const
;
schema
::
Node
::
Reader
getInterface
(
uint64_t
id
)
const
;
friend
class
DynamicEnum
;
friend
class
DynamicStruct
;
friend
class
DynamicList
;
friend
class
DynamicObject
;
friend
struct
DynamicStruct
;
friend
struct
DynamicList
;
friend
struct
DynamicObject
;
};
// -------------------------------------------------------------------
...
...
@@ -163,11 +165,11 @@ struct ListSchema {
};
template
<
typename
ElementType
,
Kind
kind
=
kind
<
ElementType
>
()
>
struct
ListSchemaFor
;
struct
ListSchemaFor
Element
;
#define CAPNPROTO_DECLARE_TYPE(discrim, typeName) \
template <> \
struct ListSchemaFor<List<typeName>> { \
struct ListSchemaFor
Element
<List<typeName>> { \
static constexpr ListSchema type = ListSchema(schema::Type::Body::discrim##_TYPE); \
};
...
...
@@ -191,23 +193,28 @@ CAPNPROTO_DECLARE_TYPE(LIST, DynamicList)
#undef CAPNPROTO_DECLARE_TYPE
template
<
typename
T
>
struct
ListSchemaFor
<
T
,
Kind
::
ENUM
>
{
struct
ListSchemaFor
Element
<
T
,
Kind
::
ENUM
>
{
static
constexpr
ListSchema
type
=
ListSchema
(
schema
::
Type
::
Body
::
ENUM_TYPE
,
typeId
<
T
>
());
};
template
<
typename
T
>
struct
ListSchemaFor
<
T
,
Kind
::
STRUCT
>
{
struct
ListSchemaFor
Element
<
T
,
Kind
::
STRUCT
>
{
static
constexpr
ListSchema
type
=
ListSchema
(
schema
::
Type
::
Body
::
STRUCT_TYPE
,
typeId
<
T
>
());
};
template
<
typename
T
>
struct
ListSchemaFor
<
T
,
Kind
::
INTERFACE
>
{
struct
ListSchemaFor
Element
<
T
,
Kind
::
INTERFACE
>
{
static
constexpr
ListSchema
type
=
ListSchema
(
schema
::
Type
::
Body
::
INTERFACE_TYPE
,
typeId
<
T
>
());
};
template
<
typename
T
>
struct
ListSchemaFor
<
List
<
T
>
,
Kind
::
LIST
>
{
static
constexpr
ListSchema
type
=
ListSchemaFor
<
T
>::
schema
.
deeper
();
struct
ListSchemaFor
Element
<
List
<
T
>
,
Kind
::
LIST
>
{
static
constexpr
ListSchema
type
=
ListSchemaFor
Element
<
T
>::
schema
.
deeper
();
};
template
<
typename
T
>
struct
ListSchemaFor
;
template
<
typename
T
>
struct
ListSchemaFor
<
List
<
T
>>:
public
ListSchemaForElement
<
T
>
{};
}
// namespace internal
// -------------------------------------------------------------------
...
...
@@ -217,7 +224,7 @@ public:
DynamicEnum
()
=
default
;
template
<
typename
T
>
inline
T
to
()
{
return
static_cast
<
T
>
(
to
Impl
(
typeId
<
T
>
()));
}
inline
T
as
()
{
return
static_cast
<
T
>
(
as
Impl
(
typeId
<
T
>
()));
}
// Cast to a native enum type.
schema
::
Node
::
Reader
getSchemaNode
()
{
return
schema
;
}
...
...
@@ -242,9 +249,10 @@ private:
inline
DynamicEnum
(
const
SchemaPool
*
pool
,
schema
::
Node
::
Reader
schema
,
uint16_t
value
)
:
pool
(
pool
),
schema
(
schema
),
value
(
value
)
{}
uint16_t
to
Impl
(
uint64_t
requestedTypeId
);
uint16_t
as
Impl
(
uint64_t
requestedTypeId
);
friend
struct
DynamicStruct
;
friend
struct
DynamicList
;
};
// -------------------------------------------------------------------
...
...
@@ -254,7 +262,7 @@ public:
Reader
()
=
default
;
template
<
typename
T
>
inline
typename
T
::
Reader
to
()
{
return
To
Impl
<
T
>::
apply
(
*
this
);
}
inline
typename
T
::
Reader
as
()
{
return
as
Impl
<
T
>::
apply
(
*
this
);
}
// Convert the object to the given struct, list, or blob type.
DynamicStruct
::
Reader
toStruct
(
schema
::
Node
::
Reader
schema
);
...
...
@@ -267,14 +275,15 @@ private:
inline
Reader
(
const
SchemaPool
*
pool
,
internal
::
ObjectReader
reader
)
:
pool
(
pool
),
reader
(
reader
)
{}
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
To
Impl
;
// Implementation backing the
to
() method. Needs to be a struct to allow partial
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
as
Impl
;
// Implementation backing the
as
() method. Needs to be a struct to allow partial
// specialization. Has a method apply() which does the work.
DynamicStruct
::
Reader
toStruct
(
uint64_t
typeId
);
DynamicList
::
Reader
toList
(
internal
::
ListSchema
schema
);
friend
struct
DynamicStruct
;
friend
struct
DynamicList
;
};
class
DynamicObject
::
Builder
{
...
...
@@ -282,7 +291,7 @@ public:
Builder
()
=
default
;
template
<
typename
T
>
inline
typename
T
::
Builder
to
()
{
return
To
Impl
<
T
>::
apply
(
*
this
);
}
inline
typename
T
::
Builder
as
()
{
return
as
Impl
<
T
>::
apply
(
*
this
);
}
// Convert the object to the given struct, list, or blob type.
DynamicStruct
::
Builder
toStruct
(
schema
::
Node
::
Reader
schema
);
...
...
@@ -295,14 +304,15 @@ private:
inline
Builder
(
const
SchemaPool
*
pool
,
internal
::
ObjectBuilder
builder
)
:
pool
(
pool
),
builder
(
builder
)
{}
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
To
Impl
;
// Implementation backing the
to
() method. Needs to be a struct to allow partial
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
as
Impl
;
// Implementation backing the
as
() method. Needs to be a struct to allow partial
// specialization. Has a method apply() which does the work.
DynamicStruct
::
Builder
toStruct
(
uint64_t
typeId
);
DynamicList
::
Builder
toList
(
internal
::
ListSchema
schema
);
friend
struct
DynamicStruct
;
friend
struct
DynamicList
;
};
// -------------------------------------------------------------------
...
...
@@ -311,8 +321,7 @@ class DynamicUnion::Reader {
public
:
Reader
()
=
default
;
schema
::
StructNode
::
Member
::
Reader
getMemberSchema
()
{
return
schema
;
}
schema
::
StructNode
::
Union
::
Reader
getSchema
();
schema
::
StructNode
::
Union
::
Reader
getSchema
()
{
return
schema
;
}
Maybe
<
schema
::
StructNode
::
Member
::
Reader
>
which
();
// Returns which field is set, or nullptr if an unknown field is set (i.e. the schema is old, and
...
...
@@ -323,20 +332,21 @@ public:
private
:
const
SchemaPool
*
pool
;
schema
::
StructNode
::
Member
::
Reader
schema
;
schema
::
StructNode
::
Union
::
Reader
schema
;
internal
::
StructReader
reader
;
inline
Reader
(
const
SchemaPool
*
pool
,
schema
::
StructNode
::
Member
::
Reader
schema
,
inline
Reader
(
const
SchemaPool
*
pool
,
schema
::
StructNode
::
Union
::
Reader
schema
,
internal
::
StructReader
reader
)
:
pool
(
pool
),
schema
(
schema
),
reader
(
reader
)
{}
friend
struct
DynamicStruct
;
};
class
DynamicUnion
::
Builder
{
public
:
Builder
()
=
default
;
schema
::
StructNode
::
Member
::
Reader
getMemberSchema
()
{
return
schema
;
}
schema
::
StructNode
::
Union
::
Reader
getSchema
();
schema
::
StructNode
::
Union
::
Reader
getSchema
()
{
return
schema
;
}
Maybe
<
schema
::
StructNode
::
Member
::
Reader
>
which
();
// Returns which field is set, or nullptr if an unknown field is set (i.e. the schema is old, and
...
...
@@ -345,15 +355,18 @@ public:
DynamicValue
::
Builder
get
();
void
set
(
schema
::
StructNode
::
Field
::
Reader
field
,
DynamicValue
::
Reader
value
);
DynamicValue
::
Builder
init
(
schema
::
StructNode
::
Field
::
Reader
field
);
DynamicValue
::
Builder
init
(
schema
::
StructNode
::
Field
::
Reader
field
,
uint
size
);
private
:
const
SchemaPool
*
pool
;
schema
::
StructNode
::
Member
::
Reader
schema
;
schema
::
StructNode
::
Union
::
Reader
schema
;
internal
::
StructBuilder
builder
;
inline
Builder
(
const
SchemaPool
*
pool
,
schema
::
StructNode
::
Member
::
Reader
schema
,
inline
Builder
(
const
SchemaPool
*
pool
,
schema
::
StructNode
::
Union
::
Reader
schema
,
internal
::
StructBuilder
builder
)
:
pool
(
pool
),
schema
(
schema
),
builder
(
builder
)
{}
friend
struct
DynamicStruct
;
};
// -------------------------------------------------------------------
...
...
@@ -363,10 +376,10 @@ public:
Reader
()
=
default
;
template
<
typename
T
>
typename
T
::
Reader
to
();
typename
T
::
Reader
as
();
// Convert the dynamic struct to its compiled-in type.
schema
::
Node
::
Reader
getSchemaNode
()
;
schema
::
Node
::
Reader
getSchemaNode
()
{
return
schema
;
}
schema
::
StructNode
::
Reader
getSchema
();
Maybe
<
schema
::
StructNode
::
Member
::
Reader
>
findMemberByName
(
Text
::
Reader
name
);
...
...
@@ -386,6 +399,8 @@ private:
inline
Reader
(
const
SchemaPool
*
pool
,
schema
::
Node
::
Reader
schema
,
internal
::
StructReader
reader
)
:
pool
(
pool
),
schema
(
schema
),
reader
(
reader
)
{}
void
verifyTypeId
(
uint64_t
id
);
static
DynamicValue
::
Reader
getFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructReader
reader
,
schema
::
StructNode
::
Field
::
Reader
field
);
...
...
@@ -393,7 +408,11 @@ private:
template
<
typename
T
>
friend
struct
internal
::
PointerHelpers
;
friend
class
DynamicUnion
::
Reader
;
friend
class
DynamicObject
;
friend
struct
DynamicObject
;
friend
class
DynamicStruct
::
Builder
;
friend
struct
DynamicList
;
friend
class
MessageReader
;
friend
class
MessageBuilder
;
};
class
DynamicStruct
::
Builder
{
...
...
@@ -401,10 +420,10 @@ public:
Builder
()
=
default
;
template
<
typename
T
>
typename
T
::
Builder
to
();
typename
T
::
Builder
as
();
// Cast to a particular struct type.
schema
::
Node
::
Reader
getSchemaNode
()
;
schema
::
Node
::
Reader
getSchemaNode
()
{
return
schema
;
}
schema
::
StructNode
::
Reader
getSchema
();
Maybe
<
schema
::
StructNode
::
Member
::
Reader
>
findMemberByName
(
Text
::
Reader
name
);
...
...
@@ -416,10 +435,16 @@ public:
void
setField
(
schema
::
StructNode
::
Field
::
Reader
field
,
DynamicValue
::
Reader
value
);
// Sets the value of the given field.
Dynamic
Struct
::
Builder
initField
(
schema
::
StructNode
::
Field
::
Reader
field
);
Dynamic
List
::
Builder
initField
(
schema
::
StructNode
::
Field
::
Reader
field
,
uint
size
);
Dynamic
Value
::
Builder
initField
(
schema
::
StructNode
::
Field
::
Reader
field
);
Dynamic
Value
::
Builder
initField
(
schema
::
StructNode
::
Field
::
Reader
field
,
uint
size
);
// Initialize a struct or list field by field schema.
DynamicValue
::
Builder
initObjectField
(
schema
::
StructNode
::
Field
::
Reader
field
,
schema
::
Type
::
Reader
type
);
DynamicValue
::
Builder
initObjectField
(
schema
::
StructNode
::
Field
::
Reader
field
,
schema
::
Type
::
Reader
type
,
uint
size
);
// Initialize an Object-typed field. You must specify the type to initialize as.
DynamicUnion
::
Builder
getUnion
(
schema
::
StructNode
::
Union
::
Reader
un
);
// Returns the value of the given union.
...
...
@@ -436,23 +461,36 @@ private:
internal
::
StructBuilder
builder
)
:
pool
(
pool
),
schema
(
schema
),
builder
(
builder
)
{}
void
verifyTypeId
(
uint64_t
id
);
static
DynamicValue
::
Builder
getFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
);
static
void
setFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
,
DynamicValue
::
Reader
value
);
static
Dynamic
List
::
Builder
initLis
tFieldImpl
(
static
Dynamic
Value
::
Builder
ini
tFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
,
uint
length
);
static
Dynamic
Struct
::
Builder
initStruc
tFieldImpl
(
schema
::
StructNode
::
Field
::
Reader
field
,
uint
size
);
static
Dynamic
Value
::
Builder
ini
tFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
);
static
DynamicValue
::
Builder
initFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
,
schema
::
Type
::
Reader
type
,
uint
size
);
static
DynamicValue
::
Builder
initFieldImpl
(
const
SchemaPool
*
pool
,
internal
::
StructBuilder
builder
,
schema
::
StructNode
::
Field
::
Reader
field
,
schema
::
Type
::
Reader
type
);
template
<
typename
T
>
friend
struct
internal
::
PointerHelpers
;
friend
class
DynamicUnion
::
Builder
;
friend
class
DynamicObject
;
friend
struct
DynamicObject
;
friend
struct
DynamicList
;
friend
class
MessageReader
;
friend
class
MessageBuilder
;
};
// -------------------------------------------------------------------
...
...
@@ -463,7 +501,7 @@ public:
inline
explicit
Reader
(
internal
::
ListReader
reader
)
:
reader
(
reader
)
{}
template
<
typename
T
>
typename
T
::
Reader
to
();
typename
T
::
Reader
as
();
// Try to convert to any List<T>, Data, or Text. Throws an exception if the underlying data
// can't possibly represent the requested type.
...
...
@@ -486,14 +524,24 @@ private:
// Number of types elementType must be wrapped in List() to get the actual element type, e.g.
// List(List(List(Bool))) has depth = 2.
schema
::
Node
::
Body
::
Reader
elementSchema
;
// if elementType is struct/enum/interface
schema
::
Node
::
Reader
elementSchema
;
// if elementType is struct/enum/interface
internal
::
ListReader
reader
;
Reader
(
const
SchemaPool
*
pool
,
schema
::
Type
::
Reader
elementType
,
internal
::
ListReader
reader
);
Reader
(
const
SchemaPool
*
pool
,
internal
::
ListSchema
schema
,
internal
::
ListReader
reader
);
friend
class
DynamicStruct
;
friend
class
DynamicObject
;
Reader
(
const
SchemaPool
*
pool
,
schema
::
Type
::
Body
::
Which
elementType
,
uint
depth
,
schema
::
Node
::
Reader
elementSchema
,
internal
::
ListReader
reader
)
:
pool
(
pool
),
elementType
(
elementType
),
depth
(
depth
),
elementSchema
(
elementSchema
),
reader
(
reader
)
{}
void
verifySchema
(
internal
::
ListSchema
schema
);
template
<
typename
T
>
friend
struct
internal
::
PointerHelpers
;
friend
struct
DynamicStruct
;
friend
struct
DynamicObject
;
friend
class
DynamicList
::
Builder
;
};
class
DynamicList
::
Builder
{
...
...
@@ -502,12 +550,14 @@ public:
inline
explicit
Builder
(
internal
::
ListBuilder
builder
)
:
builder
(
builder
)
{}
template
<
typename
T
>
typename
T
::
Builder
to
();
typename
T
::
Builder
as
();
// Try to convert to any List<T>, Data, or Text. Throws an exception if the underlying data
// can't possibly represent the requested type.
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
DynamicStruct
::
Builder
operator
[](
uint
index
);
DynamicValue
::
Builder
operator
[](
uint
index
);
void
set
(
uint
index
,
DynamicValue
::
Reader
value
);
DynamicValue
::
Builder
init
(
uint
index
,
uint
size
);
typedef
internal
::
IndexingIterator
<
Builder
,
DynamicStruct
::
Builder
>
iterator
;
inline
iterator
begin
()
{
return
iterator
(
this
,
0
);
}
...
...
@@ -521,13 +571,22 @@ private:
const
SchemaPool
*
pool
;
schema
::
Type
::
Body
::
Which
elementType
;
uint
depth
;
schema
::
Node
::
Body
::
Reader
elementSchema
;
schema
::
Node
::
Reader
elementSchema
;
internal
::
ListBuilder
builder
;
Builder
(
const
SchemaPool
*
pool
,
schema
::
Type
::
Reader
elementType
,
internal
::
ListBuilder
builder
);
Builder
(
const
SchemaPool
*
pool
,
internal
::
ListSchema
schema
,
internal
::
ListBuilder
builder
);
friend
class
DynamicStruct
;
friend
class
DynamicObject
;
Builder
(
const
SchemaPool
*
pool
,
schema
::
Type
::
Body
::
Which
elementType
,
uint
depth
,
schema
::
Node
::
Reader
elementSchema
,
internal
::
ListBuilder
builder
)
:
pool
(
pool
),
elementType
(
elementType
),
depth
(
depth
),
elementSchema
(
elementSchema
),
builder
(
builder
)
{}
void
verifySchema
(
internal
::
ListSchema
schema
);
template
<
typename
T
>
friend
struct
internal
::
PointerHelpers
;
friend
struct
DynamicStruct
;
friend
struct
DynamicObject
;
};
// -------------------------------------------------------------------
...
...
@@ -535,7 +594,7 @@ private:
namespace
internal
{
// Make sure ReaderFor<T> and BuilderFor<T> work for DynamicEnum, DynamicObject, DynamicStruct, and
// DynamicList, so that we can define DynamicValue::
to
().
// DynamicList, so that we can define DynamicValue::
as
().
template
<>
struct
MaybeReaderBuilder
<
DynamicEnum
,
Kind
::
UNKNOWN
>
{
...
...
@@ -565,8 +624,7 @@ struct MaybeReaderBuilder<DynamicList, Kind::UNKNOWN> {
class
DynamicValue
::
Reader
{
public
:
inline
Reader
()
{}
inline
Reader
(
Void
voidValue
);
inline
Reader
(
Void
voidValue
=
Void
::
VOID
);
inline
Reader
(
bool
boolValue
);
inline
Reader
(
int8_t
int8Value
);
inline
Reader
(
int16_t
int16Value
);
...
...
@@ -586,7 +644,7 @@ public:
inline
Reader
(
DynamicObject
::
Reader
objectValue
);
template
<
typename
T
>
inline
ReaderFor
<
T
>
to
()
{
return
To
Impl
<
T
>::
apply
(
*
this
);
}
inline
ReaderFor
<
T
>
as
()
{
return
as
Impl
<
T
>::
apply
(
*
this
);
}
// Use to interpret the value as some type. Allowed types are:
// - Void, bool, [u]int{8,16,32,64}_t, float, double, any enum: Returns the raw value.
// - Text, Data, any struct type: Returns the corresponding Reader.
...
...
@@ -625,15 +683,14 @@ private:
DynamicObject
::
Reader
objectValue
;
};
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
To
Impl
;
// Implementation backing the
to
() method. Needs to be a struct to allow partial
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
as
Impl
;
// Implementation backing the
as
() method. Needs to be a struct to allow partial
// specialization. Has a method apply() which does the work.
};
class
DynamicValue
::
Builder
{
public
:
inline
Builder
()
{}
inline
Builder
(
Void
voidValue
);
inline
Builder
(
Void
voidValue
=
Void
::
VOID
);
inline
Builder
(
bool
boolValue
);
inline
Builder
(
int8_t
int8Value
);
inline
Builder
(
int16_t
int16Value
);
...
...
@@ -653,8 +710,8 @@ public:
inline
Builder
(
DynamicObject
::
Builder
objectValue
);
template
<
typename
T
>
inline
BuilderFor
<
T
>
to
()
{
return
To
Impl
<
T
>::
apply
(
*
this
);
}
// See DynamicValue::Reader::
to
().
inline
BuilderFor
<
T
>
as
()
{
return
as
Impl
<
T
>::
apply
(
*
this
);
}
// See DynamicValue::Reader::
as
().
inline
schema
::
Type
::
Body
::
Which
getType
()
{
return
type
;
}
// Get the type of this value.
...
...
@@ -685,13 +742,54 @@ private:
DynamicObject
::
Builder
objectValue
;
};
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
To
Impl
;
// Implementation backing the
to
() method. Needs to be a struct to allow partial
template
<
typename
T
,
Kind
kind
=
kind
<
T
>
()
>
struct
as
Impl
;
// Implementation backing the
as
() method. Needs to be a struct to allow partial
// specialization. Has a method apply() which does the work.
};
// -------------------------------------------------------------------
// Inject the ability to use DynamicStruct for message roots and Dynamic{Struct,List} for
// generated Object accessors.
template
<>
DynamicStruct
::
Reader
MessageReader
::
getRoot
<
DynamicStruct
>
(
const
SchemaPool
&
pool
,
uint64_t
typeId
);
template
<>
DynamicStruct
::
Builder
MessageBuilder
::
initRoot
<
DynamicStruct
>
(
const
SchemaPool
&
pool
,
uint64_t
typeId
);
template
<>
DynamicStruct
::
Builder
MessageBuilder
::
getRoot
<
DynamicStruct
>
(
const
SchemaPool
&
pool
,
uint64_t
typeId
);
namespace
internal
{
template
<>
struct
PointerHelpers
<
DynamicStruct
,
Kind
::
UNKNOWN
>
{
static
DynamicStruct
::
Reader
get
(
StructReader
reader
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
uint64_t
typeId
);
static
DynamicStruct
::
Builder
get
(
StructBuilder
builder
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
uint64_t
typeId
);
static
void
set
(
StructBuilder
builder
,
WireReferenceCount
index
,
DynamicStruct
::
Reader
value
);
static
DynamicStruct
::
Builder
init
(
StructBuilder
builder
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
uint64_t
typeId
);
};
template
<>
struct
PointerHelpers
<
DynamicList
,
Kind
::
UNKNOWN
>
{
static
DynamicList
::
Reader
get
(
StructReader
reader
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
schema
::
Type
::
Reader
elementType
);
static
DynamicList
::
Builder
get
(
StructBuilder
builder
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
schema
::
Type
::
Reader
elementType
);
static
void
set
(
StructBuilder
builder
,
WireReferenceCount
index
,
DynamicList
::
Reader
value
);
static
DynamicList
::
Builder
init
(
StructBuilder
builder
,
WireReferenceCount
index
,
const
SchemaPool
&
pool
,
schema
::
Type
::
Reader
elementType
,
uint
size
);
};
}
// namespace internal
// =======================================================================================
// Implementation details.
// I
nline i
mplementation details.
#define CAPNPROTO_DECLARE_TYPE(name, discrim, typeName) \
inline DynamicValue::Reader::Reader(ReaderFor<typeName> name##Value) \
...
...
@@ -699,11 +797,11 @@ inline DynamicValue::Reader::Reader(ReaderFor<typeName> name##Value) \
inline DynamicValue::Builder::Builder(BuilderFor<typeName> name##Value) \
: type(schema::Type::Body::discrim##_TYPE), name##Value(name##Value) {} \
template <> \
struct DynamicValue::Reader::
To
Impl<typeName> { \
struct DynamicValue::Reader::
as
Impl<typeName> { \
static ReaderFor<typeName> apply(Reader reader); \
}; \
template <> \
struct DynamicValue::Builder::
To
Impl<typeName> { \
struct DynamicValue::Builder::
as
Impl<typeName> { \
static BuilderFor<typeName> apply(Builder builder); \
};
...
...
@@ -735,81 +833,140 @@ inline DynamicValue::Reader::Reader(Void voidValue) \
inline
DynamicValue
::
Builder
::
Builder
(
Void
voidValue
)
\
:
type
(
schema
::
Type
::
Body
::
VOID_TYPE
),
voidValue
(
voidValue
)
{}
\
template
<>
struct
DynamicValue
::
Reader
::
To
Impl
<
Void
>
{
struct
DynamicValue
::
Reader
::
as
Impl
<
Void
>
{
static
Void
apply
(
Reader
reader
);
};
template
<>
struct
DynamicValue
::
Builder
::
To
Impl
<
Void
>
{
struct
DynamicValue
::
Builder
::
as
Impl
<
Void
>
{
static
Void
apply
(
Builder
builder
);
};
template
<
typename
T
>
struct
DynamicValue
::
Reader
::
To
Impl
<
T
,
Kind
::
ENUM
>
{
struct
DynamicValue
::
Reader
::
as
Impl
<
T
,
Kind
::
ENUM
>
{
static
T
apply
(
Reader
reader
)
{
return
reader
.
to
<
DynamicEnum
>
().
to
<
T
>
();
return
reader
.
as
<
DynamicEnum
>
().
as
<
T
>
();
}
};
template
<
typename
T
>
struct
DynamicValue
::
Builder
::
To
Impl
<
T
,
Kind
::
ENUM
>
{
struct
DynamicValue
::
Builder
::
as
Impl
<
T
,
Kind
::
ENUM
>
{
static
T
apply
(
Builder
builder
)
{
return
builder
.
to
<
DynamicEnum
>
().
to
<
T
>
();
return
builder
.
as
<
DynamicEnum
>
().
as
<
T
>
();
}
};
template
<
typename
T
>
struct
DynamicValue
::
Reader
::
To
Impl
<
T
,
Kind
::
STRUCT
>
{
struct
DynamicValue
::
Reader
::
as
Impl
<
T
,
Kind
::
STRUCT
>
{
static
T
apply
(
Reader
reader
)
{
return
reader
.
to
<
DynamicStruct
>
().
to
<
T
>
();
return
reader
.
as
<
DynamicStruct
>
().
as
<
T
>
();
}
};
template
<
typename
T
>
struct
DynamicValue
::
Builder
::
To
Impl
<
T
,
Kind
::
STRUCT
>
{
struct
DynamicValue
::
Builder
::
as
Impl
<
T
,
Kind
::
STRUCT
>
{
static
T
apply
(
Builder
builder
)
{
return
builder
.
to
<
DynamicStruct
>
().
to
<
T
>
();
return
builder
.
as
<
DynamicStruct
>
().
as
<
T
>
();
}
};
template
<
typename
T
>
struct
DynamicValue
::
Reader
::
To
Impl
<
T
,
Kind
::
LIST
>
{
struct
DynamicValue
::
Reader
::
as
Impl
<
T
,
Kind
::
LIST
>
{
static
T
apply
(
Reader
reader
)
{
return
reader
.
to
<
DynamicList
>
().
to
<
T
>
();
return
reader
.
as
<
DynamicList
>
().
as
<
T
>
();
}
};
template
<
typename
T
>
struct
DynamicValue
::
Builder
::
To
Impl
<
T
,
Kind
::
LIST
>
{
struct
DynamicValue
::
Builder
::
as
Impl
<
T
,
Kind
::
LIST
>
{
static
T
apply
(
Builder
builder
)
{
return
builder
.
to
<
DynamicList
>
().
to
<
T
>
();
return
builder
.
as
<
DynamicList
>
().
as
<
T
>
();
}
};
// -------------------------------------------------------------------
template
<
typename
T
>
struct
DynamicObject
::
Reader
::
To
Impl
<
T
,
Kind
::
STRUCT
>
{
struct
DynamicObject
::
Reader
::
as
Impl
<
T
,
Kind
::
STRUCT
>
{
static
T
apply
(
Reader
reader
)
{
return
reader
.
toStruct
(
typeId
<
T
>
()).
to
<
T
>
();
return
reader
.
toStruct
(
typeId
<
T
>
()).
as
<
T
>
();
}
};
template
<
typename
T
>
struct
DynamicObject
::
Builder
::
To
Impl
<
T
,
Kind
::
STRUCT
>
{
struct
DynamicObject
::
Builder
::
as
Impl
<
T
,
Kind
::
STRUCT
>
{
static
T
apply
(
Builder
builder
)
{
return
builder
.
toStruct
(
typeId
<
T
>
()).
to
<
T
>
();
return
builder
.
toStruct
(
typeId
<
T
>
()).
as
<
T
>
();
}
};
template
<
typename
T
>
struct
DynamicObject
::
Reader
::
To
Impl
<
List
<
T
>
,
Kind
::
LIST
>
{
struct
DynamicObject
::
Reader
::
as
Impl
<
List
<
T
>
,
Kind
::
LIST
>
{
static
T
apply
(
Reader
reader
)
{
return
reader
.
toList
(
internal
::
ListSchemaFor
<
T
>::
schema
).
to
<
T
>
();
return
reader
.
toList
(
internal
::
ListSchemaFor
Element
<
T
>::
schema
).
as
<
T
>
();
}
};
template
<
typename
T
>
struct
DynamicObject
::
Builder
::
To
Impl
<
List
<
T
>
,
Kind
::
LIST
>
{
struct
DynamicObject
::
Builder
::
as
Impl
<
List
<
T
>
,
Kind
::
LIST
>
{
static
T
apply
(
Builder
builder
)
{
return
builder
.
toList
(
internal
::
ListSchemaFor
<
T
>::
schema
).
to
<
T
>
();
return
builder
.
toList
(
internal
::
ListSchemaFor
Element
<
T
>::
schema
).
as
<
T
>
();
}
};
// -------------------------------------------------------------------
template
<
typename
T
>
typename
T
::
Reader
DynamicStruct
::
Reader
::
as
()
{
static_assert
(
kind
<
T
>
()
==
Kind
::
STRUCT
,
"DynamicStruct::Reader::as<T>() can only convert to struct types."
);
verifyTypeId
(
typeId
<
T
>
());
return
typename
T
::
Reader
(
reader
);
}
template
<
typename
T
>
typename
T
::
Builder
DynamicStruct
::
Builder
::
as
()
{
static_assert
(
kind
<
T
>
()
==
Kind
::
STRUCT
,
"DynamicStruct::Builder::as<T>() can only convert to struct types."
);
verifyTypeId
(
typeId
<
T
>
());
return
typename
T
::
Builder
(
builder
);
}
inline
DynamicValue
::
Reader
DynamicStruct
::
Reader
::
getField
(
schema
::
StructNode
::
Field
::
Reader
field
)
{
return
getFieldImpl
(
pool
,
reader
,
field
);
}
inline
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
getField
(
schema
::
StructNode
::
Field
::
Reader
field
)
{
return
getFieldImpl
(
pool
,
builder
,
field
);
}
inline
void
DynamicStruct
::
Builder
::
setField
(
schema
::
StructNode
::
Field
::
Reader
field
,
DynamicValue
::
Reader
value
)
{
return
setFieldImpl
(
pool
,
builder
,
field
,
value
);
}
inline
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
initField
(
schema
::
StructNode
::
Field
::
Reader
field
)
{
return
initFieldImpl
(
pool
,
builder
,
field
);
}
inline
DynamicValue
::
Builder
DynamicStruct
::
Builder
::
initField
(
schema
::
StructNode
::
Field
::
Reader
field
,
uint
size
)
{
return
initFieldImpl
(
pool
,
builder
,
field
,
size
);
}
inline
DynamicStruct
::
Reader
DynamicStruct
::
Builder
::
asReader
()
{
return
DynamicStruct
::
Reader
(
pool
,
schema
,
builder
.
asReader
());
}
// -------------------------------------------------------------------
template
<
typename
T
>
typename
T
::
Reader
DynamicList
::
Reader
::
as
()
{
static_assert
(
kind
<
T
>
()
==
Kind
::
LIST
,
"DynamicStruct::Reader::as<T>() can only convert to list types."
);
verifySchema
(
internal
::
ListSchemaFor
<
T
>::
schema
);
return
typename
T
::
Reader
(
reader
);
}
template
<
typename
T
>
typename
T
::
Builder
DynamicList
::
Builder
::
as
()
{
static_assert
(
kind
<
T
>
()
==
Kind
::
LIST
,
"DynamicStruct::Builder::as<T>() can only convert to list types."
);
verifySchema
(
internal
::
ListSchemaFor
<
T
>::
schema
);
return
typename
T
::
Builder
(
builder
);
}
}
// namespace capnproto
#endif // CAPNPROTO_DYNAMIC_H_
c++/src/capnproto/generated-header-support.h
View file @
b2edb433
...
...
@@ -31,6 +31,8 @@
namespace
capnproto
{
class
SchemaPool
;
// Needs to be declared for dynamic Object accessors.
class
DynamicStruct
;
// So that it can be declared a friend.
template
<
typename
T
>
...
...
@@ -52,7 +54,7 @@ struct PointerHelpers<T, Kind::STRUCT> {
}
static
inline
void
set
(
StructBuilder
builder
,
WireReferenceCount
index
,
typename
T
::
Reader
value
)
{
// TODO(
soon)
// TODO(
now): schemaless copy
CAPNPROTO_INLINE_PRECOND
(
false
,
"Not implemented: set() for struct fields."
);
}
static
inline
typename
T
::
Builder
init
(
StructBuilder
builder
,
WireReferenceCount
index
)
{
...
...
c++/src/capnproto/layout-test.c++
View file @
b2edb433
...
...
@@ -138,7 +138,7 @@ static void setupStruct(StructBuilder builder) {
2
*
REFERENCES
,
4
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
EXPECT_EQ
(
4
*
ELEMENTS
,
list
.
size
());
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
);
element
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
300
+
i
);
element
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
FieldSize
::
EIGHT_BYTES
))
...
...
@@ -193,7 +193,7 @@ static void checkStruct(StructBuilder builder) {
ListBuilder
list
=
builder
.
getListField
(
2
*
REFERENCES
,
nullptr
);
ASSERT_EQ
(
4
*
ELEMENTS
,
list
.
size
());
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
);
EXPECT_EQ
(
300
+
i
,
element
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
400
+
i
,
element
.
getStructField
(
0
*
REFERENCES
,
...
...
c++/src/capnproto/layout.c++
View file @
b2edb433
...
...
@@ -1250,11 +1250,11 @@ Data::Builder ListBuilder::asData() {
return
Data
::
Builder
(
reinterpret_cast
<
char
*>
(
ptr
),
elementCount
/
ELEMENTS
);
}
StructBuilder
ListBuilder
::
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
{
StructBuilder
ListBuilder
::
getStructElement
(
ElementCount
index
)
const
{
BitCount64
indexBit
=
ElementCount64
(
index
)
*
step
;
byte
*
structData
=
ptr
+
indexBit
/
BITS_PER_BYTE
;
return
StructBuilder
(
segment
,
structData
,
reinterpret_cast
<
WireReference
*>
(
structData
)
+
elementSize
.
data
/
WORDS_PER_REFERENCE
,
reinterpret_cast
<
WireReference
*>
(
structData
+
structDataSize
/
BITS_PER_BYTE
)
,
structDataSize
,
structReferenceCount
,
indexBit
%
BITS_PER_BYTE
);
}
...
...
@@ -1310,9 +1310,9 @@ Data::Builder ListBuilder::getBlobElement<Data>(ElementCount index) const {
0
*
BYTES
);
}
ObjectBuilder
ListBuilder
::
getObjectElement
(
ElementCount
index
,
const
word
*
defaultValue
)
const
{
ObjectBuilder
ListBuilder
::
getObjectElement
(
ElementCount
index
)
const
{
return
WireHelpers
::
getWritableObjectReference
(
segment
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
step
/
BITS_PER_BYTE
),
defaultValue
);
segment
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
index
*
step
/
BITS_PER_BYTE
),
nullptr
);
}
ListReader
ListBuilder
::
asReader
()
const
{
...
...
@@ -1403,9 +1403,9 @@ Data::Reader ListReader::getBlobElement<Data>(ElementCount index) const {
nullptr
,
0
*
BYTES
);
}
ObjectReader
ListReader
::
getObjectElement
(
ElementCount
index
,
const
word
*
defaultValue
)
const
{
ObjectReader
ListReader
::
getObjectElement
(
ElementCount
index
)
const
{
return
WireHelpers
::
readObjectReference
(
segment
,
checkAlignment
(
ptr
+
index
*
step
/
BITS_PER_BYTE
),
defaultValue
,
nestingLimit
);
segment
,
checkAlignment
(
ptr
+
index
*
step
/
BITS_PER_BYTE
),
nullptr
,
nestingLimit
);
}
}
// namespace internal
...
...
c++/src/capnproto/layout.h
View file @
b2edb433
...
...
@@ -502,7 +502,7 @@ public:
ElementCount
index
,
typename
NoInfer
<
T
>::
Type
value
)
const
);
// Set the element at the given index.
StructBuilder
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
;
StructBuilder
getStructElement
(
ElementCount
index
)
const
;
// Get the struct element at the given index.
ListBuilder
initListElement
(
...
...
@@ -532,7 +532,7 @@ public:
typename
T
::
Builder
getBlobElement
(
ElementCount
index
)
const
;
// Get the blob element. If it is not initialized, return an empty blob builder.
ObjectBuilder
getObjectElement
(
ElementCount
index
,
const
word
*
defaultValue
)
const
;
ObjectBuilder
getObjectElement
(
ElementCount
index
)
const
;
// Gets a pointer element of arbitrary type.
ListReader
asReader
()
const
;
...
...
@@ -591,7 +591,7 @@ public:
typename
T
::
Reader
getBlobElement
(
ElementCount
index
)
const
;
// Gets the text or data field. If it is not initialized, returns an empty blob reader.
ObjectReader
getObjectElement
(
ElementCount
index
,
const
word
*
defaultValue
)
const
;
ObjectReader
getObjectElement
(
ElementCount
index
)
const
;
// Gets a pointer element of arbitrary type.
private
:
...
...
c++/src/capnproto/list.h
View file @
b2edb433
...
...
@@ -297,8 +297,7 @@ struct List<T, Kind::STRUCT> {
inline
uint
size
()
const
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
T
::
Builder
operator
[](
uint
index
)
const
{
return
typename
T
::
Builder
(
builder
.
getStructElement
(
index
*
ELEMENTS
,
internal
::
structSize
<
T
>
()));
return
typename
T
::
Builder
(
builder
.
getStructElement
(
index
*
ELEMENTS
));
}
typedef
internal
::
IndexingIterator
<
Builder
,
typename
T
::
Builder
>
iterator
;
...
...
c++/src/capnproto/message.c++
View file @
b2edb433
...
...
@@ -49,7 +49,7 @@ internal::StructReader MessageReader::getRootInternal() {
allocatedArena
=
true
;
}
internal
::
SegmentReader
*
segment
=
arena
()
->
tryGetSegment
(
SegmentId
(
0
));
internal
::
SegmentReader
*
segment
=
arena
()
->
tryGetSegment
(
internal
::
SegmentId
(
0
));
VALIDATE_INPUT
(
segment
!=
nullptr
&&
segment
->
containsInterval
(
segment
->
getStartPtr
(),
segment
->
getStartPtr
()
+
1
),
"Message did not contain a root pointer."
)
{
...
...
@@ -70,7 +70,7 @@ MessageBuilder::~MessageBuilder() {
internal
::
SegmentBuilder
*
MessageBuilder
::
getRootSegment
()
{
if
(
allocatedArena
)
{
return
arena
()
->
getSegment
(
SegmentId
(
0
));
return
arena
()
->
getSegment
(
internal
::
SegmentId
(
0
));
}
else
{
static_assert
(
sizeof
(
internal
::
BuilderArena
)
<=
sizeof
(
arenaSpace
),
"arenaSpace is too small to hold a BuilderArena. Please increase it. This will break "
...
...
@@ -80,7 +80,7 @@ internal::SegmentBuilder* MessageBuilder::getRootSegment() {
WordCount
refSize
=
1
*
REFERENCES
*
WORDS_PER_REFERENCE
;
internal
::
SegmentBuilder
*
segment
=
arena
()
->
getSegmentWithAvailable
(
refSize
);
CHECK
(
segment
->
getSegmentId
()
==
SegmentId
(
0
),
CHECK
(
segment
->
getSegmentId
()
==
internal
::
SegmentId
(
0
),
"First allocated word of new arena was not in segment ID 0."
);
word
*
location
=
segment
->
allocate
(
refSize
);
CHECK
(
location
==
segment
->
getPtrUnchecked
(
0
*
WORDS
),
...
...
c++/src/capnproto/message.h
View file @
b2edb433
...
...
@@ -37,8 +37,7 @@ namespace internal {
class
BuilderArena
;
}
class
Segment
;
typedef
Id
<
uint32_t
,
Segment
>
SegmentId
;
class
SchemaPool
;
// =======================================================================================
...
...
@@ -97,6 +96,13 @@ public:
template
<
typename
RootType
>
typename
RootType
::
Reader
getRoot
();
// Get the root struct of the message, interpreting it as the given struct type.
template
<
typename
RootType
>
typename
RootType
::
Reader
getRoot
(
const
SchemaPool
&
pool
,
uint64_t
typeId
);
// Dynamically interpret the root struct of the message using the type with the given ID.
// RootType in this case must be DynamicStruct, and you must #include <capnproto/dynamic.h> to
// use this.
private
:
ReaderOptions
options
;
...
...
@@ -125,8 +131,23 @@ public:
template
<
typename
RootType
>
typename
RootType
::
Builder
initRoot
();
// Initialize the root struct of the message as the given struct type.
template
<
typename
RootType
>
typename
RootType
::
Builder
getRoot
();
// Get the root struct of the message, interpreting it as the given struct type.
template
<
typename
RootType
>
typename
RootType
::
Builder
getRoot
(
const
SchemaPool
&
pool
,
uint64_t
typeId
);
// Dynamically interpret the root struct of the message using the type with the given ID.
// RootType in this case must be DynamicStruct, and you must #include <capnproto/dynamic.h> to
// use this.
template
<
typename
RootType
>
typename
RootType
::
Builder
initRoot
(
const
SchemaPool
&
pool
,
uint64_t
typeId
);
// Dynamically init the root struct of the message using the type with the given ID.
// RootType in this case must be DynamicStruct, and you must #include <capnproto/dynamic.h> to
// use this.
ArrayPtr
<
const
ArrayPtr
<
const
word
>>
getSegmentsForOutput
();
...
...
@@ -270,16 +291,19 @@ inline const ReaderOptions& MessageReader::getOptions() {
template
<
typename
RootType
>
inline
typename
RootType
::
Reader
MessageReader
::
getRoot
()
{
static_assert
(
kind
<
RootType
>
()
==
Kind
::
STRUCT
,
"Root type must be a Cap'n Proto struct type."
);
return
typename
RootType
::
Reader
(
getRootInternal
());
}
template
<
typename
RootType
>
inline
typename
RootType
::
Builder
MessageBuilder
::
initRoot
()
{
static_assert
(
kind
<
RootType
>
()
==
Kind
::
STRUCT
,
"Root type must be a Cap'n Proto struct type."
);
return
typename
RootType
::
Builder
(
initRoot
(
internal
::
structSize
<
RootType
>
()));
}
template
<
typename
RootType
>
inline
typename
RootType
::
Builder
MessageBuilder
::
getRoot
()
{
static_assert
(
kind
<
RootType
>
()
==
Kind
::
STRUCT
,
"Root type must be a Cap'n Proto struct type."
);
return
typename
RootType
::
Builder
(
getRoot
(
internal
::
structSize
<
RootType
>
()));
}
...
...
c++/src/capnproto/schema.capnp
View file @
b2edb433
...
...
@@ -219,6 +219,11 @@ struct StructNode {
}
struct Field {
index @3 :UInt16;
# The index of this field within the containing struct or union's member list. This is
# redundant information, but it can be useful for the dynamic API which uses Field pointers as
# identifiers.
offset @0 :UInt32;
# Offset, in units of the field's size, from the beginning of the section in which the field
# resides. E.g. for a UInt32 field, multiply this by 4 to get the byte offset from the
...
...
compiler/src/WireFormat.hs
View file @
b2edb433
...
...
@@ -575,7 +575,7 @@ encodeSchema requestedFiles allFiles = encRoot where
,
(
16
,
encUInt16
$
structPointerCount
desc
)
,
(
32
,
encUInt16
(
fieldSizeEnum
preferredListEncoding
::
Word16
))
]
ptrValues
=
[
(
0
,
encStructList
memberSize
$
map
encMember
$
ptrValues
=
[
(
0
,
encStructList
memberSize
$
zipWith
encMember
[
0
::
Word16
..
]
$
sortMembers
$
structMembers
desc
)
]
preferredListEncoding
=
case
(
structDataSize
desc
,
structPointerCount
desc
)
of
...
...
@@ -597,7 +597,7 @@ encodeSchema requestedFiles allFiles = encRoot where
selectFieldOrUnion
_
=
Nothing
memberSize
=
(
DataSectionWords
1
,
3
)
encMember
(
codeOrder
,
(
_
,
DescField
field
))
=
(
dataValues2
,
ptrValues2
)
where
encMember
index
(
codeOrder
,
(
_
,
DescField
field
))
=
(
dataValues2
,
ptrValues2
)
where
dataValues2
=
[
(
0
,
encUInt16
$
fieldNumber
field
)
,
(
16
,
encUInt16
codeOrder
)
,
(
32
,
encUInt16
(
0
::
Word16
))
-- discriminant
...
...
@@ -608,7 +608,8 @@ encodeSchema requestedFiles allFiles = encRoot where
]
-- StructNode.Field
dataValues3
=
[
(
0
,
encUInt32
$
offsetToInt
$
fieldOffset
field
)
]
dataValues3
=
[
(
0
,
encUInt32
$
offsetToInt
$
fieldOffset
field
)
,
(
32
,
encUInt16
index
)
]
ptrValues3
=
[
(
0
,
encStruct
typeSize
$
encType
$
fieldType
field
)
,
(
1
,
encStruct
valueSize
$
encValue
(
fieldType
field
)
$
fieldDefaultValue
field
)
...
...
@@ -620,7 +621,7 @@ encodeSchema requestedFiles allFiles = encRoot where
offsetToInt
(
InlineCompositeOffset
{})
=
error
"Inline types not currently supported by codegen plugins."
encMember
(
codeOrder
,
(
_
,
DescUnion
union
))
=
(
dataValues2
,
ptrValues2
)
where
encMember
_
(
codeOrder
,
(
_
,
DescUnion
union
))
=
(
dataValues2
,
ptrValues2
)
where
dataValues2
=
[
(
0
,
encUInt16
$
unionNumber
union
)
,
(
16
,
encUInt16
codeOrder
)
,
(
32
,
encUInt16
(
1
::
Word16
))
-- discriminant
...
...
@@ -632,9 +633,9 @@ encodeSchema requestedFiles allFiles = encRoot where
-- StructNode.Union
dataValues3
=
[
(
0
,
encUInt32
$
unionTagOffset
union
)
]
ptrValues3
=
[
(
0
,
encStructList
memberSize
$
map
encMember
$
sortMembers
$
ptrValues3
=
[
(
0
,
encStructList
memberSize
$
zipWith
encMember
[
0
..
]
$
sortMembers
$
unionMembers
union
)
]
encMember
_
=
error
"Not a field or union?"
encMember
_
_
=
error
"Not a field or union?"
enumNodeSize
=
(
DataSectionWords
0
,
1
)
encEnumNode
desc
=
(
dataValues
,
ptrValues
)
where
...
...
compiler/src/c++-header.mustache
View file @
b2edb433
...
...
@@ -157,6 +157,8 @@ public:
{{/
fieldIsPrimitive
}}
{{#
fieldIsGenericObject
}}
template
<typename
T
>
inline typename T::Reader get
{{
fieldTitleCase
}}
();
template
<typename
T
,
typename
...
Params
>
inline typename T::Reader get
{{
fieldTitleCase
}}
(
const ::capnproto::SchemaPool
&
pool, Params
&&
... params);
{{/
fieldIsGenericObject
}}
{{/
typeFields
}}
private:
...
...
@@ -209,6 +211,11 @@ public:
template
<typename
T
>
inline void set
{{
fieldTitleCase
}}
(typename T::Reader value);
template
<typename
T
>
inline typename T::Builder init
{{
fieldTitleCase
}}
();
template
<typename
T
>
inline typename T::Builder init
{{
fieldTitleCase
}}
(unsigned int size);
template
<typename
T
,
typename
...
Params
>
inline typename T::Builder get
{{
fieldTitleCase
}}
(
const ::capnproto::SchemaPool
&
pool, Params
&&
... params);
template
<typename
T
,
typename
...
Params
>
inline typename T::Builder init
{{
fieldTitleCase
}}
(
const ::capnproto::SchemaPool
&
pool, Params
&&
... params);
{{/
fieldIsGenericObject
}}
{{/
typeFields
}}
private:
...
...
@@ -394,6 +401,42 @@ inline typename T::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(uns
_builder,
{{
fieldOffset
}}
* ::capnproto::REFERENCES, size);
}
template
<typename
T
,
typename
...
Params
>
inline typename T::Reader
{{
typeFullName
}}
::Reader::get
{{
fieldTitleCase
}}
(
const ::capnproto::SchemaPool
&
pool, Params
&&
... params) {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return ::capnproto::internal::PointerHelpers
<T>
::get(
_reader,
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
pool, ::capnproto::forward
<Params>
(params)...);
}
template
<typename
T
,
typename
...
Params
>
inline typename T::Builder
{{
typeFullName
}}
::Builder::get
{{
fieldTitleCase
}}
(
const ::capnproto::SchemaPool
&
pool, Params
&&
... params) {
{{#
fieldUnion
}}
CAPNPROTO_INLINE_DPRECOND(which() ==
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
,
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return ::capnproto::internal::PointerHelpers
<T>
::get(
_builder,
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
pool, ::capnproto::forward
<Params>
(params)...);
}
template
<typename
T
,
typename
...
Params
>
inline typename T::Builder
{{
typeFullName
}}
::Builder::init
{{
fieldTitleCase
}}
(
const ::capnproto::SchemaPool
&
pool, Params
&&
... params) {
{{#
fieldUnion
}}
_builder.setDataField
<
{{
unionTitleCase
}}
::Which>
(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
return ::capnproto::internal::PointerHelpers
<T>
::init(
_builder,
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
pool, ::capnproto::forward
<Params>
(params)...);
}
{{/
fieldIsGenericObject
}}
{{/
typeFields
}}
{{/
typeStructOrUnion
}}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment