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
fff8e987
Commit
fff8e987
authored
Nov 09, 2014
by
Kenton Varda
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:kentonv/capnproto
parents
6b35c286
bd763a00
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
144 additions
and
7 deletions
+144
-7
any-test.c++
c++/src/capnp/any-test.c++
+74
-0
any.h
c++/src/capnp/any.h
+0
-0
capnpc-c++.c++
c++/src/capnp/compiler/capnpc-c++.c++
+2
-0
layout.c++
c++/src/capnp/layout.c++
+31
-0
layout.h
c++/src/capnp/layout.h
+15
-0
list.h
c++/src/capnp/list.h
+8
-0
pointer-helpers.h
c++/src/capnp/pointer-helpers.h
+10
-4
encoding.md
doc/encoding.md
+2
-2
index.md
doc/index.md
+1
-1
rpc.md
doc/rpc.md
+1
-0
No files found.
c++/src/capnp/any-test.c++
View file @
fff8e987
...
...
@@ -106,6 +106,80 @@ TEST(Any, AnyPointer) {
}
}
TEST
(
Any
,
AnyStruct
)
{
MallocMessageBuilder
builder
;
auto
root
=
builder
.
getRoot
<
test
::
TestAnyPointer
>
();
initTestMessage
(
root
.
getAnyPointerField
().
initAs
<
TestAllTypes
>
());
checkTestMessage
(
root
.
getAnyPointerField
().
getAs
<
TestAllTypes
>
());
checkTestMessage
(
root
.
asReader
().
getAnyPointerField
().
getAs
<
TestAllTypes
>
());
EXPECT_EQ
(
48
,
root
.
getAnyPointerField
().
getAs
<
AnyStruct
>
().
getDataSection
().
size
());
EXPECT_EQ
(
20
,
root
.
getAnyPointerField
().
getAs
<
AnyStruct
>
().
getPointerSection
().
size
());
EXPECT_EQ
(
48
,
root
.
getAnyPointerField
().
asReader
().
getAs
<
AnyStruct
>
().
getDataSection
().
size
());
EXPECT_EQ
(
20
,
root
.
getAnyPointerField
().
asReader
().
getAs
<
AnyStruct
>
().
getPointerSection
().
size
());
auto
b
=
toAny
(
root
.
getAnyPointerField
().
getAs
<
TestAllTypes
>
());
EXPECT_EQ
(
48
,
b
.
getDataSection
().
size
());
EXPECT_EQ
(
20
,
b
.
getPointerSection
().
size
());
auto
r
=
toAny
(
root
.
getAnyPointerField
().
getAs
<
TestAllTypes
>
().
asReader
());
EXPECT_EQ
(
48
,
r
.
getDataSection
().
size
());
EXPECT_EQ
(
20
,
r
.
getPointerSection
().
size
());
r
=
toAny
(
root
.
getAnyPointerField
().
getAs
<
TestAllTypes
>
()).
asReader
();
EXPECT_EQ
(
48
,
r
.
getDataSection
().
size
());
EXPECT_EQ
(
20
,
r
.
getPointerSection
().
size
());
{
MallocMessageBuilder
b2
;
auto
root2
=
b2
.
getRoot
<
test
::
TestAnyPointer
>
();
auto
sb
=
root2
.
getAnyPointerField
().
initAsAnyStruct
(
r
.
getDataSection
().
size
()
/
8
,
r
.
getPointerSection
().
size
());
EXPECT_EQ
(
48
,
sb
.
getDataSection
().
size
());
EXPECT_EQ
(
20
,
sb
.
getPointerSection
().
size
());
// TODO: is there a higher-level API for this?
memcpy
(
sb
.
getDataSection
().
begin
(),
r
.
getDataSection
().
begin
(),
r
.
getDataSection
().
size
());
}
}
TEST
(
Any
,
AnyList
)
{
MallocMessageBuilder
builder
;
auto
root
=
builder
.
getRoot
<
test
::
TestAnyPointer
>
();
List
<
TestAllTypes
>::
Builder
b
=
root
.
getAnyPointerField
().
initAs
<
List
<
TestAllTypes
>>
(
2
);
initTestMessage
(
b
[
0
]);
auto
ptr
=
root
.
getAnyPointerField
().
getAs
<
AnyList
>
();
EXPECT_EQ
(
2
,
ptr
.
size
());
EXPECT_EQ
(
48
,
ptr
.
as
<
List
<
AnyStruct
>>
()[
0
].
getDataSection
().
size
());
EXPECT_EQ
(
20
,
ptr
.
as
<
List
<
AnyStruct
>>
()[
0
].
getPointerSection
().
size
());
auto
readPtr
=
root
.
getAnyPointerField
().
asReader
().
getAs
<
AnyList
>
();
EXPECT_EQ
(
2
,
readPtr
.
size
());
EXPECT_EQ
(
48
,
readPtr
.
as
<
List
<
AnyStruct
>>
()[
0
].
getDataSection
().
size
());
EXPECT_EQ
(
20
,
readPtr
.
as
<
List
<
AnyStruct
>>
()[
0
].
getPointerSection
().
size
());
auto
alb
=
toAny
(
root
.
getAnyPointerField
().
getAs
<
List
<
TestAllTypes
>>
());
EXPECT_EQ
(
2
,
alb
.
size
());
EXPECT_EQ
(
48
,
alb
.
as
<
List
<
AnyStruct
>>
()[
0
].
getDataSection
().
size
());
EXPECT_EQ
(
20
,
alb
.
as
<
List
<
AnyStruct
>>
()[
0
].
getPointerSection
().
size
());
auto
alr
=
toAny
(
root
.
getAnyPointerField
().
getAs
<
List
<
TestAllTypes
>>
().
asReader
());
EXPECT_EQ
(
2
,
alr
.
size
());
EXPECT_EQ
(
48
,
alr
.
as
<
List
<
AnyStruct
>>
()[
0
].
getDataSection
().
size
());
EXPECT_EQ
(
20
,
alr
.
as
<
List
<
AnyStruct
>>
()[
0
].
getPointerSection
().
size
());
alr
=
toAny
(
root
.
getAnyPointerField
().
getAs
<
List
<
TestAllTypes
>>
()).
asReader
();
EXPECT_EQ
(
2
,
alr
.
size
());
EXPECT_EQ
(
48
,
alr
.
as
<
List
<
AnyStruct
>>
()[
0
].
getDataSection
().
size
());
EXPECT_EQ
(
20
,
alr
.
as
<
List
<
AnyStruct
>>
()[
0
].
getPointerSection
().
size
());
}
}
// namespace
}
// namespace _ (private)
}
// namespace capnp
c++/src/capnp/any.h
View file @
fff8e987
This diff is collapsed.
Click to expand it.
c++/src/capnp/compiler/capnpc-c++.c++
View file @
fff8e987
...
...
@@ -1700,6 +1700,8 @@ private:
" template <typename, ::capnp::Kind>
\n
"
" friend struct ::capnp::ToDynamic_;
\n
"
" friend class ::capnp::Orphanage;
\n
"
,
" template <typename, ::capnp::Kind>
\n
"
" friend struct ::capnp::_::PointerHelpers;
\n
"
"};
\n
"
"
\n
"
);
}
...
...
c++/src/capnp/layout.c++
View file @
fff8e987
...
...
@@ -251,6 +251,7 @@ struct WirePointer {
// our "null" value.
return
(
offsetAndKind
.
get
()
==
0
)
&
(
upper32Bits
==
0
);
}
};
static_assert
(
sizeof
(
WirePointer
)
==
sizeof
(
word
),
"capnp::WirePointer is not exactly one word. This will probably break everything."
);
...
...
@@ -2155,6 +2156,20 @@ bool PointerBuilder::isNull() {
return
pointer
->
isNull
();
}
bool
PointerBuilder
::
isStruct
()
{
word
*
refTarget
;
WirePointer
*
ptr
=
pointer
;
WireHelpers
::
followFars
(
ptr
,
refTarget
,
segment
);
return
ptr
->
kind
()
==
WirePointer
::
Kind
::
STRUCT
;
}
bool
PointerBuilder
::
isList
()
{
word
*
refTarget
;
WirePointer
*
ptr
=
pointer
;
WireHelpers
::
followFars
(
ptr
,
refTarget
,
segment
);
return
ptr
->
kind
()
==
WirePointer
::
Kind
::
LIST
;
}
void
PointerBuilder
::
transferFrom
(
PointerBuilder
other
)
{
if
(
!
pointer
->
isNull
())
{
WireHelpers
::
zeroObject
(
segment
,
pointer
);
...
...
@@ -2238,6 +2253,22 @@ bool PointerReader::isNull() const {
return
pointer
==
nullptr
||
pointer
->
isNull
();
}
bool
PointerReader
::
isStruct
()
const
{
word
*
refTarget
;
const
WirePointer
*
ptr
=
pointer
;
SegmentReader
*
sgmt
=
segment
;
WireHelpers
::
followFars
(
ptr
,
refTarget
,
sgmt
);
return
ptr
->
kind
()
==
WirePointer
::
Kind
::
STRUCT
;
}
bool
PointerReader
::
isList
()
const
{
word
*
refTarget
;
const
WirePointer
*
ptr
=
pointer
;
SegmentReader
*
sgmt
=
segment
;
WireHelpers
::
followFars
(
ptr
,
refTarget
,
sgmt
);
return
ptr
->
kind
()
==
WirePointer
::
Kind
::
LIST
;
}
kj
::
Maybe
<
Arena
&>
PointerReader
::
getArena
()
const
{
return
segment
==
nullptr
?
nullptr
:
segment
->
getArena
();
}
...
...
c++/src/capnp/layout.h
View file @
fff8e987
...
...
@@ -324,6 +324,8 @@ public:
// location.
bool
isNull
();
bool
isStruct
();
bool
isList
();
StructBuilder
getStruct
(
StructSize
size
,
const
word
*
defaultValue
);
ListBuilder
getList
(
FieldSize
elementSize
,
const
word
*
defaultValue
);
...
...
@@ -402,6 +404,8 @@ public:
// exception if it overruns.
bool
isNull
()
const
;
bool
isStruct
()
const
;
bool
isList
()
const
;
StructReader
getStruct
(
const
word
*
defaultValue
)
const
;
ListReader
getList
(
FieldSize
expectedElementSize
,
const
word
*
defaultValue
)
const
;
...
...
@@ -452,6 +456,7 @@ public:
inline
BitCount
getDataSectionSize
()
const
{
return
dataSize
;
}
inline
WirePointerCount
getPointerSectionSize
()
const
{
return
pointerCount
;
}
inline
Data
::
Builder
getDataSectionAsBlob
();
inline
_
::
ListBuilder
getPointerSectionAsList
();
template
<
typename
T
>
KJ_ALWAYS_INLINE
(
bool
hasDataField
(
ElementCount
offset
));
...
...
@@ -532,6 +537,7 @@ public:
inline
BitCount
getDataSectionSize
()
const
{
return
dataSize
;
}
inline
WirePointerCount
getPointerSectionSize
()
const
{
return
pointerCount
;
}
inline
Data
::
Reader
getDataSectionAsBlob
();
inline
_
::
ListReader
getPointerSectionAsList
();
template
<
typename
T
>
KJ_ALWAYS_INLINE
(
bool
hasDataField
(
ElementCount
offset
)
const
);
...
...
@@ -662,6 +668,7 @@ private:
friend
class
StructBuilder
;
friend
struct
WireHelpers
;
friend
class
OrphanBuilder
;
friend
class
AnyStruct
;
};
class
ListReader
{
...
...
@@ -846,6 +853,10 @@ inline Data::Builder StructBuilder::getDataSectionAsBlob() {
return
Data
::
Builder
(
reinterpret_cast
<
byte
*>
(
data
),
dataSize
/
BITS_PER_BYTE
/
BYTES
);
}
inline
_
::
ListBuilder
StructBuilder
::
getPointerSectionAsList
()
{
return
_
::
ListBuilder
(
segment
,
pointers
,
pointerCount
*
BITS_PER_WORD
/
ELEMENTS
,
pointerCount
,
0
,
1
,
FieldSize
::
POINTER
);
}
template
<
typename
T
>
inline
bool
StructBuilder
::
hasDataField
(
ElementCount
offset
)
{
return
getDataField
<
Mask
<
T
>>
(
offset
)
!=
0
;
...
...
@@ -924,6 +935,10 @@ inline Data::Reader StructReader::getDataSectionAsBlob() {
return
Data
::
Reader
(
reinterpret_cast
<
const
byte
*>
(
data
),
dataSize
/
BITS_PER_BYTE
/
BYTES
);
}
inline
_
::
ListReader
StructReader
::
getPointerSectionAsList
()
{
return
_
::
ListReader
(
segment
,
pointers
,
pointerCount
,
pointerCount
*
BITS_PER_WORD
/
ELEMENTS
,
0
,
1
,
FieldSize
::
POINTER
,
nestingLimit
);
}
template
<
typename
T
>
inline
bool
StructReader
::
hasDataField
(
ElementCount
offset
)
const
{
return
getDataField
<
Mask
<
T
>>
(
offset
)
!=
0
;
...
...
c++/src/capnp/list.h
View file @
fff8e987
...
...
@@ -163,6 +163,8 @@ struct List<T, Kind::PRIMITIVE> {
private
:
_
::
ListBuilder
builder
;
template
<
typename
U
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphanage
;
template
<
typename
U
,
Kind
K
>
friend
struct
ToDynamic_
;
...
...
@@ -282,6 +284,8 @@ struct List<T, Kind::STRUCT> {
private
:
_
::
ListBuilder
builder
;
template
<
typename
U
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphanage
;
template
<
typename
U
,
Kind
K
>
friend
struct
ToDynamic_
;
...
...
@@ -391,6 +395,8 @@ struct List<List<T>, Kind::LIST> {
private
:
_
::
ListBuilder
builder
;
template
<
typename
U
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphanage
;
template
<
typename
U
,
Kind
K
>
friend
struct
ToDynamic_
;
...
...
@@ -487,6 +493,8 @@ struct List<T, Kind::BLOB> {
private
:
_
::
ListBuilder
builder
;
template
<
typename
U
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphanage
;
template
<
typename
U
,
Kind
K
>
friend
struct
ToDynamic_
;
...
...
c++/src/capnp/pointer-helpers.h
View file @
fff8e987
...
...
@@ -24,6 +24,7 @@
#include "layout.h"
#include "list.h"
// #include "any.h"
namespace
capnp
{
namespace
_
{
// private
...
...
@@ -53,13 +54,12 @@ struct PointerHelpers<T, Kind::STRUCT> {
static
inline
Orphan
<
T
>
disown
(
PointerBuilder
builder
)
{
return
Orphan
<
T
>
(
builder
.
disown
());
}
static
inline
_
::
StructReader
getInternalReader
(
const
typename
T
::
Reader
&
reader
)
{
// TODO(cleanup): This is used by RpcSystem::Connect, but perhaps it should be used more
// broadly so that we can reduce the number of friends declared by every Reader type.
return
reader
.
_reader
;
}
static
inline
_
::
StructBuilder
getInternalBuilder
(
typename
T
::
Builder
&&
builder
)
{
return
builder
.
_builder
;
}
};
template
<
typename
T
>
...
...
@@ -91,6 +91,12 @@ struct PointerHelpers<List<T>, Kind::LIST> {
static
inline
Orphan
<
List
<
T
>>
disown
(
PointerBuilder
builder
)
{
return
Orphan
<
List
<
T
>>
(
builder
.
disown
());
}
static
inline
_
::
ListReader
getInternalReader
(
const
typename
List
<
T
>::
Reader
&
reader
)
{
return
reader
.
reader
;
}
static
inline
_
::
ListBuilder
getInternalBuilder
(
typename
List
<
T
>::
Builder
&&
builder
)
{
return
builder
.
builder
;
}
};
template
<
typename
T
>
...
...
doc/encoding.md
View file @
fff8e987
...
...
@@ -115,8 +115,8 @@ Lists of structs use the smallest element size in which the struct can fit. So,
list of structs that each contain two
`UInt8`
fields and nothing else could be encoded with C = 3
(2-byte elements). A list of structs that each contain a single
`Text`
field would be encoded as
C = 6 (pointer elements). A list of structs that each contain a single
`Bool`
field would be
encoded using C = 1 (1-bit elements). A list structs which are each more than one word in size
must be
be
encoded using C = 7 (composite).
encoded using C = 1 (1-bit elements). A list
of
structs which are each more than one word in size
must be encoded using C = 7 (composite).
When C = 7, the elements of the list are fixed-width composite values -- usually, structs. In
this case, the list content is prefixed by a "tag" word that describes each individual element.
...
...
doc/index.md
View file @
fff8e987
...
...
@@ -67,7 +67,7 @@ Glad you asked!
order of magnitude or more. In fact, usually it's no more than some inline accessor methods!
*
**Tiny runtime library:**
Due to the simplicity of the Cap'n Proto format, the runtime library
can be much smaller.
*
**Time-traveling RPC:**
Cap'n Proto features an RPC system implements
[
time travel
](
rpc.html
)
*
**Time-traveling RPC:**
Cap'n Proto features an RPC system
that
implements
[
time travel
](
rpc.html
)
such that call results are returned to the client before the request even arrives at the server!
<a
href=
"rpc.html"
><img
src=
'images/time-travel.png'
style=
'max-width:639px'
></a>
...
...
doc/rpc.md
View file @
fff8e987
...
...
@@ -118,6 +118,7 @@ interface Filesystem {
{% endhighlight %}
We've now solved our latency problem... but at what cost?
*
We now have to implement path string manipulation, which is always a headache.
*
If someone wants to perform multiple operations on a file or directory, we now either have to
re-allocate resources for every call or we have to implement some sort of cache, which tends to
...
...
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