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
d99c0b4c
Commit
d99c0b4c
authored
Sep 24, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove DynamicObject. DynamicValue can now contain an ObjectPointer to represent object fields.
parent
2b643930
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
147 additions
and
24 deletions
+147
-24
node-translator.c++
c++/src/capnp/compiler/node-translator.c++
+3
-3
dynamic-test.c++
c++/src/capnp/dynamic-test.c++
+12
-6
dynamic.c++
c++/src/capnp/dynamic.c++
+0
-0
dynamic.h
c++/src/capnp/dynamic.h
+0
-0
layout.c++
c++/src/capnp/layout.c++
+29
-8
layout.h
c++/src/capnp/layout.h
+4
-0
object.h
c++/src/capnp/object.h
+96
-0
orphan-test.c++
c++/src/capnp/orphan-test.c++
+3
-5
stringify.c++
c++/src/capnp/stringify.c++
+0
-2
No files found.
c++/src/capnp/compiler/node-translator.c++
View file @
d99c0b4c
...
...
@@ -1811,13 +1811,13 @@ kj::Maybe<DynamicValue::Reader> NodeTranslator::readConstant(
if
(
constValue
.
getType
()
==
DynamicValue
::
OBJECT
)
{
// We need to assign an appropriate schema to this object.
DynamicObject
::
Reader
objValue
=
constValue
.
as
<
DynamicObject
>
();
ObjectPointer
::
Reader
objValue
=
constValue
.
as
<
ObjectPointer
>
();
auto
constType
=
constReader
.
getType
();
switch
(
constType
.
which
())
{
case
schema
:
:
Type
::
STRUCT
:
KJ_IF_MAYBE
(
structSchema
,
resolver
.
resolveBootstrapSchema
(
constType
.
getStruct
().
getTypeId
()))
{
constValue
=
objValue
.
as
(
structSchema
->
asStruct
());
constValue
=
objValue
.
getAs
<
DynamicStruct
>
(
structSchema
->
asStruct
());
}
else
{
// The struct's schema is broken for reasons already reported.
return
nullptr
;
...
...
@@ -1825,7 +1825,7 @@ kj::Maybe<DynamicValue::Reader> NodeTranslator::readConstant(
break
;
case
schema
:
:
Type
::
LIST
:
KJ_IF_MAYBE
(
listSchema
,
makeListSchemaOf
(
constType
.
getList
().
getElementType
()))
{
constValue
=
objValue
.
as
(
*
listSchema
);
constValue
=
objValue
.
getAs
<
DynamicList
>
(
*
listSchema
);
}
else
{
// The list's schema is broken for reasons already reported.
return
nullptr
;
...
...
c++/src/capnp/dynamic-test.c++
View file @
d99c0b4c
...
...
@@ -191,11 +191,14 @@ TEST(DynamicApi, DynamicGenericObjects) {
checkTestMessage
(
root
.
asReader
().
as
<
test
::
TestObject
>
().
getObjectField
().
getAs
<
TestAllTypes
>
());
checkDynamicTestMessage
(
root
.
asReader
().
get
(
"objectField"
).
as
<
DynamicObject
>
().
as
(
Schema
::
from
<
TestAllTypes
>
()));
root
.
asReader
().
get
(
"objectField"
).
as
<
ObjectPointer
>
()
.
getAs
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
root
.
asReader
().
get
(
"objectField"
).
as
<
DynamicObject
>
().
as
(
Schema
::
from
<
TestAllTypes
>
()));
root
.
asReader
().
get
(
"objectField"
).
as
<
ObjectPointer
>
()
.
getAs
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
root
.
get
(
"objectField"
).
as
<
DynamicObject
>
().
asReader
().
as
(
Schema
::
from
<
TestAllTypes
>
()));
root
.
get
(
"objectField"
).
as
<
ObjectPointer
>
().
asReader
()
.
getAs
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
root
.
getObject
(
"objectField"
,
Schema
::
from
<
TestAllTypes
>
()));
...
...
@@ -218,13 +221,16 @@ TEST(DynamicApi, DynamicGenericObjects) {
}
checkList
<
uint32_t
>
(
root
.
asReader
().
get
(
"objectField"
).
as
<
DynamicObject
>
().
as
(
Schema
::
from
<
List
<
uint32_t
>>
()),
root
.
asReader
().
get
(
"objectField"
).
as
<
ObjectPointer
>
()
.
getAs
<
DynamicList
>
(
Schema
::
from
<
List
<
uint32_t
>>
()),
{
123u
,
456u
,
789u
,
123456789u
});
checkList
<
uint32_t
>
(
root
.
asReader
().
get
(
"objectField"
).
as
<
DynamicObject
>
().
as
(
Schema
::
from
<
List
<
uint32_t
>>
()),
root
.
asReader
().
get
(
"objectField"
).
as
<
ObjectPointer
>
()
.
getAs
<
DynamicList
>
(
Schema
::
from
<
List
<
uint32_t
>>
()),
{
123u
,
456u
,
789u
,
123456789u
});
checkList
<
uint32_t
>
(
root
.
get
(
"objectField"
).
as
<
DynamicObject
>
().
asReader
().
as
(
Schema
::
from
<
List
<
uint32_t
>>
()),
root
.
get
(
"objectField"
).
as
<
ObjectPointer
>
().
asReader
()
.
getAs
<
DynamicList
>
(
Schema
::
from
<
List
<
uint32_t
>>
()),
{
123u
,
456u
,
789u
,
123456789u
});
checkList
<
uint32_t
>
(
root
.
getObject
(
"objectField"
,
Schema
::
from
<
List
<
uint32_t
>>
()),
...
...
c++/src/capnp/dynamic.c++
View file @
d99c0b4c
This diff is collapsed.
Click to expand it.
c++/src/capnp/dynamic.h
View file @
d99c0b4c
This diff is collapsed.
Click to expand it.
c++/src/capnp/layout.c++
View file @
d99c0b4c
...
...
@@ -1617,19 +1617,19 @@ struct WireHelpers {
}
}
static
KJ_ALWAYS_INLINE
(
void
setObjectPointer
(
SegmentBuilder
*
segment
,
WirePointer
*
ref
,
ObjectReader
value
))
{
static
KJ_ALWAYS_INLINE
(
SegmentAnd
<
word
*>
setObjectPointer
(
SegmentBuilder
*
segment
,
WirePointer
*
ref
,
ObjectReader
value
,
BuilderArena
*
orphanArena
=
nullptr
))
{
switch
(
value
.
kind
)
{
case
ObjectKind
:
:
NULL_POINTER
:
memset
(
ref
,
0
,
sizeof
(
*
ref
));
break
;
return
{
segment
,
nullptr
}
;
case
ObjectKind
:
:
STRUCT
:
setStructPointer
(
segment
,
ref
,
value
.
structReader
);
break
;
return
setStructPointer
(
segment
,
ref
,
value
.
structReader
,
orphanArena
);
case
ObjectKind
:
:
LIST
:
setListPointer
(
segment
,
ref
,
value
.
listReader
);
break
;
return
setListPointer
(
segment
,
ref
,
value
.
listReader
,
orphanArena
);
}
KJ_UNREACHABLE
;
}
static
void
adopt
(
SegmentBuilder
*
segment
,
WirePointer
*
ref
,
OrphanBuilder
&&
value
)
{
...
...
@@ -2139,7 +2139,7 @@ void PointerBuilder::setList(const ListReader& value) {
}
void
PointerBuilder
::
setObject
(
const
ObjectReader
&
value
)
{
return
WireHelpers
::
setObjectPointer
(
segment
,
pointer
,
value
);
WireHelpers
::
setObjectPointer
(
segment
,
pointer
,
value
);
}
void
PointerBuilder
::
adopt
(
OrphanBuilder
&&
value
)
{
...
...
@@ -2159,6 +2159,18 @@ bool PointerBuilder::isNull() {
return
pointer
->
isNull
();
}
void
PointerBuilder
::
transferFrom
(
PointerBuilder
other
)
{
WireHelpers
::
transferPointer
(
segment
,
pointer
,
other
.
segment
,
other
.
pointer
);
}
void
PointerBuilder
::
copyFrom
(
PointerReader
other
)
{
WireHelpers
::
setObjectPointer
(
segment
,
pointer
,
other
.
getObject
(
nullptr
));
}
PointerReader
PointerBuilder
::
asReader
()
const
{
return
PointerReader
(
segment
,
pointer
,
std
::
numeric_limits
<
int
>::
max
());
}
// =======================================================================================
// PointerReader
...
...
@@ -2541,6 +2553,15 @@ OrphanBuilder OrphanBuilder::copy(BuilderArena* arena, ListReader copyFrom) {
return
result
;
}
OrphanBuilder
OrphanBuilder
::
copy
(
BuilderArena
*
arena
,
PointerReader
copyFrom
)
{
OrphanBuilder
result
;
auto
allocation
=
WireHelpers
::
setObjectPointer
(
nullptr
,
result
.
tagAsPtr
(),
copyFrom
.
getObject
(
nullptr
),
arena
);
result
.
segment
=
allocation
.
segment
;
result
.
location
=
reinterpret_cast
<
word
*>
(
allocation
.
value
);
return
result
;
}
OrphanBuilder
OrphanBuilder
::
copy
(
BuilderArena
*
arena
,
Text
::
Reader
copyFrom
)
{
OrphanBuilder
result
;
auto
allocation
=
WireHelpers
::
setTextPointer
(
...
...
c++/src/capnp/layout.h
View file @
d99c0b4c
...
...
@@ -316,6 +316,8 @@ public:
void
copyFrom
(
PointerReader
other
);
// Equivalent to `set(other.get())`.
PointerReader
asReader
()
const
;
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the pointer resides.
WirePointer
*
pointer
;
// Pointer to the pointer.
...
...
@@ -360,6 +362,7 @@ private:
friend
class
StructReader
;
friend
class
ListReader
;
friend
class
PointerBuilder
;
};
// -------------------------------------------------------------------
...
...
@@ -739,6 +742,7 @@ public:
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
StructReader
copyFrom
);
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
ListReader
copyFrom
);
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
PointerReader
copyFrom
);
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
Text
::
Reader
copyFrom
);
static
OrphanBuilder
copy
(
BuilderArena
*
arena
,
Data
::
Reader
copyFrom
);
...
...
c++/src/capnp/object.h
View file @
d99c0b4c
...
...
@@ -26,11 +26,13 @@
#include "layout.h"
#include "pointer-helpers.h"
#include "orphan.h"
namespace
capnp
{
class
StructSchema
;
class
ListSchema
;
class
Orphanage
;
struct
ObjectPointer
{
// Reader/Builder for the `Object` field type, i.e. a pointer that can point to an arbitrary
...
...
@@ -38,6 +40,8 @@ struct ObjectPointer {
class
Reader
{
public
:
typedef
ObjectPointer
Reads
;
Reader
()
=
default
;
inline
Reader
(
_
::
PointerReader
reader
)
:
reader
(
reader
)
{}
...
...
@@ -57,10 +61,14 @@ struct ObjectPointer {
private
:
_
::
PointerReader
reader
;
friend
struct
ObjectPointer
;
friend
class
Orphanage
;
};
class
Builder
{
public
:
typedef
ObjectPointer
Builds
;
Builder
()
=
delete
;
inline
Builder
(
decltype
(
nullptr
))
{}
inline
Builder
(
_
::
PointerBuilder
builder
)
:
builder
(
builder
)
{}
...
...
@@ -107,6 +115,9 @@ struct ObjectPointer {
inline
void
setAs
(
std
::
initializer_list
<
ReaderFor
<
ListElementType
<
T
>>>
list
);
// Valid for T = List<?>.
inline
void
set
(
Reader
value
)
{
builder
.
copyFrom
(
value
.
reader
);
}
// Set to a copy of another ObjectPointer.
template
<
typename
T
>
inline
void
adopt
(
Orphan
<
T
>&&
orphan
);
// Valid for T = any generated struct type, List<U>, Text, Data, DynamicList, DynamicStruct,
...
...
@@ -124,11 +135,69 @@ struct ObjectPointer {
inline
Orphan
<
T
>
disownAs
(
ListSchema
schema
);
// Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
inline
Orphan
<
ObjectPointer
>
disown
();
// Disown without a type.
inline
Reader
asReader
()
const
{
return
Reader
(
builder
.
asReader
());
}
inline
operator
Reader
()
const
{
return
Reader
(
builder
.
asReader
());
}
private
:
_
::
PointerBuilder
builder
;
};
};
template
<>
class
Orphan
<
ObjectPointer
>
{
// An orphaned object of unknown type.
public
:
Orphan
()
=
default
;
KJ_DISALLOW_COPY
(
Orphan
);
Orphan
(
Orphan
&&
)
=
default
;
Orphan
&
operator
=
(
Orphan
&&
)
=
default
;
// It's not possible to get an ObjectPointer::{Reader,Builder} directly since there is no
// underlying pointer (the pointer would normally live in the parent, but this object is
// orphaned). It is possible, however, to request readers/builders.
template
<
typename
T
>
inline
typename
T
::
Builder
getAs
();
template
<
typename
T
>
inline
typename
T
::
Builder
getAs
(
StructSchema
schema
);
template
<
typename
T
>
inline
typename
T
::
Builder
getAs
(
ListSchema
schema
);
template
<
typename
T
>
inline
typename
T
::
Reader
getAsReader
()
const
;
template
<
typename
T
>
inline
typename
T
::
Reader
getAsReader
(
StructSchema
schema
)
const
;
template
<
typename
T
>
inline
typename
T
::
Reader
getAsReader
(
ListSchema
schema
)
const
;
template
<
typename
T
>
inline
Orphan
<
T
>
releaseAs
();
template
<
typename
T
>
inline
Orphan
<
T
>
releaseAs
(
StructSchema
schema
);
template
<
typename
T
>
inline
Orphan
<
T
>
releaseAs
(
ListSchema
schema
);
// Down-cast the orphan to a specific type.
inline
bool
operator
==
(
decltype
(
nullptr
))
const
{
return
builder
==
nullptr
;
}
inline
bool
operator
!=
(
decltype
(
nullptr
))
const
{
return
builder
!=
nullptr
;
}
private
:
_
::
OrphanBuilder
builder
;
inline
Orphan
(
_
::
OrphanBuilder
&&
builder
)
:
builder
(
kj
::
mv
(
builder
))
{}
template
<
typename
,
Kind
>
friend
struct
_
::
PointerHelpers
;
friend
class
Orphanage
;
template
<
typename
U
>
friend
class
Orphan
;
friend
class
ObjectPointer
::
Builder
;
};
// =======================================================================================
// Inline implementation details
...
...
@@ -185,6 +254,33 @@ inline Orphan<T> ObjectPointer::Builder::disownAs() {
return
_
::
PointerHelpers
<
T
>::
disown
(
builder
);
}
inline
Orphan
<
ObjectPointer
>
ObjectPointer
::
Builder
::
disown
()
{
return
Orphan
<
ObjectPointer
>
(
builder
.
disown
());
}
template
<>
struct
ReaderFor_
<
ObjectPointer
,
Kind
::
UNKNOWN
>
{
typedef
ObjectPointer
::
Reader
Type
;
};
template
<>
struct
BuilderFor_
<
ObjectPointer
,
Kind
::
UNKNOWN
>
{
typedef
ObjectPointer
::
Builder
Type
;
};
template
<>
struct
Orphanage
::
GetInnerReader
<
ObjectPointer
,
Kind
::
UNKNOWN
>
{
static
inline
_
::
PointerReader
apply
(
const
ObjectPointer
::
Reader
&
t
)
{
return
t
.
reader
;
}
};
template
<
typename
T
>
inline
typename
T
::
Builder
Orphan
<
ObjectPointer
>::
getAs
()
{
return
_
::
OrphanGetImpl
<
T
>::
apply
(
builder
);
}
template
<
typename
T
>
inline
typename
T
::
Reader
Orphan
<
ObjectPointer
>::
getAsReader
()
const
{
return
_
::
OrphanGetImpl
<
T
>::
applyReader
(
builder
);
}
template
<
typename
T
>
inline
Orphan
<
T
>
Orphan
<
ObjectPointer
>::
releaseAs
()
{
return
Orphan
<
T
>
(
kj
::
mv
(
builder
));
}
}
// namespace capnp
#endif // CAPNP_OBJECT_H_
c++/src/capnp/orphan-test.c++
View file @
d99c0b4c
...
...
@@ -529,14 +529,12 @@ TEST(Orphans, DynamicObject) {
initTestMessage
(
root
.
getObjectField
().
initAs
<
TestAllTypes
>
());
EXPECT_TRUE
(
root
.
hasObjectField
());
Orphan
<
DynamicValue
>
orphan
=
root
.
getObjectField
().
disown
As
<
DynamicObject
>
();
Orphan
<
DynamicValue
>
orphan
=
root
.
getObjectField
().
disown
();
EXPECT_EQ
(
DynamicValue
::
OBJECT
,
orphan
.
getType
());
checkTestMessage
(
orphan
.
getReader
().
as
<
DynamicObject
>
().
as
<
TestAllTypes
>
());
Orphan
<
DynamicObject
>
objectOrphan
=
orphan
.
releaseAs
<
DynamicObject
>
();
Orphan
<
ObjectPointer
>
objectOrphan
=
orphan
.
releaseAs
<
ObjectPointer
>
();
checkTestMessage
(
objectOrphan
.
getAs
<
TestAllTypes
>
());
checkDynamicTestMessage
(
objectOrphan
.
getAs
(
Schema
::
from
<
TestAllTypes
>
()));
checkDynamicTestMessage
(
objectOrphan
.
getAs
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
()));
}
TEST
(
Orphans
,
DynamicDisown
)
{
...
...
c++/src/capnp/stringify.c++
View file @
d99c0b4c
...
...
@@ -267,8 +267,6 @@ kj::StringTree prettyPrint(DynamicList::Builder value) { return prettyPrint(valu
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicValue
::
Reader
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicValue
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
DynamicEnum
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicObject
::
Reader
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicObject
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicStruct
::
Reader
&
value
)
{
return
stringify
(
value
);
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicStruct
::
Builder
&
value
)
{
return
stringify
(
value
.
asReader
());
}
kj
::
StringTree
KJ_STRINGIFY
(
const
DynamicList
::
Reader
&
value
)
{
return
stringify
(
value
);
}
...
...
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