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
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
487 additions
and
16 deletions
+487
-16
any-test.c++
c++/src/capnp/any-test.c++
+74
-0
any.h
c++/src/capnp/any.h
+343
-9
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
...
...
@@ -25,6 +25,7 @@
#include "layout.h"
#include "pointer-helpers.h"
#include "orphan.h"
#include "list.h"
namespace
capnp
{
...
...
@@ -35,6 +36,36 @@ class Orphanage;
class
ClientHook
;
class
PipelineHook
;
struct
PipelineOp
;
struct
AnyPointer
;
struct
AnyList
{
AnyList
()
=
delete
;
class
Reader
;
class
Builder
;
};
struct
AnyStruct
{
AnyStruct
()
=
delete
;
class
Reader
;
class
Builder
;
class
Pipeline
;
};
template
<>
struct
List
<
AnyStruct
,
Kind
::
OTHER
>
{
List
()
=
delete
;
class
Reader
;
class
Builder
;
};
namespace
_
{
// private
template
<>
struct
Kind_
<
AnyPointer
>
{
static
constexpr
Kind
kind
=
Kind
::
OTHER
;
};
template
<>
struct
Kind_
<
AnyStruct
>
{
static
constexpr
Kind
kind
=
Kind
::
OTHER
;
};
template
<>
struct
Kind_
<
AnyList
>
{
static
constexpr
Kind
kind
=
Kind
::
OTHER
;
};
}
// namespace _ (private)
// =======================================================================================
// AnyPointer!
...
...
@@ -43,6 +74,8 @@ struct AnyPointer {
// Reader/Builder for the `AnyPointer` field type, i.e. a pointer that can point to an arbitrary
// object.
AnyPointer
()
=
delete
;
class
Reader
{
public
:
typedef
AnyPointer
Reads
;
...
...
@@ -54,6 +87,12 @@ struct AnyPointer {
// Get the total size of the target object and all its children.
inline
bool
isNull
()
const
;
inline
bool
isStruct
()
{
return
reader
.
isStruct
();
}
inline
bool
isList
()
{
return
reader
.
isList
();
}
template
<
typename
T
>
inline
ReaderFor
<
T
>
getAs
()
const
;
...
...
@@ -96,6 +135,12 @@ struct AnyPointer {
// Get the total size of the target object and all its children.
inline
bool
isNull
();
inline
bool
isStruct
()
{
return
builder
.
isStruct
();
}
inline
bool
isList
()
{
return
builder
.
isList
();
}
inline
void
clear
();
// Set to null.
...
...
@@ -132,6 +177,13 @@ struct AnyPointer {
inline
BuilderFor
<
T
>
initAs
(
ListSchema
schema
,
uint
elementCount
);
// Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
inline
AnyList
::
Builder
initAsAnyList
(
_
::
FieldSize
elementSize
,
uint
elementCount
);
// Note: Does not accept INLINE_COMPOSITE for elementSize.
inline
List
<
AnyStruct
>::
Builder
initAsListOfAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
,
uint
elementCount
);
inline
AnyStruct
::
Builder
initAsAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
);
template
<
typename
T
>
inline
void
setAs
(
ReaderFor
<
T
>
value
);
// Valid for ReaderType = T::Reader for T = any generated struct type, List<U>, Text, Data,
...
...
@@ -195,11 +247,9 @@ struct AnyPointer {
// Just make a copy.
Pipeline
getPointerField
(
uint16_t
pointerIndex
);
// Return a new Promise representing a sub-object of the result. `pointerIndex` is the index
// of the sub-object within the pointer section of the result (the result must be a struct).
//
// TODO(kenton): On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies.
// Also make `ops` into a Vector to optimize this.
// Deprecated. In the future, we should use .asAnyStruct.getPointerField.
inline
AnyStruct
::
Pipeline
asAnyStruct
();
kj
::
Own
<
ClientHook
>
asCap
();
// Expect that the result is a capability and construct a pipelined version of it now.
...
...
@@ -284,6 +334,282 @@ private:
friend
class
AnyPointer
::
Builder
;
};
struct
AnyList
;
struct
AnyStruct
;
template
<
Kind
k
>
struct
AnyTypeFor_
;
template
<>
struct
AnyTypeFor_
<
Kind
::
STRUCT
>
{
typedef
AnyStruct
Type
;
};
template
<>
struct
AnyTypeFor_
<
Kind
::
LIST
>
{
typedef
AnyList
Type
;
};
template
<
typename
T
>
using
AnyTypeFor
=
typename
AnyTypeFor_
<
kind
<
T
>
()
>::
Type
;
template
<
typename
T
>
inline
ReaderFor
<
AnyTypeFor
<
FromReader
<
T
>>>
toAny
(
T
&&
value
)
{
return
ReaderFor
<
AnyTypeFor
<
FromReader
<
T
>
>
>
(
_
::
PointerHelpers
<
FromReader
<
T
>>::
getInternalReader
(
value
));
}
template
<
typename
T
>
inline
BuilderFor
<
AnyTypeFor
<
FromBuilder
<
T
>>>
toAny
(
T
&&
value
)
{
return
BuilderFor
<
AnyTypeFor
<
FromBuilder
<
T
>
>
>
(
_
::
PointerHelpers
<
FromBuilder
<
T
>>::
getInternalBuilder
(
kj
::
mv
(
value
)));
}
template
<>
struct
List
<
AnyPointer
,
Kind
::
OTHER
>
{
List
()
=
delete
;
class
Reader
{
public
:
typedef
List
<
AnyPointer
>
Reads
;
Reader
()
=
default
;
inline
explicit
Reader
(
_
::
ListReader
reader
)
:
reader
(
reader
)
{}
inline
uint
size
()
const
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
typename
AnyPointer
::
Reader
operator
[](
uint
index
)
const
{
KJ_IREQUIRE
(
index
<
size
());
return
typename
AnyPointer
::
Reader
(
reader
.
getPointerElement
(
index
*
ELEMENTS
));
}
typedef
_
::
IndexingIterator
<
const
Reader
,
typename
AnyPointer
::
Reader
>
Iterator
;
inline
Iterator
begin
()
const
{
return
Iterator
(
this
,
0
);
}
inline
Iterator
end
()
const
{
return
Iterator
(
this
,
size
());
}
private
:
_
::
ListReader
reader
;
template
<
typename
U
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
template
<
typename
U
,
Kind
K
>
friend
struct
List
;
friend
class
Orphanage
;
template
<
typename
U
,
Kind
K
>
friend
struct
ToDynamic_
;
};
class
Builder
{
public
:
typedef
List
<
AnyPointer
>
Builds
;
Builder
()
=
delete
;
inline
Builder
(
decltype
(
nullptr
))
{}
inline
explicit
Builder
(
_
::
ListBuilder
builder
)
:
builder
(
builder
)
{}
inline
operator
Reader
()
{
return
Reader
(
builder
.
asReader
());
}
inline
Reader
asReader
()
{
return
Reader
(
builder
.
asReader
());
}
inline
uint
size
()
const
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
AnyPointer
::
Builder
operator
[](
uint
index
)
{
KJ_IREQUIRE
(
index
<
size
());
return
typename
AnyPointer
::
Builder
(
builder
.
getPointerElement
(
index
*
ELEMENTS
));
}
typedef
_
::
IndexingIterator
<
Builder
,
typename
AnyPointer
::
Builder
>
Iterator
;
inline
Iterator
begin
()
{
return
Iterator
(
this
,
0
);
}
inline
Iterator
end
()
{
return
Iterator
(
this
,
size
());
}
private
:
_
::
ListBuilder
builder
;
template
<
typename
U
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphanage
;
template
<
typename
U
,
Kind
K
>
friend
struct
ToDynamic_
;
};
};
class
AnyStruct
::
Reader
{
public
:
Reader
()
=
default
;
inline
Reader
(
_
::
StructReader
reader
)
:
_reader
(
reader
)
{}
Data
::
Reader
getDataSection
()
{
return
_reader
.
getDataSectionAsBlob
();
}
List
<
AnyPointer
>::
Reader
getPointerSection
()
{
return
List
<
AnyPointer
>::
Reader
(
_reader
.
getPointerSectionAsList
());
}
template
<
typename
T
>
ReaderFor
<
T
>
as
();
// T must be a struct type.
private
:
_
::
StructReader
_reader
;
};
class
AnyStruct
::
Builder
{
public
:
inline
Builder
(
decltype
(
nullptr
))
{}
inline
Builder
(
_
::
PointerBuilder
builder
,
_
::
StructSize
size
,
const
word
*
defaultValue
=
nullptr
)
:
_builder
(
builder
.
getStruct
(
size
,
defaultValue
))
{}
inline
Builder
(
_
::
StructBuilder
builder
)
:
_builder
(
builder
)
{}
inline
Data
::
Builder
getDataSection
()
{
return
_builder
.
getDataSectionAsBlob
();
}
List
<
AnyPointer
>::
Builder
getPointerSection
()
{
return
List
<
AnyPointer
>::
Builder
(
_builder
.
getPointerSectionAsList
());
}
inline
operator
Reader
()
const
{
return
Reader
(
_builder
.
asReader
());
}
inline
Reader
asReader
()
const
{
return
Reader
(
_builder
.
asReader
());
}
private
:
_
::
StructBuilder
_builder
;
friend
class
Orphanage
;
friend
class
CapBuilderContext
;
};
class
AnyStruct
::
Pipeline
{
public
:
Pipeline
getPointerField
(
uint16_t
pointerIndex
);
// Return a new Promise representing a sub-object of the result. `pointerIndex` is the index
// of the sub-object within the pointer section of the result (the result must be a struct).
//
// TODO(kenton): On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies.
// Also make `ops` into a Vector to optimize this.
private
:
kj
::
Own
<
PipelineHook
>
hook
;
kj
::
Array
<
PipelineOp
>
ops
;
inline
Pipeline
(
kj
::
Own
<
PipelineHook
>&&
hook
,
kj
::
Array
<
PipelineOp
>&&
ops
)
:
hook
(
kj
::
mv
(
hook
)),
ops
(
kj
::
mv
(
ops
))
{}
};
class
List
<
AnyStruct
,
Kind
::
OTHER
>::
Reader
{
public
:
typedef
List
<
AnyStruct
>
Reads
;
Reader
()
=
default
;
inline
explicit
Reader
(
_
::
ListReader
reader
)
:
reader
(
reader
)
{}
inline
uint
size
()
const
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
typename
AnyStruct
::
Reader
operator
[](
uint
index
)
const
{
KJ_IREQUIRE
(
index
<
size
());
return
typename
AnyStruct
::
Reader
(
reader
.
getStructElement
(
index
*
ELEMENTS
));
}
typedef
_
::
IndexingIterator
<
const
Reader
,
typename
AnyStruct
::
Reader
>
Iterator
;
inline
Iterator
begin
()
const
{
return
Iterator
(
this
,
0
);
}
inline
Iterator
end
()
const
{
return
Iterator
(
this
,
size
());
}
private
:
_
::
ListReader
reader
;
template
<
typename
U
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
template
<
typename
U
,
Kind
K
>
friend
struct
List
;
friend
class
Orphanage
;
template
<
typename
U
,
Kind
K
>
friend
struct
ToDynamic_
;
};
class
List
<
AnyStruct
,
Kind
::
OTHER
>::
Builder
{
public
:
typedef
List
<
AnyStruct
>
Builds
;
Builder
()
=
delete
;
inline
Builder
(
decltype
(
nullptr
))
{}
inline
explicit
Builder
(
_
::
ListBuilder
builder
)
:
builder
(
builder
)
{}
inline
operator
Reader
()
{
return
Reader
(
builder
.
asReader
());
}
inline
Reader
asReader
()
{
return
Reader
(
builder
.
asReader
());
}
inline
uint
size
()
const
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
typename
AnyStruct
::
Builder
operator
[](
uint
index
)
{
KJ_IREQUIRE
(
index
<
size
());
return
typename
AnyStruct
::
Builder
(
builder
.
getStructElement
(
index
*
ELEMENTS
));
}
typedef
_
::
IndexingIterator
<
Builder
,
typename
AnyStruct
::
Builder
>
Iterator
;
inline
Iterator
begin
()
{
return
Iterator
(
this
,
0
);
}
inline
Iterator
end
()
{
return
Iterator
(
this
,
size
());
}
private
:
_
::
ListBuilder
builder
;
template
<
typename
U
,
Kind
K
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphanage
;
template
<
typename
U
,
Kind
K
>
friend
struct
ToDynamic_
;
};
class
AnyList
::
Reader
{
public
:
Reader
()
=
default
;
inline
Reader
(
_
::
ListReader
reader
)
:
_reader
(
reader
)
{}
_
::
FieldSize
getElementSize
();
ElementCount
size
()
{
return
_reader
.
size
();
}
template
<
typename
T
>
ReaderFor
<
T
>
as
()
{
// T must be List<U>.
return
ReaderFor
<
T
>
(
_reader
);
}
private
:
_
::
ListReader
_reader
;
};
class
AnyList
::
Builder
{
public
:
inline
Builder
(
decltype
(
nullptr
))
{}
inline
Builder
(
_
::
PointerBuilder
builder
,
_
::
FieldSize
size
,
const
word
*
defaultValue
=
nullptr
)
:
_builder
(
builder
.
getList
(
size
,
defaultValue
))
{}
inline
Builder
(
_
::
ListBuilder
builder
)
:
_builder
(
builder
)
{}
_
::
FieldSize
getElementSize
();
ElementCount
size
()
{
return
_builder
.
size
();
}
template
<
typename
T
>
BuilderFor
<
T
>
as
()
{
// T must be List<U>.
return
BuilderFor
<
T
>
(
_builder
);
}
inline
operator
Reader
()
const
{
return
Reader
(
_builder
.
asReader
());
}
inline
Reader
asReader
()
const
{
return
Reader
(
_builder
.
asReader
());
}
private
:
_
::
ListBuilder
_builder
;
};
namespace
_
{
// (private)
template
<>
struct
PointerHelpers
<
AnyStruct
,
Kind
::
OTHER
>
{
static
inline
typename
AnyStruct
::
Reader
get
(
PointerReader
reader
,
const
word
*
defaultValue
=
nullptr
)
{
return
typename
AnyStruct
::
Reader
(
reader
.
getStruct
(
defaultValue
));
}
static
inline
typename
AnyStruct
::
Builder
get
(
PointerBuilder
builder
,
const
word
*
defaultValue
=
nullptr
)
{
return
typename
AnyStruct
::
Builder
(
builder
,
/* TODO: allow specifying the size! */
_
::
StructSize
(
0
,
0
),
defaultValue
);
}
static
inline
typename
AnyStruct
::
Builder
init
(
PointerBuilder
builder
,
uint
dataWordCount
,
uint
pointerCount
)
{
return
typename
AnyStruct
::
Builder
(
builder
.
initStruct
(
StructSize
(
dataWordCount
,
pointerCount
)));
}
};
template
<>
struct
PointerHelpers
<
AnyList
,
Kind
::
OTHER
>
{
static
inline
typename
AnyList
::
Reader
get
(
PointerReader
reader
,
const
word
*
defaultValue
=
nullptr
)
{
return
typename
AnyList
::
Reader
(
reader
.
getList
(
/* TODO: allow specifying the size! */
FieldSize
::
VOID
,
defaultValue
));
}
static
inline
typename
AnyList
::
Builder
get
(
PointerBuilder
builder
,
const
word
*
defaultValue
=
nullptr
)
{
return
typename
AnyList
::
Builder
(
builder
,
/* TODO: allow specifying the size! */
FieldSize
::
VOID
,
defaultValue
);
}
static
inline
typename
AnyList
::
Builder
init
(
PointerBuilder
builder
,
FieldSize
elementSize
,
uint
elementCount
)
{
return
typename
AnyList
::
Builder
(
builder
.
initList
(
elementSize
,
elementCount
));
}
static
inline
typename
AnyList
::
Builder
init
(
PointerBuilder
builder
,
uint
dataWordCount
,
uint
pointerCount
,
uint
elementCount
)
{
return
typename
AnyList
::
Builder
(
builder
.
initStructList
(
elementCount
,
StructSize
(
dataWordCount
,
pointerCount
)));
}
};
}
// end namespace _ (private)
// =======================================================================================
// Pipeline helpers
//
...
...
@@ -335,10 +661,6 @@ private:
// =======================================================================================
// Inline implementation details
namespace
_
{
// private
template
<>
struct
Kind_
<
AnyPointer
>
{
static
constexpr
Kind
kind
=
Kind
::
OTHER
;
};
}
// namespace _ (private)
inline
MessageSize
AnyPointer
::
Reader
::
targetSize
()
const
{
return
reader
.
targetSize
().
asPublic
();
}
...
...
@@ -379,6 +701,16 @@ inline BuilderFor<T> AnyPointer::Builder::initAs(uint elementCount) {
return
_
::
PointerHelpers
<
T
>::
init
(
builder
,
elementCount
);
}
inline
AnyList
::
Builder
AnyPointer
::
Builder
::
initAsAnyList
(
_
::
FieldSize
elementSize
,
uint
elementCount
)
{
return
_
::
PointerHelpers
<
AnyList
>::
init
(
builder
,
elementSize
,
elementCount
);
}
// inline List<AnyStruct>::Builder AnyPointer::Builder::initAsListOfAnyStruct(uint dataWordCount, uint pointerCount, uint elementCount);
inline
AnyStruct
::
Builder
AnyPointer
::
Builder
::
initAsAnyStruct
(
uint
dataWordCount
,
uint
pointerCount
)
{
return
_
::
PointerHelpers
<
AnyStruct
>::
init
(
builder
,
dataWordCount
,
pointerCount
);
}
template
<
typename
T
>
inline
void
AnyPointer
::
Builder
::
setAs
(
ReaderFor
<
T
>
value
)
{
return
_
::
PointerHelpers
<
T
>::
set
(
builder
,
value
);
...
...
@@ -406,6 +738,8 @@ inline Orphan<AnyPointer> AnyPointer::Builder::disown() {
template
<>
struct
ReaderFor_
<
AnyPointer
,
Kind
::
OTHER
>
{
typedef
AnyPointer
::
Reader
Type
;
};
template
<>
struct
BuilderFor_
<
AnyPointer
,
Kind
::
OTHER
>
{
typedef
AnyPointer
::
Builder
Type
;
};
template
<>
struct
ReaderFor_
<
AnyStruct
,
Kind
::
OTHER
>
{
typedef
AnyStruct
::
Reader
Type
;
};
template
<>
struct
BuilderFor_
<
AnyStruct
,
Kind
::
OTHER
>
{
typedef
AnyStruct
::
Builder
Type
;
};
template
<>
struct
Orphanage
::
GetInnerReader
<
AnyPointer
,
Kind
::
OTHER
>
{
...
...
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