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
Expand all
Hide 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
src/behavior.cpp
src/behavior_impl.cpp
src/behavior_stack.cpp
src/binary_deserializer.cpp
src/binary_serializer.cpp
src/blocking_actor.cpp
src/blocking_behavior.cpp
src/chars.cpp
...
...
libcaf_core/caf/all.hpp
View file @
afb884bb
...
...
@@ -93,12 +93,14 @@
#include "caf/composed_behavior.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/primitive_variant.hpp"
#include "caf/stream_serializer.hpp"
#include "caf/make_config_option.hpp"
#include "caf/timeout_definition.hpp"
#include "caf/actor_system_config.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/composable_behavior.hpp"
#include "caf/config_option_adder.hpp"
#include "caf/stream_deserializer.hpp"
#include "caf/typed_actor_pointer.hpp"
#include "caf/scoped_execution_unit.hpp"
#include "caf/typed_response_promise.hpp"
...
...
libcaf_core/caf/binary_deserializer.hpp
View file @
afb884bb
...
...
@@ -18,14 +18,81 @@
#pragma once
#include "caf/stream_deserializer.hpp"
#include "caf/streambuf.hpp"
#include <cstddef>
#include <cstdint>
#include <vector>
#include "caf/deserializer.hpp"
namespace
caf
{
/// A stream serializer that writes into an unbounded contiguous character
/// sequence.
using
binary_deserializer
=
stream_deserializer
<
charbuf
>
;
/// Implements the deserializer interface with a binary serialization protocol.
class
binary_deserializer
final
:
public
deserializer
{
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 @@
#pragma once
#include "caf/stream_serializer.hpp"
#include "caf/streambuf.hpp"
#include <cstddef>
#include <cstdint>
#include <vector>
#include "caf/serializer.hpp"
namespace
caf
{
/// A stream serializer that writes into an unbounded contiguous character
/// sequence.
using
binary_serializer
=
stream_serializer
<
vectorbuf
>
;
/// Implements the serializer interface with a binary serialization protocol.
class
binary_serializer
final
:
public
serializer
{
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:
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 --------------------
data_processor
(
const
data_processor
&
)
=
delete
;
...
...
@@ -137,7 +119,7 @@ public:
apply
(
T
&
x
)
{
static
constexpr
auto
tlindex
=
detail
::
tl_index_of
<
builtin_t
,
T
>::
value
;
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
>
...
...
@@ -147,25 +129,21 @@ public:
error
>::
type
apply
(
T
&
x
)
{
using
type
=
typename
detail
::
select_integer_type
<
static_cast
<
int
>
(
sizeof
(
T
))
*
(
std
::
is_signed
<
T
>::
value
?
-
1
:
1
)
>::
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
);
using
type
=
detail
::
select_integer_type_t
<
sizeof
(
T
),
std
::
is_signed
<
T
>::
value
>
;
return
apply_impl
(
reinterpret_cast
<
type
&>
(
x
));
}
error
apply
(
std
::
string
&
x
)
{
return
apply_
builtin
(
string8_v
,
&
x
);
return
apply_
impl
(
x
);
}
error
apply
(
std
::
u16string
&
x
)
{
return
apply_
builtin
(
string16_v
,
&
x
);
return
apply_
impl
(
x
);
}
error
apply
(
std
::
u32string
&
x
)
{
return
apply_
builtin
(
string32_v
,
&
x
);
return
apply_
impl
(
x
);
}
template
<
class
D
,
atom_value
V
>
...
...
@@ -549,8 +527,33 @@ public:
}
protected
:
/// Applies this processor to a single builtin value.
virtual
error
apply_builtin
(
builtin
in_out_type
,
void
*
in_out
)
=
0
;
virtual
error
apply_impl
(
int8_t
&
)
=
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
:
template
<
class
T
>
...
...
libcaf_core/caf/detail/select_integer_type.hpp
View file @
afb884bb
...
...
@@ -23,49 +23,52 @@
namespace
caf
{
namespace
detail
{
template
<
int
>
template
<
int
,
bool
>
struct
select_integer_type
;
template
<
>
struct
select_integer_type
<
-
1
>
{
struct
select_integer_type
<
1
,
true
>
{
using
type
=
int8_t
;
};
template
<
>
struct
select_integer_type
<
1
>
{
struct
select_integer_type
<
1
,
false
>
{
using
type
=
uint8_t
;
};
template
<
>
struct
select_integer_type
<
-
2
>
{
struct
select_integer_type
<
2
,
true
>
{
using
type
=
int16_t
;
};
template
<
>
struct
select_integer_type
<
2
>
{
struct
select_integer_type
<
2
,
false
>
{
using
type
=
uint16_t
;
};
template
<
>
struct
select_integer_type
<
-
4
>
{
struct
select_integer_type
<
4
,
true
>
{
using
type
=
int32_t
;
};
template
<
>
struct
select_integer_type
<
4
>
{
struct
select_integer_type
<
4
,
false
>
{
using
type
=
uint32_t
;
};
template
<
>
struct
select_integer_type
<
-
8
>
{
struct
select_integer_type
<
8
,
true
>
{
using
type
=
int64_t
;
};
template
<
>
struct
select_integer_type
<
8
>
{
struct
select_integer_type
<
8
,
false
>
{
using
type
=
uint64_t
;
};
template
<
int
Size
,
bool
IsSigned
>
using
select_integer_type_t
=
typename
select_integer_type
<
Size
,
IsSigned
>::
type
;
}
// namespace detail
}
// namespace caf
libcaf_core/caf/stream_deserializer.hpp
View file @
afb884bb
...
...
@@ -18,22 +18,21 @@
#pragma once
#include <limits>
#include <string>
#include <sstream>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <string>
#include <type_traits>
#include "caf/sec.hpp"
#include "caf/logger.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/logger.hpp"
#include "caf/sec.hpp"
namespace
caf
{
...
...
@@ -127,65 +126,81 @@ protected:
return
none
;
}
error
apply_builtin
(
builtin
type
,
void
*
val
)
override
{
CAF_ASSERT
(
val
!=
nullptr
);
switch
(
type
)
{
default:
// i8_v or u8_v
CAF_ASSERT
(
type
==
i8_v
||
type
==
u8_v
);
return
apply_raw
(
sizeof
(
uint8_t
),
val
);
case
i16_v
:
case
u16_v
:
return
apply_int
(
*
reinterpret_cast
<
uint16_t
*>
(
val
));
case
i32_v
:
case
u32_v
:
return
apply_int
(
*
reinterpret_cast
<
uint32_t
*>
(
val
));
case
i64_v
:
case
u64_v
:
return
apply_int
(
*
reinterpret_cast
<
uint64_t
*>
(
val
));
case
float_v
:
return
apply_float
(
*
reinterpret_cast
<
float
*>
(
val
));
case
double_v
:
return
apply_float
(
*
reinterpret_cast
<
double
*>
(
val
));
case
ldouble_v
:
{
// the IEEE-754 conversion does not work for long double
// => fall back to string serialization (even though it sucks)
std
::
string
tmp
;
auto
e
=
apply
(
tmp
);
if
(
e
)
return
e
;
std
::
istringstream
iss
{
std
::
move
(
tmp
)};
iss
>>
*
reinterpret_cast
<
long
double
*>
(
val
);
return
none
;
}
case
string8_v
:
{
auto
&
str
=
*
reinterpret_cast
<
std
::
string
*>
(
val
);
size_t
str_size
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
str
.
resize
(
str_size
);
auto
p
=
&
str
[
0
];
auto
data
=
reinterpret_cast
<
char_type
*>
(
p
);
auto
s
=
static_cast
<
streamsize
>
(
str_size
);
return
range_check
(
streambuf_
.
sgetn
(
data
,
s
),
str_size
);
},
[
&
]
{
return
end_sequence
();
});
}
case
string16_v
:
{
auto
&
str
=
*
reinterpret_cast
<
std
::
u16string
*>
(
val
);
str
.
clear
();
size_t
ns
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
ns
);
},
[
&
]
{
return
fill_range_c
<
uint16_t
>
(
str
,
ns
);
},
[
&
]
{
return
end_sequence
();
});
}
case
string32_v
:
{
auto
&
str
=
*
reinterpret_cast
<
std
::
u32string
*>
(
val
);
str
.
clear
();
size_t
ns
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
ns
);
},
[
&
]
{
return
fill_range_c
<
uint32_t
>
(
str
,
ns
);
},
[
&
]
{
return
end_sequence
();
});
}
}
error
apply_impl
(
int8_t
&
x
)
override
{
return
apply_raw
(
sizeof
(
int8_t
),
&
x
);
}
error
apply_impl
(
uint8_t
&
x
)
override
{
return
apply_raw
(
sizeof
(
uint8_t
),
&
x
);
}
error
apply_impl
(
int16_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
uint16_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
int32_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
uint32_t
&
x
)
override
{
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
;
if
(
auto
err
=
apply
(
tmp
))
return
err
;
std
::
istringstream
iss
{
std
::
move
(
tmp
)};
iss
>>
x
;
return
none
;
}
error
apply_impl
(
std
::
string
&
x
)
override
{
size_t
str_size
;
if
(
auto
err
=
begin_sequence
(
str_size
))
return
err
;
x
.
resize
(
str_size
);
auto
s
=
static_cast
<
streamsize
>
(
str_size
);
auto
data
=
reinterpret_cast
<
char_type
*>
(
&
x
[
0
]);
if
(
auto
err
=
range_check
(
streambuf_
.
sgetn
(
data
,
s
),
str_size
))
return
err
;
return
end_sequence
();
}
error
apply_impl
(
std
::
u16string
&
x
)
override
{
size_t
str_size
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
fill_range_c
<
uint16_t
>
(
x
,
str_size
);
},
[
&
]
{
return
end_sequence
();
});
}
error
apply_impl
(
std
::
u32string
&
x
)
override
{
size_t
str_size
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
fill_range_c
<
uint32_t
>
(
x
,
str_size
);
},
[
&
]
{
return
end_sequence
();
});
}
error
range_check
(
std
::
streamsize
got
,
size_t
need
)
{
...
...
@@ -197,20 +212,18 @@ protected:
template
<
class
T
>
error
apply_int
(
T
&
x
)
{
T
tmp
;
auto
e
=
apply_raw
(
sizeof
(
T
),
&
tmp
);
if
(
e
)
return
e
;
x
=
detail
::
from_network_order
(
tmp
);
typename
std
::
make_unsigned
<
T
>::
type
tmp
=
0
;
if
(
auto
err
=
apply_raw
(
sizeof
(
T
),
&
tmp
))
return
err
;
x
=
static_cast
<
T
>
(
detail
::
from_network_order
(
tmp
));
return
none
;
}
template
<
class
T
>
error
apply_float
(
T
&
x
)
{
typename
detail
::
ieee_754_trait
<
T
>::
packed_type
tmp
=
0
;
auto
e
=
apply_int
(
tmp
);
if
(
e
)
return
e
;
if
(
auto
err
=
apply_int
(
tmp
))
return
err
;
x
=
detail
::
unpack754
(
tmp
);
return
none
;
}
...
...
libcaf_core/caf/stream_serializer.hpp
View file @
afb884bb
...
...
@@ -125,65 +125,81 @@ protected:
return
none
;
}
error
apply_builtin
(
builtin
type
,
void
*
val
)
override
{
CAF_ASSERT
(
val
!=
nullptr
);
switch
(
type
)
{
default:
// i8_v or u8_v
CAF_ASSERT
(
type
==
i8_v
||
type
==
u8_v
);
return
apply_raw
(
sizeof
(
uint8_t
),
val
);
case
i16_v
:
case
u16_v
:
return
apply_int
(
*
reinterpret_cast
<
uint16_t
*>
(
val
));
case
i32_v
:
case
u32_v
:
return
apply_int
(
*
reinterpret_cast
<
uint32_t
*>
(
val
));
case
i64_v
:
case
u64_v
:
return
apply_int
(
*
reinterpret_cast
<
uint64_t
*>
(
val
));
case
float_v
:
return
apply_int
(
detail
::
pack754
(
*
reinterpret_cast
<
float
*>
(
val
)));
case
double_v
:
return
apply_int
(
detail
::
pack754
(
*
reinterpret_cast
<
double
*>
(
val
)));
case
ldouble_v
:
{
// 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
)
<<
*
reinterpret_cast
<
long
double
*>
(
val
);
auto
tmp
=
oss
.
str
();
return
apply
(
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
);
auto
s
=
str
->
size
();
// the standard does not guarantee that char16_t is exactly 16 bits...
return
error
::
eval
([
&
]
{
return
begin_sequence
(
s
);
},
[
&
]
{
return
consume_range_c
<
uint16_t
>
(
*
str
);
},
[
&
]
{
return
end_sequence
();
});
}
case
string32_v
:
{
auto
str
=
reinterpret_cast
<
std
::
u32string
*>
(
val
);
auto
s
=
str
->
size
();
// the standard does not guarantee that char32_t is exactly 32 bits...
return
error
::
eval
([
&
]
{
return
begin_sequence
(
s
);
},
[
&
]
{
return
consume_range_c
<
uint32_t
>
(
*
str
);
},
[
&
]
{
return
end_sequence
();
});
}
}
error
apply_impl
(
int8_t
&
x
)
override
{
return
apply_raw
(
sizeof
(
int8_t
),
&
x
);
}
error
apply_impl
(
uint8_t
&
x
)
override
{
return
apply_raw
(
sizeof
(
uint8_t
),
&
x
);
}
error
apply_impl
(
int16_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
uint16_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
int32_t
&
x
)
override
{
return
apply_int
(
x
);
}
error
apply_impl
(
uint32_t
&
x
)
override
{
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
;
oss
<<
std
::
setprecision
(
std
::
numeric_limits
<
long
double
>::
digits
)
<<
x
;
auto
tmp
=
oss
.
str
();
return
apply_impl
(
tmp
);
}
error
apply_impl
(
std
::
string
&
x
)
override
{
auto
str_size
=
x
.
size
();
auto
data
=
const_cast
<
char
*>
(
x
.
c_str
());
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
apply_raw
(
x
.
size
(),
data
);
},
[
&
]
{
return
end_sequence
();
});
}
error
apply_impl
(
std
::
u16string
&
x
)
override
{
auto
str_size
=
x
.
size
();
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
consume_range_c
<
uint16_t
>
(
x
);
},
[
&
]
{
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
>
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
);
}
...
...
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
This diff is collapsed.
Click to expand it.
libcaf_io/src/instance.cpp
View file @
afb884bb
...
...
@@ -198,24 +198,18 @@ bool instance::dispatch(execution_unit* ctx, const strong_actor_ptr& sender,
void
instance
::
write
(
execution_unit
*
ctx
,
buffer_type
&
buf
,
header
&
hdr
,
payload_writer
*
pw
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
hdr
));
error
err
;
binary_serializer
sink
{
ctx
,
buf
}
;
if
(
pw
!=
nullptr
)
{
auto
pos
=
buf
.
size
();
// write payload first (skip first 72 bytes and write header later)
char
placeholder
[
basp
::
header_size
];
buf
.
insert
(
buf
.
end
(),
std
::
begin
(
placeholder
),
std
::
end
(
placeholder
));
binary_serializer
bs
{
ctx
,
buf
};
(
*
pw
)(
bs
);
auto
plen
=
buf
.
size
()
-
pos
-
basp
::
header_size
;
CAF_ASSERT
(
plen
<=
std
::
numeric_limits
<
uint32_t
>::
max
());
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
);
// Write the BASP header after the payload.
auto
header_offset
=
buf
.
size
();
sink
.
skip
(
header_size
);
if
(
auto
err
=
(
*
pw
)(
sink
))
CAF_LOG_ERROR
(
CAF_ARG
(
err
));
sink
.
seek
(
header_offset
);
auto
payload_len
=
buf
.
size
()
-
(
header_offset
+
basp
::
header_size
);
hdr
.
payload_len
=
static_cast
<
uint32_t
>
(
payload_len
);
}
if
(
err
)
if
(
auto
err
=
sink
(
hdr
)
)
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