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
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
102 additions
and
25 deletions
+102
-25
arena.h
c++/src/capnproto/arena.h
+3
-0
dynamic.c++
c++/src/capnproto/dynamic.c++
+0
-0
dynamic.h
c++/src/capnproto/dynamic.h
+0
-0
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
This diff is collapsed.
Click to expand it.
c++/src/capnproto/dynamic.h
View file @
b2edb433
This diff is collapsed.
Click to expand it.
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