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
afb884bb
Unverified
Commit
afb884bb
authored
Feb 14, 2019
by
Joseph Noir
Committed by
GitHub
Feb 14, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #818
Re-implement container-based binary serializers
parents
d208f93c
d04f510a
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
878 additions
and
272 deletions
+878
-272
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+2
-0
libcaf_core/caf/all.hpp
libcaf_core/caf/all.hpp
+2
-0
libcaf_core/caf/binary_deserializer.hpp
libcaf_core/caf/binary_deserializer.hpp
+73
-6
libcaf_core/caf/binary_serializer.hpp
libcaf_core/caf/binary_serializer.hpp
+85
-6
libcaf_core/caf/data_processor.hpp
libcaf_core/caf/data_processor.hpp
+34
-31
libcaf_core/caf/detail/select_integer_type.hpp
libcaf_core/caf/detail/select_integer_type.hpp
+13
-10
libcaf_core/caf/stream_deserializer.hpp
libcaf_core/caf/stream_deserializer.hpp
+86
-73
libcaf_core/caf/stream_serializer.hpp
libcaf_core/caf/stream_serializer.hpp
+71
-55
libcaf_core/src/binary_deserializer.cpp
libcaf_core/src/binary_deserializer.cpp
+196
-0
libcaf_core/src/binary_serializer.cpp
libcaf_core/src/binary_serializer.cpp
+187
-0
libcaf_core/test/serialization.cpp
libcaf_core/test/serialization.cpp
+119
-75
libcaf_io/src/instance.cpp
libcaf_io/src/instance.cpp
+10
-16
No files found.
libcaf_core/CMakeLists.txt
View file @
afb884bb
...
@@ -30,6 +30,8 @@ set(LIBCAF_CORE_SRCS
...
@@ -30,6 +30,8 @@ set(LIBCAF_CORE_SRCS
src/behavior.cpp
src/behavior.cpp
src/behavior_impl.cpp
src/behavior_impl.cpp
src/behavior_stack.cpp
src/behavior_stack.cpp
src/binary_deserializer.cpp
src/binary_serializer.cpp
src/blocking_actor.cpp
src/blocking_actor.cpp
src/blocking_behavior.cpp
src/blocking_behavior.cpp
src/chars.cpp
src/chars.cpp
...
...
libcaf_core/caf/all.hpp
View file @
afb884bb
...
@@ -93,12 +93,14 @@
...
@@ -93,12 +93,14 @@
#include "caf/composed_behavior.hpp"
#include "caf/composed_behavior.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/primitive_variant.hpp"
#include "caf/primitive_variant.hpp"
#include "caf/stream_serializer.hpp"
#include "caf/make_config_option.hpp"
#include "caf/make_config_option.hpp"
#include "caf/timeout_definition.hpp"
#include "caf/timeout_definition.hpp"
#include "caf/actor_system_config.hpp"
#include "caf/actor_system_config.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/composable_behavior.hpp"
#include "caf/composable_behavior.hpp"
#include "caf/config_option_adder.hpp"
#include "caf/config_option_adder.hpp"
#include "caf/stream_deserializer.hpp"
#include "caf/typed_actor_pointer.hpp"
#include "caf/typed_actor_pointer.hpp"
#include "caf/scoped_execution_unit.hpp"
#include "caf/scoped_execution_unit.hpp"
#include "caf/typed_response_promise.hpp"
#include "caf/typed_response_promise.hpp"
...
...
libcaf_core/caf/binary_deserializer.hpp
View file @
afb884bb
...
@@ -18,14 +18,81 @@
...
@@ -18,14 +18,81 @@
#pragma once
#pragma once
#include "caf/stream_deserializer.hpp"
#include <cstddef>
#include "caf/streambuf.hpp"
#include <cstdint>
#include <vector>
#include "caf/deserializer.hpp"
namespace
caf
{
namespace
caf
{
/// A stream serializer that writes into an unbounded contiguous character
/// Implements the deserializer interface with a binary serialization protocol.
/// sequence.
class
binary_deserializer
final
:
public
deserializer
{
using
binary_deserializer
=
stream_deserializer
<
charbuf
>
;
public:
// -- member types -----------------------------------------------------------
}
// namespace caf
using
super
=
deserializer
;
using
buffer
=
std
::
vector
<
char
>
;
// -- constructors, destructors, and assignment operators --------------------
binary_deserializer
(
actor_system
&
sys
,
const
char
*
buf
,
size_t
buf_size
);
binary_deserializer
(
execution_unit
*
ctx
,
const
char
*
buf
,
size_t
buf_size
);
binary_deserializer
(
actor_system
&
sys
,
const
buffer
&
buf
);
binary_deserializer
(
execution_unit
*
ctx
,
const
buffer
&
buf
);
// -- overridden member functions --------------------------------------------
error
begin_object
(
uint16_t
&
typenr
,
std
::
string
&
name
)
override
;
error
end_object
()
override
;
error
begin_sequence
(
size_t
&
list_size
)
override
;
error
end_sequence
()
override
;
error
apply_raw
(
size_t
num_bytes
,
void
*
data
)
override
;
protected:
error
apply_impl
(
int8_t
&
)
override
;
error
apply_impl
(
uint8_t
&
)
override
;
error
apply_impl
(
int16_t
&
)
override
;
error
apply_impl
(
uint16_t
&
)
override
;
error
apply_impl
(
int32_t
&
)
override
;
error
apply_impl
(
uint32_t
&
)
override
;
error
apply_impl
(
int64_t
&
)
override
;
error
apply_impl
(
uint64_t
&
)
override
;
error
apply_impl
(
float
&
)
override
;
error
apply_impl
(
double
&
)
override
;
error
apply_impl
(
long
double
&
)
override
;
error
apply_impl
(
std
::
string
&
)
override
;
error
apply_impl
(
std
::
u16string
&
)
override
;
error
apply_impl
(
std
::
u32string
&
)
override
;
private:
bool
range_check
(
size_t
read_size
)
{
return
pos_
+
read_size
<=
end_
;
}
const
char
*
pos_
;
const
char
*
end_
;
};
}
// namespace caf
libcaf_core/caf/binary_serializer.hpp
View file @
afb884bb
...
@@ -18,14 +18,93 @@
...
@@ -18,14 +18,93 @@
#pragma once
#pragma once
#include "caf/stream_serializer.hpp"
#include <cstddef>
#include "caf/streambuf.hpp"
#include <cstdint>
#include <vector>
#include "caf/serializer.hpp"
namespace
caf
{
namespace
caf
{
/// A stream serializer that writes into an unbounded contiguous character
/// Implements the serializer interface with a binary serialization protocol.
/// sequence.
class
binary_serializer
final
:
public
serializer
{
using
binary_serializer
=
stream_serializer
<
vectorbuf
>
;
public:
// -- member types -----------------------------------------------------------
}
// namespace caf
using
super
=
serializer
;
using
buffer
=
std
::
vector
<
char
>
;
// -- constructors, destructors, and assignment operators --------------------
binary_serializer
(
actor_system
&
sys
,
buffer
&
buf
);
binary_serializer
(
execution_unit
*
ctx
,
buffer
&
buf
);
// -- position management ----------------------------------------------------
/// Sets the write position to given offset.
/// @pre `offset <= buf.size()`
void
seek
(
size_t
offset
);
/// Jumps `num_bytes` forward. Resizes the buffer (filling it with zeros)
/// when skipping past the end.
void
skip
(
size_t
num_bytes
);
// -- overridden member functions --------------------------------------------
error
begin_object
(
uint16_t
&
typenr
,
std
::
string
&
name
)
override
;
error
end_object
()
override
;
error
begin_sequence
(
size_t
&
list_size
)
override
;
error
end_sequence
()
override
;
error
apply_raw
(
size_t
num_bytes
,
void
*
data
)
override
;
// -- properties -------------------------------------------------------------
buffer
&
buf
()
{
return
buf_
;
}
const
buffer
&
buf
()
const
{
return
buf_
;
}
protected:
error
apply_impl
(
int8_t
&
)
override
;
error
apply_impl
(
uint8_t
&
)
override
;
error
apply_impl
(
int16_t
&
)
override
;
error
apply_impl
(
uint16_t
&
)
override
;
error
apply_impl
(
int32_t
&
)
override
;
error
apply_impl
(
uint32_t
&
)
override
;
error
apply_impl
(
int64_t
&
)
override
;
error
apply_impl
(
uint64_t
&
)
override
;
error
apply_impl
(
float
&
)
override
;
error
apply_impl
(
double
&
)
override
;
error
apply_impl
(
long
double
&
)
override
;
error
apply_impl
(
std
::
string
&
)
override
;
error
apply_impl
(
std
::
u16string
&
)
override
;
error
apply_impl
(
std
::
u32string
&
)
override
;
private:
buffer
&
buf_
;
buffer
::
iterator
write_pos_
;
};
}
// namespace caf
libcaf_core/caf/data_processor.hpp
View file @
afb884bb
...
@@ -73,24 +73,6 @@ public:
...
@@ -73,24 +73,6 @@ public:
std
::
u32string
std
::
u32string
>
;
>
;
/// List of builtin types for data processors as enum.
enum
builtin
{
i8_v
,
u8_v
,
i16_v
,
u16_v
,
i32_v
,
u32_v
,
i64_v
,
u64_v
,
float_v
,
double_v
,
ldouble_v
,
string8_v
,
string16_v
,
string32_v
};
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
data_processor
(
const
data_processor
&
)
=
delete
;
data_processor
(
const
data_processor
&
)
=
delete
;
...
@@ -137,7 +119,7 @@ public:
...
@@ -137,7 +119,7 @@ public:
apply
(
T
&
x
)
{
apply
(
T
&
x
)
{
static
constexpr
auto
tlindex
=
detail
::
tl_index_of
<
builtin_t
,
T
>::
value
;
static
constexpr
auto
tlindex
=
detail
::
tl_index_of
<
builtin_t
,
T
>::
value
;
static_assert
(
tlindex
>=
0
,
"T not recognized as builtin type"
);
static_assert
(
tlindex
>=
0
,
"T not recognized as builtin type"
);
return
apply_
builtin
(
static_cast
<
builtin
>
(
tlindex
),
&
x
);
return
apply_
impl
(
x
);
}
}
template
<
class
T
>
template
<
class
T
>
...
@@ -147,25 +129,21 @@ public:
...
@@ -147,25 +129,21 @@ public:
error
error
>::
type
>::
type
apply
(
T
&
x
)
{
apply
(
T
&
x
)
{
using
type
=
using
type
=
detail
::
select_integer_type_t
<
sizeof
(
T
),
typename
detail
::
select_integer_type
<
std
::
is_signed
<
T
>::
value
>
;
static_cast
<
int
>
(
sizeof
(
T
))
*
(
std
::
is_signed
<
T
>::
value
?
-
1
:
1
)
return
apply_impl
(
reinterpret_cast
<
type
&>
(
x
));
>::
type
;
static
constexpr
auto
tlindex
=
detail
::
tl_index_of
<
builtin_t
,
type
>::
value
;
static_assert
(
tlindex
>=
0
,
"T not recognized as builtin type"
);
return
apply_builtin
(
static_cast
<
builtin
>
(
tlindex
),
&
x
);
}
}
error
apply
(
std
::
string
&
x
)
{
error
apply
(
std
::
string
&
x
)
{
return
apply_
builtin
(
string8_v
,
&
x
);
return
apply_
impl
(
x
);
}
}
error
apply
(
std
::
u16string
&
x
)
{
error
apply
(
std
::
u16string
&
x
)
{
return
apply_
builtin
(
string16_v
,
&
x
);
return
apply_
impl
(
x
);
}
}
error
apply
(
std
::
u32string
&
x
)
{
error
apply
(
std
::
u32string
&
x
)
{
return
apply_
builtin
(
string32_v
,
&
x
);
return
apply_
impl
(
x
);
}
}
template
<
class
D
,
atom_value
V
>
template
<
class
D
,
atom_value
V
>
...
@@ -549,8 +527,33 @@ public:
...
@@ -549,8 +527,33 @@ public:
}
}
protected
:
protected
:
/// Applies this processor to a single builtin value.
virtual
error
apply_impl
(
int8_t
&
)
=
0
;
virtual
error
apply_builtin
(
builtin
in_out_type
,
void
*
in_out
)
=
0
;
virtual
error
apply_impl
(
uint8_t
&
)
=
0
;
virtual
error
apply_impl
(
int16_t
&
)
=
0
;
virtual
error
apply_impl
(
uint16_t
&
)
=
0
;
virtual
error
apply_impl
(
int32_t
&
)
=
0
;
virtual
error
apply_impl
(
uint32_t
&
)
=
0
;
virtual
error
apply_impl
(
int64_t
&
)
=
0
;
virtual
error
apply_impl
(
uint64_t
&
)
=
0
;
virtual
error
apply_impl
(
float
&
)
=
0
;
virtual
error
apply_impl
(
double
&
)
=
0
;
virtual
error
apply_impl
(
long
double
&
)
=
0
;
virtual
error
apply_impl
(
std
::
string
&
)
=
0
;
virtual
error
apply_impl
(
std
::
u16string
&
)
=
0
;
virtual
error
apply_impl
(
std
::
u32string
&
)
=
0
;
private
:
private
:
template
<
class
T
>
template
<
class
T
>
...
...
libcaf_core/caf/detail/select_integer_type.hpp
View file @
afb884bb
...
@@ -23,49 +23,52 @@
...
@@ -23,49 +23,52 @@
namespace
caf
{
namespace
caf
{
namespace
detail
{
namespace
detail
{
template
<
int
>
template
<
int
,
bool
>
struct
select_integer_type
;
struct
select_integer_type
;
template
<
>
template
<
>
struct
select_integer_type
<
-
1
>
{
struct
select_integer_type
<
1
,
true
>
{
using
type
=
int8_t
;
using
type
=
int8_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
1
>
{
struct
select_integer_type
<
1
,
false
>
{
using
type
=
uint8_t
;
using
type
=
uint8_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
-
2
>
{
struct
select_integer_type
<
2
,
true
>
{
using
type
=
int16_t
;
using
type
=
int16_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
2
>
{
struct
select_integer_type
<
2
,
false
>
{
using
type
=
uint16_t
;
using
type
=
uint16_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
-
4
>
{
struct
select_integer_type
<
4
,
true
>
{
using
type
=
int32_t
;
using
type
=
int32_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
4
>
{
struct
select_integer_type
<
4
,
false
>
{
using
type
=
uint32_t
;
using
type
=
uint32_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
-
8
>
{
struct
select_integer_type
<
8
,
true
>
{
using
type
=
int64_t
;
using
type
=
int64_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
8
>
{
struct
select_integer_type
<
8
,
false
>
{
using
type
=
uint64_t
;
using
type
=
uint64_t
;
};
};
template
<
int
Size
,
bool
IsSigned
>
using
select_integer_type_t
=
typename
select_integer_type
<
Size
,
IsSigned
>::
type
;
}
// namespace detail
}
// namespace detail
}
// namespace caf
}
// namespace caf
libcaf_core/caf/stream_deserializer.hpp
View file @
afb884bb
...
@@ -18,22 +18,21 @@
...
@@ -18,22 +18,21 @@
#pragma once
#pragma once
#include <limits>
#include <string>
#include <sstream>
#include <cstddef>
#include <cstddef>
#include <cstdint>
#include <cstdint>
#include <cstring>
#include <cstring>
#include <iomanip>
#include <iomanip>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <type_traits>
#include "caf/sec.hpp"
#include "caf/logger.hpp"
#include "caf/deserializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/logger.hpp"
#include "caf/sec.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -127,66 +126,82 @@ protected:
...
@@ -127,66 +126,82 @@ protected:
return
none
;
return
none
;
}
}
error
apply_builtin
(
builtin
type
,
void
*
val
)
override
{
error
apply_impl
(
int8_t
&
x
)
override
{
CAF_ASSERT
(
val
!=
nullptr
);
return
apply_raw
(
sizeof
(
int8_t
),
&
x
);
switch
(
type
)
{
}
default:
// i8_v or u8_v
CAF_ASSERT
(
type
==
i8_v
||
type
==
u8_v
);
error
apply_impl
(
uint8_t
&
x
)
override
{
return
apply_raw
(
sizeof
(
uint8_t
),
val
);
return
apply_raw
(
sizeof
(
uint8_t
),
&
x
);
case
i16_v
:
}
case
u16_v
:
return
apply_int
(
*
reinterpret_cast
<
uint16_t
*>
(
val
));
error
apply_impl
(
int16_t
&
x
)
override
{
case
i32_v
:
return
apply_int
(
x
);
case
u32_v
:
}
return
apply_int
(
*
reinterpret_cast
<
uint32_t
*>
(
val
));
case
i64_v
:
error
apply_impl
(
uint16_t
&
x
)
override
{
case
u64_v
:
return
apply_int
(
x
);
return
apply_int
(
*
reinterpret_cast
<
uint64_t
*>
(
val
));
}
case
float_v
:
return
apply_float
(
*
reinterpret_cast
<
float
*>
(
val
));
error
apply_impl
(
int32_t
&
x
)
override
{
case
double_v
:
return
apply_int
(
x
);
return
apply_float
(
*
reinterpret_cast
<
double
*>
(
val
));
}
case
ldouble_v
:
{
// the IEEE-754 conversion does not work for long double
error
apply_impl
(
uint32_t
&
x
)
override
{
// => fall back to string serialization (even though it sucks)
return
apply_int
(
x
);
}
error
apply_impl
(
int64_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
uint64_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
float
&
x
)
override
{
return
apply_float
(
x
);
}
error
apply_impl
(
double
&
x
)
override
{
return
apply_float
(
x
);
}
error
apply_impl
(
long
double
&
x
)
override
{
// The IEEE-754 conversion does not work for long double
// => fall back to string serialization (even though it sucks).
std
::
string
tmp
;
std
::
string
tmp
;
auto
e
=
apply
(
tmp
);
if
(
auto
err
=
apply
(
tmp
))
if
(
e
)
return
err
;
return
e
;
std
::
istringstream
iss
{
std
::
move
(
tmp
)};
std
::
istringstream
iss
{
std
::
move
(
tmp
)};
iss
>>
*
reinterpret_cast
<
long
double
*>
(
val
)
;
iss
>>
x
;
return
none
;
return
none
;
}
}
case
string8_v
:
{
auto
&
str
=
*
reinterpret_cast
<
std
::
string
*>
(
val
);
error
apply_impl
(
std
::
string
&
x
)
override
{
size_t
str_size
;
size_t
str_size
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
if
(
auto
err
=
begin_sequence
(
str_size
))
[
&
]
{
str
.
resize
(
str_size
);
return
err
;
auto
p
=
&
str
[
0
];
x
.
resize
(
str_size
);
auto
data
=
reinterpret_cast
<
char_type
*>
(
p
);
auto
s
=
static_cast
<
streamsize
>
(
str_size
);
auto
s
=
static_cast
<
streamsize
>
(
str_size
);
return
range_check
(
streambuf_
.
sgetn
(
data
,
s
),
auto
data
=
reinterpret_cast
<
char_type
*>
(
&
x
[
0
]);
str_size
);
},
if
(
auto
err
=
range_check
(
streambuf_
.
sgetn
(
data
,
s
),
str_size
))
[
&
]
{
return
end_sequence
();
});
return
err
;
return
end_sequence
();
}
}
case
string16_v
:
{
auto
&
str
=
*
reinterpret_cast
<
std
::
u16string
*>
(
val
);
error
apply_impl
(
std
::
u16string
&
x
)
override
{
str
.
clear
();
size_t
str_size
;
size_t
ns
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
return
error
::
eval
([
&
]
{
return
begin_sequence
(
ns
);
},
[
&
]
{
return
fill_range_c
<
uint16_t
>
(
x
,
str_size
);
},
[
&
]
{
return
fill_range_c
<
uint16_t
>
(
str
,
ns
);
},
[
&
]
{
return
end_sequence
();
});
[
&
]
{
return
end_sequence
();
});
}
}
case
string32_v
:
{
auto
&
str
=
*
reinterpret_cast
<
std
::
u32string
*>
(
val
);
error
apply_impl
(
std
::
u32string
&
x
)
override
{
str
.
clear
();
size_t
str_size
;
size_t
ns
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
return
error
::
eval
([
&
]
{
return
begin_sequence
(
ns
);
},
[
&
]
{
return
fill_range_c
<
uint32_t
>
(
x
,
str_size
);
},
[
&
]
{
return
fill_range_c
<
uint32_t
>
(
str
,
ns
);
},
[
&
]
{
return
end_sequence
();
});
[
&
]
{
return
end_sequence
();
});
}
}
}
}
error
range_check
(
std
::
streamsize
got
,
size_t
need
)
{
error
range_check
(
std
::
streamsize
got
,
size_t
need
)
{
if
(
got
>=
0
&&
static_cast
<
size_t
>
(
got
)
==
need
)
if
(
got
>=
0
&&
static_cast
<
size_t
>
(
got
)
==
need
)
...
@@ -197,20 +212,18 @@ protected:
...
@@ -197,20 +212,18 @@ protected:
template
<
class
T
>
template
<
class
T
>
error
apply_int
(
T
&
x
)
{
error
apply_int
(
T
&
x
)
{
T
tmp
;
typename
std
::
make_unsigned
<
T
>::
type
tmp
=
0
;
auto
e
=
apply_raw
(
sizeof
(
T
),
&
tmp
);
if
(
auto
err
=
apply_raw
(
sizeof
(
T
),
&
tmp
))
if
(
e
)
return
err
;
return
e
;
x
=
static_cast
<
T
>
(
detail
::
from_network_order
(
tmp
));
x
=
detail
::
from_network_order
(
tmp
);
return
none
;
return
none
;
}
}
template
<
class
T
>
template
<
class
T
>
error
apply_float
(
T
&
x
)
{
error
apply_float
(
T
&
x
)
{
typename
detail
::
ieee_754_trait
<
T
>::
packed_type
tmp
=
0
;
typename
detail
::
ieee_754_trait
<
T
>::
packed_type
tmp
=
0
;
auto
e
=
apply_int
(
tmp
);
if
(
auto
err
=
apply_int
(
tmp
))
if
(
e
)
return
err
;
return
e
;
x
=
detail
::
unpack754
(
tmp
);
x
=
detail
::
unpack754
(
tmp
);
return
none
;
return
none
;
}
}
...
...
libcaf_core/caf/stream_serializer.hpp
View file @
afb884bb
...
@@ -125,65 +125,81 @@ protected:
...
@@ -125,65 +125,81 @@ protected:
return
none
;
return
none
;
}
}
error
apply_builtin
(
builtin
type
,
void
*
val
)
override
{
error
apply_impl
(
int8_t
&
x
)
override
{
CAF_ASSERT
(
val
!=
nullptr
);
return
apply_raw
(
sizeof
(
int8_t
),
&
x
);
switch
(
type
)
{
}
default:
// i8_v or u8_v
CAF_ASSERT
(
type
==
i8_v
||
type
==
u8_v
);
error
apply_impl
(
uint8_t
&
x
)
override
{
return
apply_raw
(
sizeof
(
uint8_t
),
val
);
return
apply_raw
(
sizeof
(
uint8_t
),
&
x
);
case
i16_v
:
}
case
u16_v
:
return
apply_int
(
*
reinterpret_cast
<
uint16_t
*>
(
val
));
error
apply_impl
(
int16_t
&
x
)
override
{
case
i32_v
:
return
apply_int
(
x
);
case
u32_v
:
}
return
apply_int
(
*
reinterpret_cast
<
uint32_t
*>
(
val
));
case
i64_v
:
error
apply_impl
(
uint16_t
&
x
)
override
{
case
u64_v
:
return
apply_int
(
x
);
return
apply_int
(
*
reinterpret_cast
<
uint64_t
*>
(
val
));
}
case
float_v
:
return
apply_int
(
detail
::
pack754
(
*
reinterpret_cast
<
float
*>
(
val
)));
error
apply_impl
(
int32_t
&
x
)
override
{
case
double_v
:
return
apply_int
(
x
);
return
apply_int
(
detail
::
pack754
(
*
reinterpret_cast
<
double
*>
(
val
)));
}
case
ldouble_v
:
{
// the IEEE-754 conversion does not work for long double
error
apply_impl
(
uint32_t
&
x
)
override
{
// => fall back to string serialization (event though it sucks)
return
apply_int
(
x
);
}
error
apply_impl
(
int64_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
uint64_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
float
&
x
)
override
{
return
apply_int
(
detail
::
pack754
(
x
));
}
error
apply_impl
(
double
&
x
)
override
{
return
apply_int
(
detail
::
pack754
(
x
));
}
error
apply_impl
(
long
double
&
x
)
override
{
// The IEEE-754 conversion does not work for long double
// => fall back to string serialization (event though it sucks).
std
::
ostringstream
oss
;
std
::
ostringstream
oss
;
oss
<<
std
::
setprecision
(
std
::
numeric_limits
<
long
double
>::
digits
)
oss
<<
std
::
setprecision
(
std
::
numeric_limits
<
long
double
>::
digits
)
<<
x
;
<<
*
reinterpret_cast
<
long
double
*>
(
val
);
auto
tmp
=
oss
.
str
();
auto
tmp
=
oss
.
str
();
return
apply
(
tmp
);
return
apply_impl
(
tmp
);
}
case
string8_v
:
{
auto
str
=
reinterpret_cast
<
std
::
string
*>
(
val
);
auto
s
=
str
->
size
();
auto
data
=
reinterpret_cast
<
char_type
*>
(
const_cast
<
std
::
string
::
value_type
*>
(
str
->
data
()));
return
error
::
eval
([
&
]
{
return
begin_sequence
(
s
);
},
[
&
]
{
return
apply_raw
(
str
->
size
(),
data
);
},
[
&
]
{
return
end_sequence
();
});
}
}
case
string16_v
:
{
auto
str
=
reinterpret_cast
<
std
::
u16string
*>
(
val
);
error
apply_impl
(
std
::
string
&
x
)
override
{
auto
s
=
str
->
size
();
auto
str_size
=
x
.
size
();
// the standard does not guarantee that char16_t is exactly 16 bits...
auto
data
=
const_cast
<
char
*>
(
x
.
c_str
());
return
error
::
eval
([
&
]
{
return
begin_sequence
(
s
);
},
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
consume_range_c
<
uint16_t
>
(
*
str
);
},
[
&
]
{
return
apply_raw
(
x
.
size
(),
data
);
},
[
&
]
{
return
end_sequence
();
});
[
&
]
{
return
end_sequence
();
});
}
}
case
string32_v
:
{
auto
str
=
reinterpret_cast
<
std
::
u32string
*>
(
val
);
error
apply_impl
(
std
::
u16string
&
x
)
override
{
auto
s
=
str
->
size
();
auto
str_size
=
x
.
size
();
// the standard does not guarantee that char32_t is exactly 32 bits...
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
return
error
::
eval
([
&
]
{
return
begin_sequence
(
s
);
},
[
&
]
{
return
consume_range_c
<
uint16_t
>
(
x
);
},
[
&
]
{
return
consume_range_c
<
uint32_t
>
(
*
str
);
},
[
&
]
{
return
end_sequence
();
});
[
&
]
{
return
end_sequence
();
});
}
}
}
error
apply_impl
(
std
::
u32string
&
x
)
override
{
auto
str_size
=
x
.
size
();
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
consume_range_c
<
uint32_t
>
(
x
);
},
[
&
]
{
return
end_sequence
();
});
}
}
template
<
class
T
>
template
<
class
T
>
error
apply_int
(
T
x
)
{
error
apply_int
(
T
x
)
{
auto
y
=
detail
::
to_network_order
(
x
);
using
unsigned_type
=
typename
std
::
make_unsigned
<
T
>::
type
;
auto
y
=
detail
::
to_network_order
(
static_cast
<
unsigned_type
>
(
x
));
return
apply_raw
(
sizeof
(
T
),
&
y
);
return
apply_raw
(
sizeof
(
T
),
&
y
);
}
}
...
...
libcaf_core/src/binary_deserializer.cpp
0 → 100644
View file @
afb884bb
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/binary_deserializer.hpp"
#include <iomanip>
#include <sstream>
#include <type_traits>
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/sec.hpp"
namespace
caf
{
namespace
{
template
<
class
T
>
error
apply_int
(
binary_deserializer
&
bs
,
T
&
x
)
{
typename
std
::
make_unsigned
<
T
>::
type
tmp
;
if
(
auto
err
=
bs
.
apply_raw
(
sizeof
(
T
),
&
tmp
))
return
err
;
x
=
static_cast
<
T
>
(
detail
::
from_network_order
(
tmp
));
return
none
;
}
template
<
class
T
>
error
apply_float
(
binary_deserializer
&
bs
,
T
&
x
)
{
typename
detail
::
ieee_754_trait
<
T
>::
packed_type
tmp
;
if
(
auto
err
=
apply_int
(
bs
,
tmp
))
return
err
;
x
=
detail
::
unpack754
(
tmp
);
return
none
;
}
}
// namespace <anonmyous>
binary_deserializer
::
binary_deserializer
(
actor_system
&
sys
,
const
char
*
buf
,
size_t
buf_size
)
:
super
(
sys
),
pos_
(
buf
),
end_
(
buf
+
buf_size
)
{
// nop
}
binary_deserializer
::
binary_deserializer
(
execution_unit
*
ctx
,
const
char
*
buf
,
size_t
buf_size
)
:
super
(
ctx
),
pos_
(
buf
),
end_
(
buf
+
buf_size
)
{
// nop
}
binary_deserializer
::
binary_deserializer
(
actor_system
&
sys
,
const
buffer
&
buf
)
:
binary_deserializer
(
sys
,
buf
.
data
(),
buf
.
size
())
{
// nop
}
binary_deserializer
::
binary_deserializer
(
execution_unit
*
ctx
,
const
buffer
&
buf
)
:
binary_deserializer
(
ctx
,
buf
.
data
(),
buf
.
size
())
{
// nop
}
error
binary_deserializer
::
begin_object
(
uint16_t
&
nr
,
std
::
string
&
name
)
{
if
(
auto
err
=
apply
(
nr
))
return
err
;
if
(
nr
!=
0
)
return
none
;
return
apply
(
name
);
}
error
binary_deserializer
::
end_object
()
{
return
none
;
}
error
binary_deserializer
::
begin_sequence
(
size_t
&
list_size
)
{
auto
s
=
static_cast
<
uint32_t
>
(
list_size
);
if
(
auto
err
=
apply
(
s
))
return
err
;
list_size
=
s
;
return
none
;
}
error
binary_deserializer
::
end_sequence
()
{
return
none
;
}
error
binary_deserializer
::
apply_raw
(
size_t
num_bytes
,
void
*
storage
)
{
if
(
!
range_check
(
num_bytes
))
return
sec
::
end_of_stream
;
memcpy
(
storage
,
pos_
,
num_bytes
);
pos_
+=
num_bytes
;
return
none
;
}
error
binary_deserializer
::
apply_impl
(
int8_t
&
x
)
{
return
apply_raw
(
sizeof
(
int8_t
),
&
x
);
}
error
binary_deserializer
::
apply_impl
(
uint8_t
&
x
)
{
return
apply_raw
(
sizeof
(
uint8_t
),
&
x
);
}
error
binary_deserializer
::
apply_impl
(
int16_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_deserializer
::
apply_impl
(
uint16_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_deserializer
::
apply_impl
(
int32_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_deserializer
::
apply_impl
(
uint32_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_deserializer
::
apply_impl
(
int64_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_deserializer
::
apply_impl
(
uint64_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_deserializer
::
apply_impl
(
float
&
x
)
{
return
apply_float
(
*
this
,
x
);
}
error
binary_deserializer
::
apply_impl
(
double
&
x
)
{
return
apply_float
(
*
this
,
x
);
}
error
binary_deserializer
::
apply_impl
(
long
double
&
x
)
{
// The IEEE-754 conversion does not work for long double
// => fall back to string serialization (even though it sucks).
std
::
string
tmp
;
if
(
auto
err
=
apply
(
tmp
))
return
err
;
std
::
istringstream
iss
{
std
::
move
(
tmp
)};
iss
>>
x
;
return
none
;
}
error
binary_deserializer
::
apply_impl
(
std
::
string
&
x
)
{
size_t
str_size
;
if
(
auto
err
=
begin_sequence
(
str_size
))
return
err
;
if
(
!
range_check
(
str_size
))
return
sec
::
end_of_stream
;
x
.
assign
(
pos_
,
pos_
+
str_size
);
pos_
+=
str_size
;
return
end_sequence
();
}
error
binary_deserializer
::
apply_impl
(
std
::
u16string
&
x
)
{
auto
str_size
=
x
.
size
();
if
(
auto
err
=
begin_sequence
(
str_size
))
return
err
;
for
(
size_t
i
=
0
;
i
<
str_size
;
++
i
)
{
// The standard does not guarantee that char16_t is exactly 16 bits.
uint16_t
tmp
;
if
(
auto
err
=
apply_int
(
*
this
,
tmp
))
return
err
;
x
.
push_back
(
static_cast
<
char16_t
>
(
tmp
));
}
return
none
;
}
error
binary_deserializer
::
apply_impl
(
std
::
u32string
&
x
)
{
auto
str_size
=
x
.
size
();
if
(
auto
err
=
begin_sequence
(
str_size
))
return
err
;
for
(
size_t
i
=
0
;
i
<
str_size
;
++
i
)
{
// The standard does not guarantee that char32_t is exactly 32 bits.
uint32_t
tmp
;
if
(
auto
err
=
apply_int
(
*
this
,
tmp
))
return
err
;
x
.
push_back
(
static_cast
<
char32_t
>
(
tmp
));
}
return
none
;
}
}
// namespace caf
libcaf_core/src/binary_serializer.cpp
0 → 100644
View file @
afb884bb
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/binary_serializer.hpp"
#include <cstring>
#include <iomanip>
#include <sstream>
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp"
namespace
caf
{
namespace
{
template
<
class
T
>
error
apply_int
(
binary_serializer
&
bs
,
T
x
)
{
auto
y
=
detail
::
to_network_order
(
x
);
return
bs
.
apply_raw
(
sizeof
(
T
),
&
y
);
}
}
// namespace <anonmyous>
binary_serializer
::
binary_serializer
(
actor_system
&
sys
,
buffer
&
buf
)
:
super
(
sys
),
buf_
(
buf
),
write_pos_
(
buf
.
end
())
{
// nop
}
binary_serializer
::
binary_serializer
(
execution_unit
*
ctx
,
buffer
&
buf
)
:
super
(
ctx
),
buf_
(
buf
),
write_pos_
(
buf
.
end
())
{
// nop
}
void
binary_serializer
::
seek
(
size_t
offset
)
{
write_pos_
=
buf_
.
begin
()
+
offset
;
}
void
binary_serializer
::
skip
(
size_t
num_bytes
)
{
auto
last
=
buf_
.
end
();
auto
remaining
=
static_cast
<
size_t
>
(
std
::
distance
(
write_pos_
,
last
));
if
(
remaining
>=
num_bytes
)
{
write_pos_
+=
num_bytes
;
}
else
{
buf_
.
insert
(
last
,
num_bytes
-
remaining
,
0
);
write_pos_
=
buf_
.
end
();
}
}
error
binary_serializer
::
begin_object
(
uint16_t
&
nr
,
std
::
string
&
name
)
{
if
(
nr
!=
0
)
return
apply
(
nr
);
if
(
auto
err
=
apply
(
nr
))
return
err
;
return
apply
(
name
);
}
error
binary_serializer
::
end_object
()
{
return
none
;
}
error
binary_serializer
::
begin_sequence
(
size_t
&
list_size
)
{
auto
s
=
static_cast
<
uint32_t
>
(
list_size
);
return
apply
(
s
);
}
error
binary_serializer
::
end_sequence
()
{
return
none
;
}
error
binary_serializer
::
apply_raw
(
size_t
num_bytes
,
void
*
data
)
{
auto
ptr
=
reinterpret_cast
<
char
*>
(
data
);
auto
last
=
buf_
.
end
();
if
(
write_pos_
==
last
)
{
buf_
.
insert
(
last
,
ptr
,
ptr
+
num_bytes
);
write_pos_
=
buf_
.
end
();
}
else
if
(
write_pos_
+
num_bytes
<
last
)
{
memcpy
(
&
(
*
write_pos_
),
ptr
,
num_bytes
);
write_pos_
+=
num_bytes
;
}
else
{
auto
remaining
=
static_cast
<
size_t
>
(
last
-
write_pos_
);
memcpy
(
&
(
*
write_pos_
),
ptr
,
remaining
);
buf_
.
insert
(
last
,
ptr
+
remaining
,
ptr
+
num_bytes
);
write_pos_
=
buf_
.
end
();
}
return
none
;
}
error
binary_serializer
::
apply_impl
(
int8_t
&
x
)
{
return
apply_raw
(
sizeof
(
int8_t
),
&
x
);
}
error
binary_serializer
::
apply_impl
(
uint8_t
&
x
)
{
return
apply_raw
(
sizeof
(
uint8_t
),
&
x
);
}
error
binary_serializer
::
apply_impl
(
int16_t
&
x
)
{
return
apply_int
(
*
this
,
static_cast
<
uint16_t
>
(
x
));
}
error
binary_serializer
::
apply_impl
(
uint16_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_serializer
::
apply_impl
(
int32_t
&
x
)
{
return
apply_int
(
*
this
,
static_cast
<
uint32_t
>
(
x
));
}
error
binary_serializer
::
apply_impl
(
uint32_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_serializer
::
apply_impl
(
int64_t
&
x
)
{
return
apply_int
(
*
this
,
static_cast
<
uint64_t
>
(
x
));
}
error
binary_serializer
::
apply_impl
(
uint64_t
&
x
)
{
return
apply_int
(
*
this
,
x
);
}
error
binary_serializer
::
apply_impl
(
float
&
x
)
{
return
apply_int
(
*
this
,
detail
::
pack754
(
x
));
}
error
binary_serializer
::
apply_impl
(
double
&
x
)
{
return
apply_int
(
*
this
,
detail
::
pack754
(
x
));
}
error
binary_serializer
::
apply_impl
(
long
double
&
x
)
{
// The IEEE-754 conversion does not work for long double
// => fall back to string serialization (event though it sucks).
std
::
ostringstream
oss
;
oss
<<
std
::
setprecision
(
std
::
numeric_limits
<
long
double
>::
digits
)
<<
x
;
auto
tmp
=
oss
.
str
();
return
apply_impl
(
tmp
);
}
error
binary_serializer
::
apply_impl
(
std
::
string
&
x
)
{
auto
str_size
=
x
.
size
();
if
(
str_size
==
0
)
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
end_sequence
();
});
auto
data
=
const_cast
<
char
*>
(
x
.
c_str
());
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
apply_raw
(
str_size
,
data
);
},
[
&
]
{
return
end_sequence
();
});
}
error
binary_serializer
::
apply_impl
(
std
::
u16string
&
x
)
{
auto
str_size
=
x
.
size
();
if
(
auto
err
=
begin_sequence
(
str_size
))
return
err
;
for
(
auto
c
:
x
)
{
// The standard does not guarantee that char16_t is exactly 16 bits.
if
(
auto
err
=
apply_int
(
*
this
,
static_cast
<
uint16_t
>
(
c
)))
return
err
;
}
return
none
;
}
error
binary_serializer
::
apply_impl
(
std
::
u32string
&
x
)
{
auto
str_size
=
x
.
size
();
if
(
auto
err
=
begin_sequence
(
str_size
))
return
err
;
for
(
auto
c
:
x
)
{
// The standard does not guarantee that char16_t is exactly 16 bits.
if
(
auto
err
=
apply_int
(
*
this
,
static_cast
<
uint32_t
>
(
c
)))
return
err
;
}
return
none
;
}
}
// namespace caf
libcaf_core/test/serialization.cpp
View file @
afb884bb
...
@@ -21,51 +21,52 @@
...
@@ -21,51 +21,52 @@
#define CAF_SUITE serialization
#define CAF_SUITE serialization
#include "caf/test/unit_test.hpp"
#include "caf/test/unit_test.hpp"
#include <new>
#include <algorithm>
#include <set>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <list>
#include <stack>
#include <tuple>
#include <locale>
#include <locale>
#include <memory>
#include <memory>
#include <string>
#include <new>
#include <limits>
#include <set>
#include <vector>
#include <cstring>
#include <sstream>
#include <sstream>
#include <cstdint>
#include <stack>
#include <cstring>
#include <cassert>
#include <iterator>
#include <typeinfo>
#include <iostream>
#include <stdexcept>
#include <stdexcept>
#include <
algorithm
>
#include <
string
>
#include <
functional
>
#include <
tuple
>
#include <type_traits>
#include <type_traits>
#include <typeinfo>
#include <vector>
#include "caf/message.hpp"
#include "caf/streambuf.hpp"
#include "caf/serializer.hpp"
#include "caf/ref_counted.hpp"
#include "caf/deserializer.hpp"
#include "caf/actor_system.hpp"
#include "caf/actor_system.hpp"
#include "caf/proxy_registry.hpp"
#include "caf/message_handler.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/primitive_variant.hpp"
#include "caf/binary_serializer.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/actor_system_config.hpp"
#include "caf/actor_system_config.hpp"
#include "caf/make_type_erased_view.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/binary_serializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/make_type_erased_tuple_view.hpp"
#include "caf/make_type_erased_tuple_view.hpp"
#include "caf/make_type_erased_view.hpp"
#include "caf/message.hpp"
#include "caf/message_handler.hpp"
#include "caf/primitive_variant.hpp"
#include "caf/proxy_registry.hpp"
#include "caf/ref_counted.hpp"
#include "caf/serializer.hpp"
#include "caf/stream_deserializer.hpp"
#include "caf/stream_serializer.hpp"
#include "caf/streambuf.hpp"
#include "caf/detail/enum_to_string.hpp"
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/safe_equal.hpp"
#include "caf/detail/safe_equal.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/enum_to_string.hpp"
#include "caf/detail/get_mac_addresses.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
caf
;
using
namespace
caf
;
...
@@ -138,6 +139,7 @@ public:
...
@@ -138,6 +139,7 @@ public:
}
}
};
};
template
<
class
Serializer
,
class
Deserializer
>
struct
fixture
{
struct
fixture
{
int32_t
i32
=
-
345
;
int32_t
i32
=
-
345
;
int64_t
i64
=
-
1234567890123456789ll
;
int64_t
i64
=
-
1234567890123456789ll
;
...
@@ -159,21 +161,25 @@ struct fixture {
...
@@ -159,21 +161,25 @@ struct fixture {
config
cfg
;
config
cfg
;
actor_system
system
;
actor_system
system
;
scoped_execution_unit
context
;
message
msg
;
message
msg
;
message
recursive
;
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
vector
<
char
>
serialize
(
T
&
x
,
Ts
&
...
xs
)
{
vector
<
char
>
serialize
(
T
&
x
,
Ts
&
...
xs
)
{
vector
<
char
>
buf
;
vector
<
char
>
buf
;
binary_serializer
bs
{
&
context
,
buf
};
binary_serializer
sink
{
system
,
buf
};
bs
(
x
,
xs
...);
if
(
auto
err
=
sink
(
x
,
xs
...))
CAF_FAIL
(
"serialization failed: "
<<
system
.
render
(
err
)
<<
", data: "
<<
deep_to_string
(
std
::
forward_as_tuple
(
x
,
xs
...)));
return
buf
;
return
buf
;
}
}
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
void
deserialize
(
const
vector
<
char
>&
buf
,
T
&
x
,
Ts
&
...
xs
)
{
void
deserialize
(
const
vector
<
char
>&
buf
,
T
&
x
,
Ts
&
...
xs
)
{
binary_deserializer
bd
{
&
context
,
buf
};
binary_deserializer
source
{
system
,
buf
};
bd
(
x
,
xs
...);
if
(
auto
err
=
source
(
x
,
xs
...))
CAF_FAIL
(
"deserialization failed: "
<<
system
.
render
(
err
));
}
}
// serializes `x` and then deserializes and returns the serialized value
// serializes `x` and then deserializes and returns the serialized value
...
@@ -191,15 +197,20 @@ struct fixture {
...
@@ -191,15 +197,20 @@ struct fixture {
message
result
;
message
result
;
auto
tmp
=
make_message
(
x
);
auto
tmp
=
make_message
(
x
);
deserialize
(
serialize
(
tmp
),
result
);
deserialize
(
serialize
(
tmp
),
result
);
CAF_REQUIRE
(
result
.
match_elements
<
T
>
());
if
(
!
result
.
match_elements
<
T
>
())
CAF_FAIL
(
"expected: "
<<
x
<<
", got: "
<<
result
);
return
result
.
get_as
<
T
>
(
0
);
return
result
.
get_as
<
T
>
(
0
);
}
}
fixture
()
fixture
()
:
system
(
cfg
)
{
:
system
(
cfg
),
context
(
&
system
)
{
rs
.
str
.
assign
(
string
(
str
.
rbegin
(),
str
.
rend
()));
rs
.
str
.
assign
(
string
(
str
.
rbegin
(),
str
.
rend
()));
msg
=
make_message
(
i32
,
i64
,
dur
,
ts
,
te
,
str
,
rs
);
msg
=
make_message
(
i32
,
i64
,
dur
,
ts
,
te
,
str
,
rs
);
config_value
::
dictionary
dict
;
put
(
dict
,
"scheduler.policy"
,
atom
(
"none"
));
put
(
dict
,
"scheduler.max-threads"
,
42
);
put
(
dict
,
"nodes.preload"
,
make_config_value_list
(
"sun"
,
"venus"
,
"mercury"
,
"earth"
,
"mars"
));
recursive
=
make_message
(
config_value
{
std
::
move
(
dict
)});
}
}
};
};
...
@@ -227,9 +238,43 @@ struct is_message {
...
@@ -227,9 +238,43 @@ struct is_message {
}
// namespace <anonymous>
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
serialization_tests
,
fixture
)
#define SERIALIZATION_TEST(name) \
template <class Serializer, class Deserializer> \
CAF_TEST
(
ieee_754_conversion
)
{
struct name##_tpl : fixture<Serializer, Deserializer> { \
using super = fixture<Serializer, Deserializer>; \
using super::i32; \
using super::i64; \
using super::f32; \
using super::f64; \
using super::dur; \
using super::ts; \
using super::te; \
using super::str; \
using super::rs; \
using super::ta; \
using super::ra; \
using super::system; \
using super::msg; \
using super::recursive; \
using super::serialize; \
using super::deserialize; \
using super::roundtrip; \
using super::msg_roundtrip; \
void run_test_impl(); \
}; \
namespace { \
using name##_binary = name##_tpl<binary_serializer, binary_deserializer>; \
using name##_stream = name##_tpl<stream_serializer<vectorbuf>, \
stream_deserializer<charbuf>>; \
::caf::test::detail::adder<::caf::test::test_impl<name##_binary>> \
CAF_UNIQUE(a_binary){CAF_XSTR(CAF_SUITE), CAF_XSTR(name##_binary), false}; \
::caf::test::detail::adder<::caf::test::test_impl<name##_stream>> \
CAF_UNIQUE(a_stream){CAF_XSTR(CAF_SUITE), CAF_XSTR(name##_stream), false}; \
} \
template <class Serializer, class Deserializer> \
void name##_tpl<Serializer, Deserializer>::run_test_impl()
SERIALIZATION_TEST
(
ieee_754_conversion
)
{
// check conversion of float
// check conversion of float
float
f1
=
3.1415925
f
;
// float value
float
f1
=
3.1415925
f
;
// float value
auto
p1
=
caf
::
detail
::
pack754
(
f1
);
// packet value
auto
p1
=
caf
::
detail
::
pack754
(
f1
);
// packet value
...
@@ -244,70 +289,70 @@ CAF_TEST(ieee_754_conversion) {
...
@@ -244,70 +289,70 @@ CAF_TEST(ieee_754_conversion) {
CAF_CHECK_EQUAL
(
f2
,
u2
);
CAF_CHECK_EQUAL
(
f2
,
u2
);
}
}
CAF
_TEST
(
i32_values
)
{
SERIALIZATION
_TEST
(
i32_values
)
{
auto
buf
=
serialize
(
i32
);
auto
buf
=
serialize
(
i32
);
int32_t
x
;
int32_t
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
i32
,
x
);
CAF_CHECK_EQUAL
(
i32
,
x
);
}
}
CAF
_TEST
(
i64_values
)
{
SERIALIZATION
_TEST
(
i64_values
)
{
auto
buf
=
serialize
(
i64
);
auto
buf
=
serialize
(
i64
);
int64_t
x
;
int64_t
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
i64
,
x
);
CAF_CHECK_EQUAL
(
i64
,
x
);
}
}
CAF
_TEST
(
float_values
)
{
SERIALIZATION
_TEST
(
float_values
)
{
auto
buf
=
serialize
(
f32
);
auto
buf
=
serialize
(
f32
);
float
x
;
float
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
f32
,
x
);
CAF_CHECK_EQUAL
(
f32
,
x
);
}
}
CAF
_TEST
(
double_values
)
{
SERIALIZATION
_TEST
(
double_values
)
{
auto
buf
=
serialize
(
f64
);
auto
buf
=
serialize
(
f64
);
double
x
;
double
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
f64
,
x
);
CAF_CHECK_EQUAL
(
f64
,
x
);
}
}
CAF
_TEST
(
duration_values
)
{
SERIALIZATION
_TEST
(
duration_values
)
{
auto
buf
=
serialize
(
dur
);
auto
buf
=
serialize
(
dur
);
duration
x
;
duration
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
dur
,
x
);
CAF_CHECK_EQUAL
(
dur
,
x
);
}
}
CAF
_TEST
(
timestamp_values
)
{
SERIALIZATION
_TEST
(
timestamp_values
)
{
auto
buf
=
serialize
(
ts
);
auto
buf
=
serialize
(
ts
);
timestamp
x
;
timestamp
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
ts
,
x
);
CAF_CHECK_EQUAL
(
ts
,
x
);
}
}
CAF
_TEST
(
enum_classes
)
{
SERIALIZATION
_TEST
(
enum_classes
)
{
auto
buf
=
serialize
(
te
);
auto
buf
=
serialize
(
te
);
test_enum
x
;
test_enum
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
te
,
x
);
CAF_CHECK_EQUAL
(
te
,
x
);
}
}
CAF
_TEST
(
strings
)
{
SERIALIZATION
_TEST
(
strings
)
{
auto
buf
=
serialize
(
str
);
auto
buf
=
serialize
(
str
);
string
x
;
string
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
str
,
x
);
CAF_CHECK_EQUAL
(
str
,
x
);
}
}
CAF
_TEST
(
custom_struct
)
{
SERIALIZATION
_TEST
(
custom_struct
)
{
auto
buf
=
serialize
(
rs
);
auto
buf
=
serialize
(
rs
);
raw_struct
x
;
raw_struct
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
CAF_CHECK_EQUAL
(
rs
,
x
);
CAF_CHECK_EQUAL
(
rs
,
x
);
}
}
CAF
_TEST
(
atoms
)
{
SERIALIZATION
_TEST
(
atoms
)
{
auto
foo
=
atom
(
"foo"
);
auto
foo
=
atom
(
"foo"
);
CAF_CHECK_EQUAL
(
foo
,
roundtrip
(
foo
));
CAF_CHECK_EQUAL
(
foo
,
roundtrip
(
foo
));
CAF_CHECK_EQUAL
(
foo
,
msg_roundtrip
(
foo
));
CAF_CHECK_EQUAL
(
foo
,
msg_roundtrip
(
foo
));
...
@@ -316,7 +361,7 @@ CAF_TEST(atoms) {
...
@@ -316,7 +361,7 @@ CAF_TEST(atoms) {
CAF_CHECK_EQUAL
(
bar_atom
::
value
,
msg_roundtrip
(
atom
(
"bar"
)));
CAF_CHECK_EQUAL
(
bar_atom
::
value
,
msg_roundtrip
(
atom
(
"bar"
)));
}
}
CAF
_TEST
(
raw_arrays
)
{
SERIALIZATION
_TEST
(
raw_arrays
)
{
auto
buf
=
serialize
(
ra
);
auto
buf
=
serialize
(
ra
);
int
x
[
3
];
int
x
[
3
];
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
...
@@ -324,7 +369,7 @@ CAF_TEST(raw_arrays) {
...
@@ -324,7 +369,7 @@ CAF_TEST(raw_arrays) {
CAF_CHECK_EQUAL
(
ra
[
i
],
x
[
i
]);
CAF_CHECK_EQUAL
(
ra
[
i
],
x
[
i
]);
}
}
CAF
_TEST
(
arrays
)
{
SERIALIZATION
_TEST
(
arrays
)
{
auto
buf
=
serialize
(
ta
);
auto
buf
=
serialize
(
ta
);
test_array
x
;
test_array
x
;
deserialize
(
buf
,
x
);
deserialize
(
buf
,
x
);
...
@@ -335,7 +380,7 @@ CAF_TEST(arrays) {
...
@@ -335,7 +380,7 @@ CAF_TEST(arrays) {
CAF_CHECK_EQUAL
(
ta
.
value2
[
i
][
j
],
x
.
value2
[
i
][
j
]);
CAF_CHECK_EQUAL
(
ta
.
value2
[
i
][
j
],
x
.
value2
[
i
][
j
]);
}
}
CAF
_TEST
(
empty_non_pods
)
{
SERIALIZATION
_TEST
(
empty_non_pods
)
{
test_empty_non_pod
x
;
test_empty_non_pod
x
;
auto
buf
=
serialize
(
x
);
auto
buf
=
serialize
(
x
);
CAF_REQUIRE
(
buf
.
empty
());
CAF_REQUIRE
(
buf
.
empty
());
...
@@ -354,7 +399,7 @@ std::string hexstr(const std::vector<char>& buf) {
...
@@ -354,7 +399,7 @@ std::string hexstr(const std::vector<char>& buf) {
return
oss
.
str
();
return
oss
.
str
();
}
}
CAF
_TEST
(
messages
)
{
SERIALIZATION
_TEST
(
messages
)
{
// serialize original message which uses tuple_vals internally and
// serialize original message which uses tuple_vals internally and
// deserialize into a message which uses type_erased_value pointers
// deserialize into a message which uses type_erased_value pointers
message
x
;
message
x
;
...
@@ -369,9 +414,10 @@ CAF_TEST(messages) {
...
@@ -369,9 +414,10 @@ CAF_TEST(messages) {
deserialize
(
buf2
,
y
);
deserialize
(
buf2
,
y
);
CAF_CHECK_EQUAL
(
to_string
(
msg
),
to_string
(
y
));
CAF_CHECK_EQUAL
(
to_string
(
msg
),
to_string
(
y
));
CAF_CHECK
(
is_message
(
y
).
equal
(
i32
,
i64
,
dur
,
ts
,
te
,
str
,
rs
));
CAF_CHECK
(
is_message
(
y
).
equal
(
i32
,
i64
,
dur
,
ts
,
te
,
str
,
rs
));
CAF_CHECK_EQUAL
(
to_string
(
recursive
),
to_string
(
roundtrip
(
recursive
)));
}
}
CAF
_TEST
(
multiple_messages
)
{
SERIALIZATION
_TEST
(
multiple_messages
)
{
auto
m
=
make_message
(
rs
,
te
);
auto
m
=
make_message
(
rs
,
te
);
auto
buf
=
serialize
(
te
,
m
,
msg
);
auto
buf
=
serialize
(
te
,
m
,
msg
);
test_enum
t
;
test_enum
t
;
...
@@ -385,15 +431,15 @@ CAF_TEST(multiple_messages) {
...
@@ -385,15 +431,15 @@ CAF_TEST(multiple_messages) {
}
}
CAF
_TEST
(
type_erased_value
)
{
SERIALIZATION
_TEST
(
type_erased_value
)
{
auto
buf
=
serialize
(
str
);
auto
buf
=
serialize
(
str
);
type_erased_value_ptr
ptr
{
new
type_erased_value_impl
<
std
::
string
>
};
type_erased_value_ptr
ptr
{
new
type_erased_value_impl
<
std
::
string
>
};
binary_deserializer
bd
{
&
context
,
buf
.
data
(),
buf
.
size
()
};
binary_deserializer
source
{
system
,
buf
};
ptr
->
load
(
bd
);
ptr
->
load
(
source
);
CAF_CHECK_EQUAL
(
str
,
*
reinterpret_cast
<
const
std
::
string
*>
(
ptr
->
get
()));
CAF_CHECK_EQUAL
(
str
,
*
reinterpret_cast
<
const
std
::
string
*>
(
ptr
->
get
()));
}
}
CAF
_TEST
(
type_erased_view
)
{
SERIALIZATION
_TEST
(
type_erased_view
)
{
auto
str_view
=
make_type_erased_view
(
str
);
auto
str_view
=
make_type_erased_view
(
str
);
auto
buf
=
serialize
(
str_view
);
auto
buf
=
serialize
(
str_view
);
std
::
string
res
;
std
::
string
res
;
...
@@ -401,7 +447,7 @@ CAF_TEST(type_erased_view) {
...
@@ -401,7 +447,7 @@ CAF_TEST(type_erased_view) {
CAF_CHECK_EQUAL
(
str
,
res
);
CAF_CHECK_EQUAL
(
str
,
res
);
}
}
CAF
_TEST
(
type_erased_tuple
)
{
SERIALIZATION
_TEST
(
type_erased_tuple
)
{
auto
tview
=
make_type_erased_tuple_view
(
str
,
i32
);
auto
tview
=
make_type_erased_tuple_view
(
str
,
i32
);
CAF_CHECK_EQUAL
(
to_string
(
tview
),
deep_to_string
(
std
::
make_tuple
(
str
,
i32
)));
CAF_CHECK_EQUAL
(
to_string
(
tview
),
deep_to_string
(
std
::
make_tuple
(
str
,
i32
)));
auto
buf
=
serialize
(
tview
);
auto
buf
=
serialize
(
tview
);
...
@@ -415,7 +461,7 @@ CAF_TEST(type_erased_tuple) {
...
@@ -415,7 +461,7 @@ CAF_TEST(type_erased_tuple) {
CAF_CHECK_EQUAL
(
to_string
(
tview
),
deep_to_string
(
std
::
make_tuple
(
str
,
i32
)));
CAF_CHECK_EQUAL
(
to_string
(
tview
),
deep_to_string
(
std
::
make_tuple
(
str
,
i32
)));
}
}
CAF
_TEST
(
streambuf_serialization
)
{
SERIALIZATION
_TEST
(
streambuf_serialization
)
{
auto
data
=
std
::
string
{
"The quick brown fox jumps over the lazy dog"
};
auto
data
=
std
::
string
{
"The quick brown fox jumps over the lazy dog"
};
std
::
vector
<
char
>
buf
;
std
::
vector
<
char
>
buf
;
// First, we check the standard use case in CAF where stream serializers own
// First, we check the standard use case in CAF where stream serializers own
...
@@ -443,7 +489,7 @@ CAF_TEST(streambuf_serialization) {
...
@@ -443,7 +489,7 @@ CAF_TEST(streambuf_serialization) {
CAF_CHECK
(
data
==
target
);
CAF_CHECK
(
data
==
target
);
}
}
CAF
_TEST
(
byte_sequence_optimization
)
{
SERIALIZATION
_TEST
(
byte_sequence_optimization
)
{
std
::
vector
<
uint8_t
>
data
(
42
);
std
::
vector
<
uint8_t
>
data
(
42
);
std
::
fill
(
data
.
begin
(),
data
.
end
(),
0x2a
);
std
::
fill
(
data
.
begin
(),
data
.
end
(),
0x2a
);
std
::
vector
<
uint8_t
>
buf
;
std
::
vector
<
uint8_t
>
buf
;
...
@@ -462,7 +508,7 @@ CAF_TEST(byte_sequence_optimization) {
...
@@ -462,7 +508,7 @@ CAF_TEST(byte_sequence_optimization) {
[](
uint8_t
c
)
{
return
c
==
0x2a
;
}));
[](
uint8_t
c
)
{
return
c
==
0x2a
;
}));
}
}
CAF
_TEST
(
long_sequences
)
{
SERIALIZATION
_TEST
(
long_sequences
)
{
std
::
vector
<
char
>
data
;
std
::
vector
<
char
>
data
;
binary_serializer
sink
{
nullptr
,
data
};
binary_serializer
sink
{
nullptr
,
data
};
size_t
n
=
std
::
numeric_limits
<
uint32_t
>::
max
();
size_t
n
=
std
::
numeric_limits
<
uint32_t
>::
max
();
...
@@ -475,7 +521,7 @@ CAF_TEST(long_sequences) {
...
@@ -475,7 +521,7 @@ CAF_TEST(long_sequences) {
CAF_CHECK_EQUAL
(
n
,
m
);
CAF_CHECK_EQUAL
(
n
,
m
);
}
}
CAF_TEST
(
non
-
empty
vector
)
{
SERIALIZATION_TEST
(
non_empty_
vector
)
{
CAF_MESSAGE
(
"deserializing into a non-empty vector overrides any content"
);
CAF_MESSAGE
(
"deserializing into a non-empty vector overrides any content"
);
std
::
vector
<
int
>
foo
{
1
,
2
,
3
};
std
::
vector
<
int
>
foo
{
1
,
2
,
3
};
std
::
vector
<
int
>
bar
{
0
};
std
::
vector
<
int
>
bar
{
0
};
...
@@ -487,21 +533,21 @@ CAF_TEST(non-empty vector) {
...
@@ -487,21 +533,21 @@ CAF_TEST(non-empty vector) {
// -- our vector<bool> serialization packs into an uint64_t. Hence, the
// -- our vector<bool> serialization packs into an uint64_t. Hence, the
// critical sizes to test are 0, 1, 63, 64, and 65.
// critical sizes to test are 0, 1, 63, 64, and 65.
CAF
_TEST
(
bool_vector_size_0
)
{
SERIALIZATION
_TEST
(
bool_vector_size_0
)
{
std
::
vector
<
bool
>
xs
;
std
::
vector
<
bool
>
xs
;
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[]"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[]"
);
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
}
CAF
_TEST
(
bool_vector_size_1
)
{
SERIALIZATION
_TEST
(
bool_vector_size_1
)
{
std
::
vector
<
bool
>
xs
{
true
};
std
::
vector
<
bool
>
xs
{
true
};
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[1]"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[1]"
);
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
}
CAF
_TEST
(
bool_vector_size_63
)
{
SERIALIZATION
_TEST
(
bool_vector_size_63
)
{
std
::
vector
<
bool
>
xs
;
std
::
vector
<
bool
>
xs
;
for
(
int
i
=
0
;
i
<
63
;
++
i
)
for
(
int
i
=
0
;
i
<
63
;
++
i
)
xs
.
push_back
(
i
%
3
==
0
);
xs
.
push_back
(
i
%
3
==
0
);
...
@@ -514,7 +560,7 @@ CAF_TEST(bool_vector_size_63) {
...
@@ -514,7 +560,7 @@ CAF_TEST(bool_vector_size_63) {
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
}
CAF
_TEST
(
bool_vector_size_64
)
{
SERIALIZATION
_TEST
(
bool_vector_size_64
)
{
std
::
vector
<
bool
>
xs
;
std
::
vector
<
bool
>
xs
;
for
(
int
i
=
0
;
i
<
64
;
++
i
)
for
(
int
i
=
0
;
i
<
64
;
++
i
)
xs
.
push_back
(
i
%
5
==
0
);
xs
.
push_back
(
i
%
5
==
0
);
...
@@ -527,7 +573,7 @@ CAF_TEST(bool_vector_size_64) {
...
@@ -527,7 +573,7 @@ CAF_TEST(bool_vector_size_64) {
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
}
CAF
_TEST
(
bool_vector_size_65
)
{
SERIALIZATION
_TEST
(
bool_vector_size_65
)
{
std
::
vector
<
bool
>
xs
;
std
::
vector
<
bool
>
xs
;
for
(
int
i
=
0
;
i
<
65
;
++
i
)
for
(
int
i
=
0
;
i
<
65
;
++
i
)
xs
.
push_back
(
!
(
i
%
7
==
0
));
xs
.
push_back
(
!
(
i
%
7
==
0
));
...
@@ -539,5 +585,3 @@ CAF_TEST(bool_vector_size_65) {
...
@@ -539,5 +585,3 @@ CAF_TEST(bool_vector_size_65) {
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_io/src/instance.cpp
View file @
afb884bb
...
@@ -198,24 +198,18 @@ bool instance::dispatch(execution_unit* ctx, const strong_actor_ptr& sender,
...
@@ -198,24 +198,18 @@ bool instance::dispatch(execution_unit* ctx, const strong_actor_ptr& sender,
void
instance
::
write
(
execution_unit
*
ctx
,
buffer_type
&
buf
,
void
instance
::
write
(
execution_unit
*
ctx
,
buffer_type
&
buf
,
header
&
hdr
,
payload_writer
*
pw
)
{
header
&
hdr
,
payload_writer
*
pw
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
hdr
));
CAF_LOG_TRACE
(
CAF_ARG
(
hdr
));
error
err
;
binary_serializer
sink
{
ctx
,
buf
}
;
if
(
pw
!=
nullptr
)
{
if
(
pw
!=
nullptr
)
{
auto
pos
=
buf
.
size
();
// Write the BASP header after the payload.
// write payload first (skip first 72 bytes and write header later)
auto
header_offset
=
buf
.
size
();
char
placeholder
[
basp
::
header_size
];
sink
.
skip
(
header_size
);
buf
.
insert
(
buf
.
end
(),
std
::
begin
(
placeholder
),
std
::
end
(
placeholder
));
if
(
auto
err
=
(
*
pw
)(
sink
))
binary_serializer
bs
{
ctx
,
buf
};
CAF_LOG_ERROR
(
CAF_ARG
(
err
));
(
*
pw
)(
bs
);
sink
.
seek
(
header_offset
);
auto
plen
=
buf
.
size
()
-
pos
-
basp
::
header_size
;
auto
payload_len
=
buf
.
size
()
-
(
header_offset
+
basp
::
header_size
);
CAF_ASSERT
(
plen
<=
std
::
numeric_limits
<
uint32_t
>::
max
());
hdr
.
payload_len
=
static_cast
<
uint32_t
>
(
payload_len
);
hdr
.
payload_len
=
static_cast
<
uint32_t
>
(
plen
);
stream_serializer
<
charbuf
>
out
{
ctx
,
buf
.
data
()
+
pos
,
basp
::
header_size
};
err
=
out
(
hdr
);
}
else
{
binary_serializer
bs
{
ctx
,
buf
};
err
=
bs
(
hdr
);
}
}
if
(
err
)
if
(
auto
err
=
sink
(
hdr
)
)
CAF_LOG_ERROR
(
CAF_ARG
(
err
));
CAF_LOG_ERROR
(
CAF_ARG
(
err
));
}
}
...
...
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