Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
d3b18572
Commit
d3b18572
authored
Dec 11, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enable config_value to parse its to_string output
parent
ab7535c7
Changes
29
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
218 additions
and
151 deletions
+218
-151
libcaf_core/caf/binary_deserializer.hpp
libcaf_core/caf/binary_deserializer.hpp
+3
-2
libcaf_core/caf/binary_serializer.hpp
libcaf_core/caf/binary_serializer.hpp
+5
-4
libcaf_core/caf/config_value.hpp
libcaf_core/caf/config_value.hpp
+13
-0
libcaf_core/caf/config_value_reader.hpp
libcaf_core/caf/config_value_reader.hpp
+1
-1
libcaf_core/caf/config_value_writer.hpp
libcaf_core/caf/config_value_writer.hpp
+1
-4
libcaf_core/caf/deserializer.hpp
libcaf_core/caf/deserializer.hpp
+7
-5
libcaf_core/caf/detail/serialized_size.hpp
libcaf_core/caf/detail/serialized_size.hpp
+1
-3
libcaf_core/caf/detail/stringification_inspector.hpp
libcaf_core/caf/detail/stringification_inspector.hpp
+1
-1
libcaf_core/caf/hash/fnv.hpp
libcaf_core/caf/hash/fnv.hpp
+1
-1
libcaf_core/caf/hash/sha1.hpp
libcaf_core/caf/hash/sha1.hpp
+1
-1
libcaf_core/caf/load_inspector.hpp
libcaf_core/caf/load_inspector.hpp
+9
-4
libcaf_core/caf/load_inspector_base.hpp
libcaf_core/caf/load_inspector_base.hpp
+2
-1
libcaf_core/caf/save_inspector.hpp
libcaf_core/caf/save_inspector.hpp
+8
-3
libcaf_core/caf/save_inspector_base.hpp
libcaf_core/caf/save_inspector_base.hpp
+2
-1
libcaf_core/caf/sec.hpp
libcaf_core/caf/sec.hpp
+6
-0
libcaf_core/caf/serializer.hpp
libcaf_core/caf/serializer.hpp
+4
-9
libcaf_core/caf/type_id.hpp
libcaf_core/caf/type_id.hpp
+9
-0
libcaf_core/src/binary_deserializer.cpp
libcaf_core/src/binary_deserializer.cpp
+14
-7
libcaf_core/src/binary_serializer.cpp
libcaf_core/src/binary_serializer.cpp
+0
-4
libcaf_core/src/config_value.cpp
libcaf_core/src/config_value.cpp
+15
-0
libcaf_core/src/config_value_reader.cpp
libcaf_core/src/config_value_reader.cpp
+39
-17
libcaf_core/src/config_value_writer.cpp
libcaf_core/src/config_value_writer.cpp
+3
-16
libcaf_core/src/detail/serialized_size.cpp
libcaf_core/src/detail/serialized_size.cpp
+1
-5
libcaf_core/src/detail/stringification_inspector.cpp
libcaf_core/src/detail/stringification_inspector.cpp
+1
-1
libcaf_core/src/message.cpp
libcaf_core/src/message.cpp
+18
-30
libcaf_core/src/tracing_data.cpp
libcaf_core/src/tracing_data.cpp
+8
-8
libcaf_core/test/config_value.cpp
libcaf_core/test/config_value.cpp
+38
-1
libcaf_core/test/load_inspector.cpp
libcaf_core/test/load_inspector.cpp
+1
-1
libcaf_core/test/save_inspector.cpp
libcaf_core/test/save_inspector.cpp
+6
-21
No files found.
libcaf_core/caf/binary_deserializer.hpp
View file @
d3b18572
...
...
@@ -35,7 +35,8 @@
namespace
caf
{
/// Deserializes objects from sequence of bytes.
/// Deserializes objects from sequence of bytes. Does not perform run-time type
/// checks.
class
CAF_CORE_EXPORT
binary_deserializer
:
public
load_inspector_base
<
binary_deserializer
>
{
public:
...
...
@@ -112,7 +113,7 @@ public:
bool
fetch_next_object_type
(
type_id_t
&
type
)
noexcept
;
constexpr
bool
begin_object
(
string_view
)
noexcept
{
constexpr
bool
begin_object
(
type_id_t
,
string_view
)
noexcept
{
return
true
;
}
...
...
libcaf_core/caf/binary_serializer.hpp
View file @
d3b18572
...
...
@@ -33,7 +33,10 @@
namespace
caf
{
/// Serializes objects into a sequence of bytes.
/// Serializes C++ objects into a sequence of bytes.
/// @note The binary data format may change between CAF versions and does not
/// perform any type checking at run-time. Thus the output of this
/// serializer is unsuitable for persistence layers.
class
CAF_CORE_EXPORT
binary_serializer
:
public
save_inspector_base
<
binary_serializer
>
{
public:
...
...
@@ -95,9 +98,7 @@ public:
// -- interface functions ----------------------------------------------------
bool
inject_next_object_type
(
type_id_t
type
);
constexpr
bool
begin_object
(
string_view
)
{
constexpr
bool
begin_object
(
type_id_t
,
string_view
)
noexcept
{
return
true
;
}
...
...
libcaf_core/caf/config_value.hpp
View file @
d3b18572
...
...
@@ -172,6 +172,9 @@ public:
// -- utility ----------------------------------------------------------------
/// @private
type_id_t
type_id
()
const
noexcept
;
/// @private
error_code
<
sec
>
default_construct
(
type_id_t
);
...
...
@@ -207,6 +210,16 @@ public:
return
{
reader
.
move_error
()};
}
/// @experimental
template
<
class
T
>
error
assign
(
const
T
&
x
)
{
config_value_writer
writer
{
this
};
if
(
detail
::
save
(
writer
,
x
))
return
{};
else
return
{
writer
.
move_error
()};
}
private:
// -- properties -------------------------------------------------------------
...
...
libcaf_core/caf/config_value_reader.hpp
View file @
d3b18572
...
...
@@ -99,7 +99,7 @@ public:
bool
fetch_next_object_type
(
type_id_t
&
type
)
override
;
bool
begin_object
(
string_view
name
)
override
;
bool
begin_object
(
type_id_t
type
,
string_view
name
)
override
;
bool
end_object
()
override
;
...
...
libcaf_core/caf/config_value_writer.hpp
View file @
d3b18572
...
...
@@ -68,9 +68,7 @@ public:
// -- interface functions ----------------------------------------------------
bool
inject_next_object_type
(
type_id_t
type
)
override
;
bool
begin_object
(
string_view
name
)
override
;
bool
begin_object
(
type_id_t
type
,
string_view
name
)
override
;
bool
end_object
()
override
;
...
...
@@ -140,7 +138,6 @@ private:
bool
push
(
config_value
&&
x
);
stack_type
st_
;
string_view
type_hint_
;
};
}
// namespace caf
libcaf_core/caf/deserializer.hpp
View file @
d3b18572
...
...
@@ -62,13 +62,15 @@ public:
// -- interface functions ----------------------------------------------------
/// Reads run-time-type information for the next object. Requires that the
/// @ref serializer provided this information via
/// @ref serializer::inject_next_object_type.
/// Reads run-time-type information for the next object if available.
virtual
bool
fetch_next_object_type
(
type_id_t
&
type
)
=
0
;
/// Begins processing of an object.
virtual
bool
begin_object
(
string_view
type
)
=
0
;
/// Begins processing of an object, may perform a type check depending on the
/// data format.
/// @param type 16-bit ID for known types, @ref invalid_type_id otherwise.
/// @param pretty_class_name Either the output of @ref type_name_or_anonymous
/// or the optionally defined pretty name.
virtual
bool
begin_object
(
type_id_t
type
,
string_view
pretty_class_name
)
=
0
;
/// Ends processing of an object.
virtual
bool
end_object
()
=
0
;
...
...
libcaf_core/caf/detail/serialized_size.hpp
View file @
d3b18572
...
...
@@ -32,9 +32,7 @@ public:
size_t
result
=
0
;
bool
inject_next_object_type
(
type_id_t
type
)
override
;
bool
begin_object
(
string_view
)
override
;
bool
begin_object
(
type_id_t
,
string_view
)
override
;
bool
end_object
()
override
;
...
...
libcaf_core/caf/detail/stringification_inspector.hpp
View file @
d3b18572
...
...
@@ -58,7 +58,7 @@ public:
// -- serializer interface ---------------------------------------------------
bool
begin_object
(
string_view
name
);
bool
begin_object
(
type_id_t
,
string_view
name
);
bool
end_object
();
...
...
libcaf_core/caf/hash/fnv.hpp
View file @
d3b18572
...
...
@@ -53,7 +53,7 @@ public:
return
false
;
}
constexpr
bool
begin_object
(
string_view
)
{
constexpr
bool
begin_object
(
type_id_t
,
string_view
)
{
return
true
;
}
...
...
libcaf_core/caf/hash/sha1.hpp
View file @
d3b18572
...
...
@@ -49,7 +49,7 @@ public:
return
false
;
}
constexpr
bool
begin_object
(
string_view
)
{
constexpr
bool
begin_object
(
type_id_t
,
string_view
)
{
return
true
;
}
...
...
libcaf_core/caf/load_inspector.hpp
View file @
d3b18572
...
...
@@ -275,6 +275,7 @@ public:
template
<
class
Inspector
,
class
LoadCallback
>
struct
object_with_load_callback_t
{
type_id_t
object_type
;
string_view
object_name
;
Inspector
*
f
;
LoadCallback
load_callback
;
...
...
@@ -282,7 +283,7 @@ public:
template
<
class
...
Fields
>
bool
fields
(
Fields
&&
...
fs
)
{
using
load_callback_result
=
decltype
(
load_callback
());
if
(
!
(
f
->
begin_object
(
object_name
)
&&
(
fs
(
*
f
)
&&
...)))
if
(
!
(
f
->
begin_object
(
object_
type
,
object_
name
)
&&
(
fs
(
*
f
)
&&
...)))
return
false
;
if
constexpr
(
std
::
is_same
<
load_callback_result
,
bool
>::
value
)
{
if
(
!
load_callback
())
{
...
...
@@ -299,7 +300,7 @@ public:
}
auto
pretty_name
(
string_view
name
)
&&
{
return
object_t
{
name
,
f
};
return
object_t
{
object_type
,
name
,
f
};
}
template
<
class
F
>
...
...
@@ -310,16 +311,19 @@ public:
template
<
class
Inspector
>
struct
object_t
{
type_id_t
object_type
;
string_view
object_name
;
Inspector
*
f
;
template
<
class
...
Fields
>
bool
fields
(
Fields
&&
...
fs
)
{
return
f
->
begin_object
(
object_name
)
&&
(
fs
(
*
f
)
&&
...)
&&
f
->
end_object
();
return
f
->
begin_object
(
object_type
,
object_name
)
//
&&
(
fs
(
*
f
)
&&
...)
//
&&
f
->
end_object
();
}
auto
pretty_name
(
string_view
name
)
&&
{
return
object_t
{
name
,
f
};
return
object_t
{
object_type
,
name
,
f
};
}
template
<
class
F
>
...
...
@@ -330,6 +334,7 @@ public:
template
<
class
F
>
auto
on_load
(
F
fun
)
&&
{
return
object_with_load_callback_t
<
Inspector
,
F
>
{
object_type
,
object_name
,
f
,
std
::
move
(
fun
),
...
...
libcaf_core/caf/load_inspector_base.hpp
View file @
d3b18572
...
...
@@ -38,7 +38,8 @@ public:
template
<
class
T
>
constexpr
auto
object
(
T
&
)
noexcept
{
return
super
::
object_t
<
Subtype
>
{
type_name_or_anonymous
<
T
>
(),
dptr
()};
return
super
::
object_t
<
Subtype
>
{
type_id_or_invalid
<
T
>
(),
type_name_or_anonymous
<
T
>
(),
dptr
()};
}
template
<
class
T
>
...
...
libcaf_core/caf/save_inspector.hpp
View file @
d3b18572
...
...
@@ -171,6 +171,7 @@ public:
template
<
class
Inspector
,
class
SaveCallback
>
struct
object_with_save_callback_t
{
type_id_t
object_type
;
string_view
object_name
;
Inspector
*
f
;
SaveCallback
save_callback
;
...
...
@@ -178,7 +179,7 @@ public:
template
<
class
...
Fields
>
bool
fields
(
Fields
&&
...
fs
)
{
using
save_callback_result
=
decltype
(
save_callback
());
if
(
!
(
f
->
begin_object
(
object_name
)
&&
(
fs
(
*
f
)
&&
...)))
if
(
!
(
f
->
begin_object
(
object_
type
,
object_
name
)
&&
(
fs
(
*
f
)
&&
...)))
return
false
;
if
constexpr
(
std
::
is_same
<
save_callback_result
,
bool
>::
value
)
{
if
(
!
save_callback
())
{
...
...
@@ -206,16 +207,19 @@ public:
template
<
class
Inspector
>
struct
object_t
{
type_id_t
object_type
;
string_view
object_name
;
Inspector
*
f
;
template
<
class
...
Fields
>
bool
fields
(
Fields
&&
...
fs
)
{
return
f
->
begin_object
(
object_name
)
&&
(
fs
(
*
f
)
&&
...)
&&
f
->
end_object
();
return
f
->
begin_object
(
object_type
,
object_name
)
//
&&
(
fs
(
*
f
)
&&
...)
//
&&
f
->
end_object
();
}
auto
pretty_name
(
string_view
name
)
&&
{
return
object_t
{
name
,
f
};
return
object_t
{
object_type
,
name
,
f
};
}
template
<
class
F
>
...
...
@@ -226,6 +230,7 @@ public:
template
<
class
F
>
auto
on_save
(
F
fun
)
&&
{
return
object_with_save_callback_t
<
Inspector
,
F
>
{
object_type
,
object_name
,
f
,
std
::
move
(
fun
),
...
...
libcaf_core/caf/save_inspector_base.hpp
View file @
d3b18572
...
...
@@ -34,7 +34,8 @@ public:
template
<
class
T
>
constexpr
auto
object
(
T
&
)
noexcept
{
return
super
::
object_t
<
Subtype
>
{
type_name_or_anonymous
<
T
>
(),
dptr
()};
return
super
::
object_t
<
Subtype
>
{
type_id_or_invalid
<
T
>
(),
type_name_or_anonymous
<
T
>
(),
dptr
()};
}
template
<
class
T
>
...
...
libcaf_core/caf/sec.hpp
View file @
d3b18572
...
...
@@ -164,6 +164,12 @@ enum class sec : uint8_t {
conversion_failed
,
/// A network connection was closed by the remote side.
connection_closed
,
/// An operation failed because run-time type information diverged from the
/// expected type.
type_clash
,
/// An operation failed because the callee does not implement this
/// functionality.
unsupported_operation
,
};
/// @relates sec
...
...
libcaf_core/caf/serializer.hpp
View file @
d3b18572
...
...
@@ -66,15 +66,10 @@ public:
// -- interface functions ----------------------------------------------------
/// Injects run-time-type information for the *next* object, i.e., causes the
/// next call to `begin_object` to write additional meta information. Allows a
/// @ref deserializer to retrieve the type for the next object via
/// @ref deserializer::fetch_next_object_type.
virtual
bool
inject_next_object_type
(
type_id_t
type
)
=
0
;
/// Begins processing of an object. Saves the type information
/// to the underlying storage.
virtual
bool
begin_object
(
string_view
name
)
=
0
;
/// Begins processing of an object. May save the type information to the
/// underlying storage to allow a @ref deserializer to retrieve and check the
/// type information for data formats that provide deserialization.
virtual
bool
begin_object
(
type_id_t
type
,
string_view
name
)
=
0
;
/// Ends processing of an object.
virtual
bool
end_object
()
=
0
;
...
...
libcaf_core/caf/type_id.hpp
View file @
d3b18572
...
...
@@ -108,6 +108,15 @@ string_view type_name_or_anonymous() {
return
"anonymous"
;
}
/// Returns `type_id_v<T>` if available, `invalid_type_id` otherwise.
template
<
class
T
>
type_id_t
type_id_or_invalid
()
{
if
constexpr
(
detail
::
is_complete
<
type_id
<
T
>>
)
return
type_id
<
T
>::
value
;
else
return
invalid_type_id
;
}
/// Returns the type name of given `type` or an empty string if `type` is an
/// invalid ID.
CAF_CORE_EXPORT
string_view
query_type_name
(
type_id_t
type
);
...
...
libcaf_core/src/binary_deserializer.cpp
View file @
d3b18572
...
...
@@ -35,19 +35,23 @@ namespace {
template
<
class
T
>
bool
int_value
(
binary_deserializer
&
source
,
T
&
x
)
{
auto
tmp
=
std
::
make_unsigned_t
<
T
>
{};
if
(
!
source
.
value
(
as_writable_bytes
(
make_span
(
&
tmp
,
1
))))
if
(
source
.
value
(
as_writable_bytes
(
make_span
(
&
tmp
,
1
))))
{
x
=
static_cast
<
T
>
(
detail
::
from_network_order
(
tmp
));
return
true
;
}
else
{
return
false
;
x
=
static_cast
<
T
>
(
detail
::
from_network_order
(
tmp
));
return
true
;
}
}
template
<
class
T
>
bool
float_value
(
binary_deserializer
&
source
,
T
&
x
)
{
auto
tmp
=
typename
detail
::
ieee_754_trait
<
T
>::
packed_type
{};
if
(
!
int_value
(
source
,
tmp
))
if
(
int_value
(
source
,
tmp
))
{
x
=
detail
::
unpack754
(
tmp
);
return
true
;
}
else
{
return
false
;
x
=
detail
::
unpack754
(
tmp
);
return
true
;
}
}
// Does not perform any range checks.
...
...
@@ -67,7 +71,10 @@ binary_deserializer::binary_deserializer(actor_system& sys) noexcept
}
bool
binary_deserializer
::
fetch_next_object_type
(
type_id_t
&
type
)
noexcept
{
return
value
(
type
);
type
=
invalid_type_id
;
emplace_error
(
sec
::
unsupported_operation
,
"the default binary format does not embed type information"
);
return
false
;
}
bool
binary_deserializer
::
begin_sequence
(
size_t
&
list_size
)
noexcept
{
...
...
libcaf_core/src/binary_serializer.cpp
View file @
d3b18572
...
...
@@ -51,10 +51,6 @@ void binary_serializer::skip(size_t num_bytes) {
write_pos_
+=
num_bytes
;
}
bool
binary_serializer
::
inject_next_object_type
(
type_id_t
type
)
{
return
value
(
type
);
}
bool
binary_serializer
::
begin_sequence
(
size_t
list_size
)
{
// Use varbyte encoding to compress sequence size on the wire.
// For 64-bit values, the encoded representation cannot get larger than 10
...
...
libcaf_core/src/config_value.cpp
View file @
d3b18572
...
...
@@ -149,6 +149,21 @@ const char* config_value::type_name_at_index(size_t index) noexcept {
// -- utility ------------------------------------------------------------------
type_id_t
config_value
::
type_id
()
const
noexcept
{
static
constexpr
type_id_t
allowed_types
[]
=
{
type_id_v
<
none_t
>
,
type_id_v
<
config_value
::
integer
>
,
type_id_v
<
config_value
::
boolean
>
,
type_id_v
<
config_value
::
real
>
,
type_id_v
<
timespan
>
,
type_id_v
<
uri
>
,
type_id_v
<
config_value
::
string
>
,
type_id_v
<
config_value
::
list
>
,
type_id_v
<
config_value
::
dictionary
>
,
};
return
allowed_types
[
data_
.
index
()];
}
error_code
<
sec
>
config_value
::
default_construct
(
type_id_t
id
)
{
switch
(
id
)
{
case
type_id_v
<
bool
>
:
...
...
libcaf_core/src/config_value_reader.cpp
View file @
d3b18572
...
...
@@ -122,11 +122,12 @@ bool config_value_reader::fetch_next_object_type(type_id_t& type) {
return
false
;
},
[
this
,
&
type
](
const
config_value
*
val
)
{
if
(
auto
obj
=
get_if
<
settings
>
(
val
);
obj
==
nullptr
)
{
emplace_error
(
sec
::
conversion_failed
,
"cannot read input as object"
);
return
false
;
auto
tid
=
val
->
type_id
();
if
(
tid
!=
type_id_v
<
config_value
::
dictionary
>
)
{
type
=
tid
;
return
true
;
}
else
{
return
fetch_object_type
(
obj
,
type
);
return
fetch_object_type
(
get_if
<
settings
>
(
val
)
,
type
);
}
},
[
this
](
key_ptr
)
{
...
...
@@ -146,11 +147,13 @@ bool config_value_reader::fetch_next_object_type(type_id_t& type) {
emplace_error
(
sec
::
runtime_error
,
"list index out of bounds"
);
return
false
;
}
if
(
auto
obj
=
get_if
<
settings
>
(
std
::
addressof
(
seq
.
current
()));
!
obj
)
{
emplace_error
(
sec
::
conversion_failed
,
"cannot read input as object"
);
return
false
;
auto
&
val
=
seq
.
current
();
auto
tid
=
val
.
type_id
();
if
(
tid
!=
type_id_v
<
config_value
::
dictionary
>
)
{
type
=
tid
;
return
true
;
}
else
{
return
fetch_object_type
(
obj
,
type
);
return
fetch_object_type
(
get_if
<
settings
>
(
&
val
)
,
type
);
}
},
[
this
](
associative_array
&
)
{
...
...
@@ -162,7 +165,7 @@ bool config_value_reader::fetch_next_object_type(type_id_t& type) {
}
}
bool
config_value_reader
::
begin_object
(
string_view
)
{
bool
config_value_reader
::
begin_object
(
type_id_t
type
,
string_view
)
{
if
(
st_
.
empty
())
{
emplace_error
(
sec
::
runtime_error
,
"tried to read multiple objects from the root object"
);
...
...
@@ -216,7 +219,27 @@ bool config_value_reader::begin_object(string_view) {
"fetch_next_object_type called inside associative array"
);
return
false
;
});
return
visit
(
f
,
st_
.
top
());
if
(
visit
(
f
,
st_
.
top
()))
{
// Perform a type check if type is a valid ID and the object contains an
// "@type" field.
if
(
type
!=
invalid_type_id
)
{
CAF_ASSERT
(
holds_alternative
<
const
settings
*>
(
st_
.
top
()));
auto
obj
=
get
<
const
settings
*>
(
st_
.
top
());
auto
want
=
query_type_name
(
type
);
if
(
auto
i
=
obj
->
find
(
"@type"
);
i
!=
obj
->
end
())
{
if
(
auto
got
=
get_if
<
std
::
string
>
(
std
::
addressof
(
i
->
second
)))
{
if
(
want
!=
*
got
)
{
emplace_error
(
sec
::
type_clash
,
"expected type: "
+
to_string
(
want
),
"found type: "
+
*
got
);
return
false
;
}
}
}
}
return
true
;
}
else
{
return
false
;
}
}
bool
config_value_reader
::
end_object
()
{
...
...
@@ -563,15 +586,14 @@ bool config_value_reader::value(span<byte> bytes) {
bool
config_value_reader
::
fetch_object_type
(
const
settings
*
obj
,
type_id_t
&
type
)
{
if
(
auto
str
=
get_if
<
std
::
string
>
(
obj
,
"@type"
);
str
==
nullptr
)
{
emplace_error
(
sec
::
runtime_error
,
"cannot fetch object type: no '@type' entry found"
);
return
false
;
}
else
if
(
auto
id
=
query_type_id
(
*
str
);
id
==
invalid_type_id
)
{
emplace_error
(
sec
::
runtime_error
,
"no such type: "
+
*
str
);
return
false
;
}
else
{
type
=
type_id_v
<
config_value
::
dictionary
>
;
return
true
;
}
else
if
(
auto
id
=
query_type_id
(
*
str
);
id
!=
invalid_type_id
)
{
type
=
id
;
return
true
;
}
else
{
emplace_error
(
sec
::
runtime_error
,
"unknown type: "
+
*
str
);
return
false
;
}
}
...
...
libcaf_core/src/config_value_writer.cpp
View file @
d3b18572
...
...
@@ -66,18 +66,7 @@ config_value_writer::~config_value_writer() {
// -- interface functions ------------------------------------------------------
bool
config_value_writer
::
inject_next_object_type
(
type_id_t
type
)
{
CHECK_NOT_EMPTY
();
type_hint_
=
query_type_name
(
type
);
if
(
type_hint_
.
empty
())
{
emplace_error
(
sec
::
runtime_error
,
"query_type_name returned an empty string for type ID"
);
return
false
;
}
return
true
;
}
bool
config_value_writer
::
begin_object
(
string_view
)
{
bool
config_value_writer
::
begin_object
(
type_id_t
type
,
string_view
)
{
CHECK_NOT_EMPTY
();
auto
f
=
detail
::
make_overload
(
[
this
](
config_value
*
x
)
{
...
...
@@ -118,10 +107,8 @@ bool config_value_writer::begin_object(string_view) {
});
if
(
!
visit
(
f
,
st_
.
top
()))
return
false
;
if
(
!
type_hint_
.
empty
())
{
put
(
*
get
<
settings
*>
(
st_
.
top
()),
"@type"
,
type_hint_
);
type_hint_
=
string_view
{};
}
if
(
type
!=
invalid_type_id
)
put
(
*
get
<
settings
*>
(
st_
.
top
()),
"@type"
,
query_type_name
(
type
));
return
true
;
}
...
...
libcaf_core/src/detail/serialized_size.cpp
View file @
d3b18572
...
...
@@ -26,11 +26,7 @@
namespace
caf
::
detail
{
bool
serialized_size_inspector
::
inject_next_object_type
(
type_id_t
type
)
{
return
value
(
type
);
}
bool
serialized_size_inspector
::
begin_object
(
string_view
)
{
bool
serialized_size_inspector
::
begin_object
(
type_id_t
,
string_view
)
{
return
true
;
}
...
...
libcaf_core/src/detail/stringification_inspector.cpp
View file @
d3b18572
...
...
@@ -49,7 +49,7 @@ void escape(std::string& result, char c) {
namespace
caf
::
detail
{
bool
stringification_inspector
::
begin_object
(
string_view
name
)
{
bool
stringification_inspector
::
begin_object
(
type_id_t
,
string_view
name
)
{
sep
();
if
(
name
!=
"std::string"
)
{
result_
.
insert
(
result_
.
end
(),
name
.
begin
(),
name
.
end
());
...
...
libcaf_core/src/message.cpp
View file @
d3b18572
...
...
@@ -59,7 +59,7 @@ template <class Deserializer>
bool
load_data
(
Deserializer
&
source
,
message
::
data_ptr
&
data
)
{
// For machine-to-machine data formats, we prefix the type information.
if
(
!
source
.
has_human_readable_format
())
{
GUARDED
(
source
.
begin_object
(
"message"
));
GUARDED
(
source
.
begin_object
(
type_id_v
<
message
>
,
"message"
));
GUARDED
(
source
.
begin_field
(
"types"
));
size_t
msg_size
=
0
;
GUARDED
(
source
.
begin_sequence
(
msg_size
));
...
...
@@ -159,8 +159,6 @@ bool load_data(Deserializer& source, message::data_ptr& data) {
using
unique_void_ptr
=
std
::
unique_ptr
<
void
,
free_t
>
;
auto
msg_size
=
size_t
{
0
};
std
::
vector
<
object_ptr
>
objects
;
GUARDED
(
source
.
begin_object
(
"message"
));
GUARDED
(
source
.
begin_field
(
"values"
));
GUARDED
(
source
.
begin_sequence
(
msg_size
));
if
(
msg_size
>
0
)
{
// Deserialize message elements individually.
...
...
@@ -185,7 +183,7 @@ bool load_data(Deserializer& source, message::data_ptr& data) {
STOP
(
sec
::
unknown_type
);
}
}
GUARDED
(
source
.
end_
field
()
&&
source
.
end_
sequence
());
GUARDED
(
source
.
end_sequence
());
// Merge elements into a single message data object.
intrusive_ptr
<
detail
::
message_data
>
ptr
;
if
(
auto
vptr
=
malloc
(
sizeof
(
detail
::
message_data
)
+
data_size
))
{
...
...
@@ -203,13 +201,11 @@ bool load_data(Deserializer& source, message::data_ptr& data) {
pos
+=
x
.
meta
->
padded_size
;
}
data
.
reset
(
ptr
.
release
(),
false
);
return
source
.
end_object
()
;
return
true
;
}
else
{
data
.
reset
();
return
source
.
end_sequence
();
}
return
source
.
end_sequence
()
//
&&
source
.
end_field
()
//
&&
source
.
end_object
();
}
}
// namespace
...
...
@@ -242,18 +238,18 @@ save_data(Serializer& sink, const message::data_ptr& data) {
if
(
!
sink
.
has_human_readable_format
())
{
if
(
data
==
nullptr
)
{
// Short-circuit empty tuples.
return
sink
.
begin_object
(
"message"
)
//
&&
sink
.
begin_field
(
"types"
)
//
&&
sink
.
begin_sequence
(
0
)
//
&&
sink
.
end_sequence
()
//
&&
sink
.
end_field
()
//
&&
sink
.
begin_field
(
"values"
)
//
&&
sink
.
begin_tuple
(
0
)
//
&&
sink
.
end_tuple
()
//
&&
sink
.
end_field
()
//
return
sink
.
begin_object
(
type_id_v
<
message
>
,
"message"
)
//
&&
sink
.
begin_field
(
"types"
)
//
&&
sink
.
begin_sequence
(
0
)
//
&&
sink
.
end_sequence
()
//
&&
sink
.
end_field
()
//
&&
sink
.
begin_field
(
"values"
)
//
&&
sink
.
begin_tuple
(
0
)
//
&&
sink
.
end_tuple
()
//
&&
sink
.
end_field
()
//
&&
sink
.
end_object
();
}
GUARDED
(
sink
.
begin_object
(
"message"
));
GUARDED
(
sink
.
begin_object
(
type_id_v
<
message
>
,
"message"
));
auto
type_ids
=
data
->
types
();
// Write type information.
GUARDED
(
sink
.
begin_field
(
"types"
)
&&
sink
.
begin_sequence
(
type_ids
.
size
()));
...
...
@@ -274,25 +270,17 @@ save_data(Serializer& sink, const message::data_ptr& data) {
// dynamically-typed objects.
if
(
data
==
nullptr
)
{
// Short-circuit empty tuples.
return
sink
.
begin_object
(
"message"
)
//
&&
sink
.
begin_field
(
"values"
)
//
&&
sink
.
begin_sequence
(
0
)
//
&&
sink
.
end_sequence
()
//
&&
sink
.
end_field
()
//
&&
sink
.
end_object
();
return
sink
.
begin_sequence
(
0
)
&&
sink
.
end_sequence
();
}
auto
type_ids
=
data
->
types
();
GUARDED
(
sink
.
begin_object
(
"message"
)
//
&&
sink
.
begin_field
(
"values"
)
//
&&
sink
.
begin_sequence
(
type_ids
.
size
()));
GUARDED
(
sink
.
begin_sequence
(
type_ids
.
size
()));
auto
storage
=
data
->
storage
();
for
(
auto
id
:
type_ids
)
{
auto
&
meta
=
gmos
[
id
];
GUARDED
(
sink
.
inject_next_object_type
(
id
)
//
&&
save
(
meta
,
sink
,
storage
));
GUARDED
(
save
(
meta
,
sink
,
storage
));
storage
+=
meta
.
padded_size
;
}
return
sink
.
end_sequence
()
&&
sink
.
end_field
()
&&
sink
.
end_object
()
;
return
sink
.
end_sequence
();
}
}
// namespace
...
...
libcaf_core/src/tracing_data.cpp
View file @
d3b18572
...
...
@@ -41,22 +41,22 @@ namespace {
template
<
class
Serializer
>
bool
serialize_impl
(
Serializer
&
sink
,
const
tracing_data_ptr
&
x
)
{
if
(
!
x
)
{
return
sink
.
begin_object
(
"tracing_data"
)
//
&&
sink
.
begin_field
(
"value"
,
false
)
//
&&
sink
.
end_field
()
//
return
sink
.
begin_object
(
invalid_type_id
,
"tracing_data"
)
//
&&
sink
.
begin_field
(
"value"
,
false
)
//
&&
sink
.
end_field
()
//
&&
sink
.
end_object
();
}
return
sink
.
begin_object
(
"tracing_data"
)
//
&&
sink
.
begin_field
(
"value"
,
true
)
//
&&
x
->
serialize
(
sink
)
//
&&
sink
.
end_field
()
//
return
sink
.
begin_object
(
invalid_type_id
,
"tracing_data"
)
//
&&
sink
.
begin_field
(
"value"
,
true
)
//
&&
x
->
serialize
(
sink
)
//
&&
sink
.
end_field
()
//
&&
sink
.
end_object
();
}
template
<
class
Deserializer
>
bool
deserialize_impl
(
Deserializer
&
source
,
tracing_data_ptr
&
x
)
{
bool
is_present
=
false
;
if
(
!
source
.
begin_object
(
"tracing_data"
)
if
(
!
source
.
begin_object
(
invalid_type_id
,
"tracing_data"
)
||
!
source
.
begin_field
(
"value"
,
is_present
))
return
false
;
if
(
!
is_present
)
...
...
libcaf_core/test/config_value.cpp
View file @
d3b18572
...
...
@@ -672,7 +672,9 @@ SCENARIO("config values can default-construct all registered types") {
auto
val
=
from
(
type_id_v
<
my_request
>
);
CHECK_EQ
(
val
.
get_data
().
index
(),
8u
);
auto
&
dict
=
val
.
as_dictionary
();
CHECK_EQ
(
keys
(
dict
),
std
::
vector
<
std
::
string
>
({
"a"
,
"b"
}));
CHECK_EQ
(
keys
(
dict
),
std
::
vector
<
std
::
string
>
({
"@type"
,
"a"
,
"b"
}));
CHECK_EQ
(
dict
[
"@type"
].
get_data
().
index
(),
6u
);
CHECK_EQ
(
get_as
<
std
::
string
>
(
dict
[
"@type"
]),
"my_request"
s
);
CHECK_EQ
(
dict
[
"a"
].
get_data
().
index
(),
1u
);
CHECK_EQ
(
get_as
<
int32_t
>
(
dict
[
"a"
]),
0
);
CHECK_EQ
(
dict
[
"b"
].
get_data
().
index
(),
1u
);
...
...
@@ -682,6 +684,41 @@ SCENARIO("config values can default-construct all registered types") {
}
}
#define CHECK_ROUNDTRIP(init_val, expected_str) \
do { \
config_value x; \
if (auto assign_failed = x.assign(init_val); CHECK(!assign_failed)) { \
auto str = to_string(x); \
CHECK_EQ(str, expected_str); \
auto parsed = config_value::parse(str); \
using init_val_type = decltype(init_val); \
if (CHECK(parsed)) { \
if constexpr (!std::is_same<init_val_type, message>::value) \
CHECK_EQ(get_as<init_val_type>(*parsed), init_val); \
else \
CHECK_EQ(to_string(*parsed), str); \
} \
} \
} while (false)
SCENARIO
(
"config values can parse their own to_string output"
)
{
GIVEN
(
"a config value"
)
{
WHEN
(
"assigning a value and then calling to_string on it"
)
{
THEN
(
"then config_value::parse reconstitutes the original value"
)
{
CHECK_ROUNDTRIP
(
0
,
"0"
);
CHECK_ROUNDTRIP
(
"hello world"
s
,
"hello world"
);
CHECK_ROUNDTRIP
(
std
::
vector
<
int
>
({
1
,
2
,
3
}),
"[1, 2, 3]"
);
CHECK_ROUNDTRIP
(
my_request
(
1
,
2
),
R"_({"@type" = "my_request", a = 1, b = 2})_"
);
CHECK_ROUNDTRIP
(
std
::
make_tuple
(
add_atom_v
,
1
,
2
),
R"_([{"@type" = "caf::add_atom"}, 1, 2])_"
);
CHECK_ROUNDTRIP
(
make_message
(
add_atom_v
,
1
,
2
),
R"_([{"@type" = "caf::add_atom"}, 1, 2])_"
);
}
}
}
}
CAF_TEST
(
default_constructed
)
{
config_value
x
;
CAF_CHECK_EQUAL
(
holds_alternative
<
none_t
>
(
x
),
true
);
...
...
libcaf_core/test/load_inspector.cpp
View file @
d3b18572
...
...
@@ -58,7 +58,7 @@ struct testee : deserializer {
return
false
;
}
bool
begin_object
(
string_view
object_name
)
override
{
bool
begin_object
(
type_id_t
,
string_view
object_name
)
override
{
new_line
();
indent
+=
2
;
log
+=
"begin object "
;
...
...
libcaf_core/test/save_inspector.cpp
View file @
d3b18572
...
...
@@ -49,15 +49,7 @@ struct testee : serializer {
log
.
insert
(
log
.
end
(),
indent
,
' '
);
}
bool
inject_next_object_type
(
type_id_t
type
)
override
{
new_line
();
log
+=
"next object type: "
;
auto
tn
=
detail
::
global_meta_object
(
type
)
->
type_name
;
log
.
insert
(
log
.
end
(),
tn
.
begin
(),
tn
.
end
());
return
true
;
}
bool
begin_object
(
string_view
object_name
)
override
{
bool
begin_object
(
type_id_t
,
string_view
object_name
)
override
{
new_line
();
indent
+=
2
;
log
+=
"begin object "
;
...
...
@@ -734,18 +726,11 @@ end object)_");
f
.
set_has_human_readable_format
(
true
);
CAF_CHECK
(
inspect
(
f
,
x
));
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
begin object message
begin field values
begin sequence of size 3
next object type: int32_t
int32_t value
next object type: std::string
std::string value
next object type: double
double value
end sequence
end field
end object)_"
);
begin sequence of size 3
int32_t value
std::string value
double value
end sequence)_"
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
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