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
d0c322ae
Commit
d0c322ae
authored
May 12, 2011
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
binary_deserializer
parent
65a71be9
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
469 additions
and
466 deletions
+469
-466
cppa.creator.user
cppa.creator.user
+1
-1
cppa.files
cppa.files
+3
-0
cppa/actor.hpp
cppa/actor.hpp
+21
-6
cppa/binary_deserializer.hpp
cppa/binary_deserializer.hpp
+36
-0
cppa/detail/default_uniform_type_info_impl.hpp
cppa/detail/default_uniform_type_info_impl.hpp
+38
-38
cppa/object.hpp
cppa/object.hpp
+12
-52
cppa/uniform_type_info.hpp
cppa/uniform_type_info.hpp
+20
-17
cppa/util/type_list.hpp
cppa/util/type_list.hpp
+51
-51
libcppa.Makefile
libcppa.Makefile
+6
-1
src/actor.cpp
src/actor.cpp
+14
-0
src/binary_deserializer.cpp
src/binary_deserializer.cpp
+168
-0
src/binary_serializer.cpp
src/binary_serializer.cpp
+3
-1
src/uniform_type_info.cpp
src/uniform_type_info.cpp
+49
-21
unit_testing/main.cpp
unit_testing/main.cpp
+1
-1
unit_testing/test__serialization.cpp
unit_testing/test__serialization.cpp
+19
-241
unit_testing/test__uniform_type.cpp
unit_testing/test__uniform_type.cpp
+27
-36
No files found.
cppa.creator.user
View file @
d0c322ae
...
...
@@ -135,7 +135,7 @@
</data>
<data>
<variable>
ProjectExplorer.Project.Updater.EnvironmentId
</variable>
<value
type=
"QString"
>
{
07fcd197-092d-45a0-8500-3be614e6ae31
}
</value>
<value
type=
"QString"
>
{
23902c37-f07e-47cd-bb19-c366b9f708db
}
</value>
</data>
<data>
<variable>
ProjectExplorer.Project.Updater.FileVersion
</variable>
...
...
cppa.files
View file @
d0c322ae
...
...
@@ -140,3 +140,6 @@ cppa/util/rm_ref.hpp
cppa/util/is_iterable.hpp
cppa/binary_serializer.hpp
src/binary_serializer.cpp
cppa/binary_deserializer.hpp
src/binary_deserializer.cpp
src/actor.cpp
cppa/actor.hpp
View file @
d0c322ae
#ifndef ACTOR_HPP
#define ACTOR_HPP
#include <cstdint>
#include "cppa/group.hpp"
#include "cppa/channel.hpp"
...
...
@@ -12,6 +14,12 @@ class deserializer;
class
actor
:
public
channel
{
std
::
uint32_t
m_id
;
protected:
actor
();
public:
virtual
void
join
(
group_ptr
&
what
)
=
0
;
...
...
@@ -22,6 +30,13 @@ class actor : public channel
virtual
bool
remove_backlink
(
const
intrusive_ptr
<
actor
>&
to
)
=
0
;
virtual
bool
establish_backlink
(
const
intrusive_ptr
<
actor
>&
to
)
=
0
;
inline
std
::
uint32_t
id
()
const
{
return
m_id
;
}
/**
* @brief
*/
static
intrusive_ptr
<
actor
>
by_id
(
std
::
uint32_t
actor_id
);
};
typedef
intrusive_ptr
<
actor
>
actor_ptr
;
...
...
cppa/binary_deserializer.hpp
0 → 100644
View file @
d0c322ae
#ifndef BINARY_DESERIALIZER_HPP
#define BINARY_DESERIALIZER_HPP
#include "cppa/deserializer.hpp"
namespace
cppa
{
class
binary_deserializer
:
public
deserializer
{
const
char
*
pos
;
const
char
*
end
;
void
range_check
(
size_t
read_size
);
public:
binary_deserializer
(
const
char
*
buf
,
size_t
buf_size
);
binary_deserializer
(
const
char
*
begin
,
const
char
*
end
);
std
::
string
seek_object
();
std
::
string
peek_object
();
void
begin_object
(
const
std
::
string
&
type_name
);
void
end_object
();
size_t
begin_sequence
();
void
end_sequence
();
primitive_variant
read_value
(
primitive_type
ptype
);
void
read_tuple
(
size_t
size
,
const
primitive_type
*
ptypes
,
primitive_variant
*
storage
);
};
}
// namespace cppa
#endif // BINARY_DESERIALIZER_HPP
cppa/detail/default_uniform_type_info_impl.hpp
View file @
d0c322ae
...
...
@@ -79,16 +79,16 @@ struct has_default_uniform_type_info_impl
||
is_stl_compliant_list
<
T
>::
value
;
};
template
<
typename
Struct
>
class
default_uniform_type_info_impl
:
public
util
::
uniform_type_info_base
<
Struct
>
template
<
typename
T
>
class
default_uniform_type_info_impl
:
public
util
::
uniform_type_info_base
<
T
>
{
template
<
typename
T
>
template
<
typename
X
>
struct
is_invalid
{
static
const
bool
value
=
!
util
::
is_primitive
<
T
>::
value
&&
!
is_stl_compliant_map
<
T
>::
value
&&
!
is_stl_compliant_list
<
T
>::
value
;
static
const
bool
value
=
!
util
::
is_primitive
<
X
>::
value
&&
!
is_stl_compliant_map
<
X
>::
value
&&
!
is_stl_compliant_list
<
X
>::
value
;
};
class
member
...
...
@@ -124,8 +124,8 @@ class default_uniform_type_info_impl : public util::uniform_type_info_base<Struc
public:
template
<
typename
T
,
class
C
>
member
(
uniform_type_info
*
mtptr
,
T
C
::*
mem_ptr
)
:
m_meta
(
mtptr
)
template
<
typename
R
,
class
C
>
member
(
uniform_type_info
*
mtptr
,
R
C
::*
mem_ptr
)
:
m_meta
(
mtptr
)
{
m_serialize
=
[
mem_ptr
]
(
const
uniform_type_info
*
mt
,
const
void
*
obj
,
...
...
@@ -193,70 +193,70 @@ class default_uniform_type_info_impl : public util::uniform_type_info_base<Struc
// pr.first = member pointer
// pr.second = meta object to handle pr.first
template
<
typename
T
,
class
C
,
typename
...
Args
>
void
push_back
(
std
::
pair
<
T
C
::*
,
util
::
uniform_type_info_base
<
T
>*>
pr
,
template
<
typename
R
,
class
C
,
typename
...
Args
>
void
push_back
(
std
::
pair
<
R
C
::*
,
util
::
uniform_type_info_base
<
R
>*>
pr
,
const
Args
&
...
args
)
{
m_members
.
push_back
({
pr
.
second
,
pr
.
first
});
push_back
(
args
...);
}
template
<
class
C
,
typename
T
,
typename
...
Args
>
typename
util
::
enable_if
<
util
::
is_primitive
<
T
>
>::
type
push_back
(
T
C
::*
mem_ptr
,
const
Args
&
...
args
)
template
<
typename
R
,
class
C
,
typename
...
Args
>
typename
util
::
enable_if
<
util
::
is_primitive
<
R
>
>::
type
push_back
(
R
C
::*
mem_ptr
,
const
Args
&
...
args
)
{
m_members
.
push_back
({
new
primitive_member
<
T
>
(),
mem_ptr
});
m_members
.
push_back
({
new
primitive_member
<
R
>
(),
mem_ptr
});
push_back
(
args
...);
}
template
<
class
C
,
typename
T
,
typename
...
Args
>
typename
util
::
enable_if
<
is_stl_compliant_list
<
T
>
>::
type
push_back
(
T
C
::*
mem_ptr
,
const
Args
&
...
args
)
template
<
typename
R
,
class
C
,
typename
...
Args
>
typename
util
::
enable_if
<
is_stl_compliant_list
<
R
>
>::
type
push_back
(
R
C
::*
mem_ptr
,
const
Args
&
...
args
)
{
m_members
.
push_back
({
new
list_member
<
T
>
(),
mem_ptr
});
m_members
.
push_back
({
new
list_member
<
R
>
(),
mem_ptr
});
push_back
(
args
...);
}
template
<
class
C
,
typename
T
,
typename
...
Args
>
typename
util
::
enable_if
<
is_stl_compliant_map
<
T
>
>::
type
push_back
(
T
C
::*
mem_ptr
,
const
Args
&
...
args
)
template
<
typename
R
,
class
C
,
typename
...
Args
>
typename
util
::
enable_if
<
is_stl_compliant_map
<
R
>
>::
type
push_back
(
R
C
::*
mem_ptr
,
const
Args
&
...
args
)
{
m_members
.
push_back
({
new
map_member
<
T
>
(),
mem_ptr
});
m_members
.
push_back
({
new
map_member
<
R
>
(),
mem_ptr
});
push_back
(
args
...);
}
template
<
class
C
,
typename
T
,
typename
...
Args
>
typename
util
::
enable_if
<
is_invalid
<
T
>>::
type
push_back
(
T
C
::*
mem_ptr
,
const
Args
&
...
args
)
template
<
typename
R
,
class
C
,
typename
...
Args
>
typename
util
::
enable_if
<
is_invalid
<
R
>>::
type
push_back
(
R
C
::*
mem_ptr
,
const
Args
&
...
args
)
{
static_assert
(
util
::
is_primitive
<
T
>::
value
,
static_assert
(
util
::
is_primitive
<
R
>::
value
,
"T is neither a primitive type nor a "
"stl-compliant list/map"
);
}
template
<
typename
T
>
template
<
class
C
>
void
init_
(
typename
util
::
enable_if
<
util
::
disjunction
<
std
::
is_same
<
T
,
util
::
void_type
>
,
std
::
is_same
<
T
,
any_type
>>>::
type
*
=
0
)
util
::
disjunction
<
std
::
is_same
<
C
,
util
::
void_type
>
,
std
::
is_same
<
C
,
any_type
>>>::
type
*
=
0
)
{
// any_type doesn't have any fields (no serialization required)
}
template
<
typename
T
>
void
init_
(
typename
util
::
enable_if
<
util
::
is_primitive
<
T
>>::
type
*
=
0
)
template
<
typename
P
>
void
init_
(
typename
util
::
enable_if
<
util
::
is_primitive
<
P
>>::
type
*
=
0
)
{
m_members
.
push_back
(
member
::
fake_member
(
new
primitive_member
<
T
>
()));
m_members
.
push_back
(
member
::
fake_member
(
new
primitive_member
<
P
>
()));
}
template
<
typename
T
>
template
<
typename
X
>
void
init_
(
typename
util
::
disable_if
<
util
::
disjunction
<
util
::
is_primitive
<
T
>
,
std
::
is_same
<
T
,
util
::
void_type
>
,
std
::
is_same
<
T
,
any_type
>>>::
type
*
=
0
)
util
::
disjunction
<
util
::
is_primitive
<
X
>
,
std
::
is_same
<
X
,
util
::
void_type
>
,
std
::
is_same
<
X
,
any_type
>>>::
type
*
=
0
)
{
static_assert
(
util
::
is_primitive
<
T
>::
value
,
static_assert
(
util
::
is_primitive
<
X
>::
value
,
"T is neither a primitive type nor a "
"stl-compliant list/map"
);
}
...
...
@@ -271,7 +271,7 @@ class default_uniform_type_info_impl : public util::uniform_type_info_base<Struc
default_uniform_type_info_impl
()
{
init_
<
Struct
>
();
init_
<
T
>
();
}
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
...
...
cppa/object.hpp
View file @
d0c322ae
...
...
@@ -67,6 +67,7 @@ public:
* @post {@code other.type() == nullptr}
*/
object
&
operator
=
(
object
&&
other
);
object
&
operator
=
(
const
object
&
other
);
bool
equal
(
const
object
&
other
)
const
;
...
...
@@ -97,79 +98,38 @@ inline void assert_type(const object& obj, const std::type_info& tinfo)
}
}
// get a const reference
template
<
typename
T
>
struct
object_caster
<
const
T
&>
{
static
const
T
&
_
(
const
object
&
obj
)
{
assert_type
(
obj
,
typeid
(
T
));
return
*
reinterpret_cast
<
const
T
*>
(
obj
.
m_value
);
}
};
// get a mutable reference
template
<
typename
T
>
struct
object_caster
<
T
&>
struct
object_caster
{
static
T
&
_
(
object
&
obj
)
{
assert_type
(
obj
,
typeid
(
T
));
return
*
reinterpret_cast
<
T
*>
(
obj
.
m_value
);
}
};
// get a const pointer
template
<
typename
T
>
struct
object_caster
<
const
T
*>
{
static
const
T
*
_
(
const
object
&
obj
)
{
assert_type
(
obj
,
typeid
(
T
));
return
reinterpret_cast
<
const
T
*>
(
obj
.
m_value
);
}
};
// get a mutable pointer
template
<
typename
T
>
struct
object_caster
<
T
*>
{
static
T
*
_
(
object
&
obj
)
static
const
T
&
_
(
const
object
&
obj
)
{
assert_type
(
obj
,
typeid
(
T
));
return
reinterpret_cast
<
T
*>
(
obj
.
m_value
);
return
*
reinterpret_cast
<
const
T
*>
(
obj
.
m_value
);
}
};
template
<
typename
T
>
struct
is_const_reference
:
std
::
false_type
{
};
template
<
typename
T
>
struct
is_const_reference
<
const
T
&>
:
std
::
true_type
{
};
}
// namespace detail
template
<
typename
T
>
struct
is_const_pointer
:
std
::
false_type
{
};
template
<
typename
T
>
struct
is_const_pointer
<
const
T
*>
:
std
::
true_type
{
};
}
template
<
typename
T
>
T
object_cast
(
object
&
obj
)
T
&
get
(
object
&
obj
)
{
static_assert
(
util
::
disjunction
<
std
::
is_pointer
<
T
>
,
std
::
is_reference
<
T
>>::
value
,
"T is
neither a reference n
or a pointer type."
);
std
::
is_reference
<
T
>>::
value
==
false
,
"T is
a reference
or a pointer type."
);
return
detail
::
object_caster
<
T
>::
_
(
obj
);
}
template
<
typename
T
>
const
T
&
object_cas
t
(
const
object
&
obj
)
const
T
&
ge
t
(
const
object
&
obj
)
{
static_assert
(
util
::
disjunction
<
detail
::
is_const
_pointer
<
T
>
,
detail
::
is_const
_reference
<
T
>>::
value
,
"T is
neither a const reference nor a const
pointer type."
);
static_assert
(
util
::
disjunction
<
std
::
is
_pointer
<
T
>
,
std
::
is
_reference
<
T
>>::
value
,
"T is
a reference a
pointer type."
);
return
detail
::
object_caster
<
T
>::
_
(
obj
);
}
...
...
cppa/uniform_type_info.hpp
View file @
d0c322ae
...
...
@@ -21,17 +21,21 @@
namespace
cppa
{
class
uniform_type_info
;
const
uniform_type_info
*
uniform_typeid
(
const
std
::
type_info
&
);
/**
* @brief Provides a platform independent type name and (very primitive)
* reflection in combination with {@link cppa::object object}.
* @brief Provides a platform independent type name and
a
(very primitive)
*
kind of
reflection in combination with {@link cppa::object object}.
*
* The platform dependent type name (from GCC or Microsofts VC++ Compiler) is
* translated to a (usually) shorter and platform independent name.
*
* This name is usually equal to the "in-sourcecode-name",
* with a few exceptions:
* This name is equal to the "in-sourcecode-name" but with a few exceptions:
* - @c std::string is named @c \@str
* - @c std::wstring is named @c \@wstr
* - @c std::u16string is named @c \@u16str
* - @c std::u32string is named @c \@u32str
* - @c integers are named <tt>\@(i|u)$size</tt>\n
* e.g.: @c \@i32 is a 32 bit signed integer; @c \@u16
* is a 16 bit unsigned integer
...
...
@@ -46,10 +50,7 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
friend
class
object
;
// needs access to by_type_info()
template
<
typename
T
>
friend
uniform_type_info
*
uniform_typeid
();
friend
uniform_type_info
*
uniform_typeid
(
const
std
::
type_info
&
);
friend
const
uniform_type_info
*
uniform_typeid
(
const
std
::
type_info
&
);
public:
...
...
@@ -94,11 +95,11 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
uniform_type_info
&
operator
=
(
uniform_type_info
&&
)
=
delete
;
uniform_type_info
&
operator
=
(
const
uniform_type_info
&
)
=
delete
;
static
uniform_type_info
*
by_type_info
(
const
std
::
type_info
&
tinfo
);
static
const
uniform_type_info
*
by_type_info
(
const
std
::
type_info
&
tinfo
);
protected:
explicit
uniform_type_info
(
const
std
::
string
&
uniform_name
);
uniform_type_info
(
const
std
::
string
&
uniform_name
);
public:
...
...
@@ -134,6 +135,7 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
{
return
id
().
compare
(
other
.
id
());
}
/**
* @brief Add a new type mapping to the libCPPA internal type system.
* @return <code>true</code> if @p uniform_type was added as known
...
...
@@ -158,11 +160,14 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
// const ToStringFun& ts, const FromStringFun& fs);
/**
* @brief Create an object of this type.
* @brief Create
s
an object of this type.
*/
object
create
()
const
;
object
deserialize
(
deserializer
*
from
)
const
;
/**
* @brief Deserializes an object of this type from @p source.
*/
object
deserialize
(
deserializer
*
source
)
const
;
protected:
...
...
@@ -203,12 +208,10 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
};
uniform_type_info
*
uniform_typeid
(
const
std
::
type_info
&
tinfo
);
template
<
typename
T
>
uniform_type_info
*
uniform_typeid
()
inline
const
uniform_type_info
*
uniform_typeid
()
{
return
uniform_type
_info
::
by_type_info
(
typeid
(
T
));
return
uniform_type
id
(
typeid
(
T
));
}
bool
operator
==
(
const
uniform_type_info
&
lhs
,
const
std
::
type_info
&
rhs
);
...
...
cppa/util/type_list.hpp
View file @
d0c322ae
...
...
@@ -12,7 +12,7 @@ namespace cppa {
// forward declarations
class
uniform_type_info
;
uniform_type_info
*
uniform_typeid
(
const
std
::
type_info
&
tinfo
);
const
uniform_type_info
*
uniform_typeid
(
const
std
::
type_info
&
);
}
// namespace cppa
...
...
libcppa.Makefile
View file @
d0c322ae
...
...
@@ -6,6 +6,9 @@ INCLUDES = -I./
HEADERS = cppa/actor.hpp \
cppa/any_type.hpp \
cppa/binary_deserializer.hpp \
cppa/binary_serializer.hpp \
cppa/channel.hpp \
cppa/config.hpp \
cppa/context.hpp \
cppa/cow_ptr.hpp \
...
...
@@ -65,7 +68,9 @@ HEADERS = cppa/actor.hpp \
cppa/util/type_list_pop_back.hpp \
cppa/util/void_type.hpp
SOURCES = src/actor_behavior.cpp \
SOURCES = src/actor.cpp \
src/actor_behavior.cpp \
src/binary_deserializer.cpp \
src/binary_serializer.cpp \
src/blocking_message_queue.cpp \
src/channel.cpp \
...
...
src/actor.cpp
0 → 100644
View file @
d0c322ae
#include "cppa/actor.hpp"
namespace
cppa
{
actor
::
actor
()
:
m_id
(
0
)
{
}
intrusive_ptr
<
actor
>
actor
::
by_id
(
std
::
uint32_t
)
{
return
nullptr
;
}
}
// namespace cppa
src/binary_deserializer.cpp
0 → 100644
View file @
d0c322ae
#include <cstdint>
#include <cstring>
#include <iterator>
#include <exception>
#include <stdexcept>
#include <type_traits>
#include "cppa/util/enable_if.hpp"
#include "cppa/binary_deserializer.hpp"
using
cppa
::
util
::
enable_if
;
namespace
cppa
{
namespace
{
typedef
const
char
*
iterator
;
inline
void
range_check
(
iterator
begin
,
iterator
end
,
size_t
read_size
)
{
if
((
begin
+
read_size
)
>
end
)
{
throw
std
::
out_of_range
(
"binary_deserializer::read()"
);
}
}
// @return the next iterator position
template
<
typename
T
>
iterator
read
(
iterator
,
iterator
,
T
&
,
typename
enable_if
<
std
::
is_floating_point
<
T
>
>::
type
*
=
0
)
{
throw
std
::
logic_error
(
"read floating point not implemented yet"
);
}
template
<
typename
T
>
iterator
read
(
iterator
begin
,
iterator
end
,
T
&
storage
,
typename
enable_if
<
std
::
is_integral
<
T
>
>::
type
*
=
0
)
{
range_check
(
begin
,
end
,
sizeof
(
T
));
memcpy
(
&
storage
,
begin
,
sizeof
(
T
));
return
begin
+
sizeof
(
T
);
}
iterator
read
(
iterator
begin
,
iterator
end
,
std
::
string
&
storage
)
{
std
::
uint32_t
str_size
;
begin
=
read
(
begin
,
end
,
str_size
);
range_check
(
begin
,
end
,
str_size
);
storage
.
clear
();
storage
.
reserve
(
str_size
);
iterator
cpy_end
=
begin
+
str_size
;
std
::
copy
(
begin
,
cpy_end
,
std
::
back_inserter
(
storage
));
return
begin
+
str_size
;
}
template
<
typename
CharType
,
typename
StringType
>
iterator
read_unicode_string
(
iterator
begin
,
iterator
end
,
StringType
&
str
)
{
std
::
uint32_t
str_size
;
begin
=
read
(
begin
,
end
,
str_size
);
str
.
reserve
(
str_size
);
for
(
size_t
i
=
0
;
i
<
str_size
;
++
i
)
{
CharType
c
;
begin
=
read
(
begin
,
end
,
c
);
str
+=
static_cast
<
typename
StringType
::
value_type
>
(
c
);
}
return
begin
;
}
iterator
read
(
iterator
begin
,
iterator
end
,
std
::
u16string
&
storage
)
{
// char16_t is guaranteed to has *at least* 16 bytes,
// but not to have *exactly* 16 bytes; thus use uint16_t
return
read_unicode_string
<
std
::
uint16_t
>
(
begin
,
end
,
storage
);
}
iterator
read
(
iterator
begin
,
iterator
end
,
std
::
u32string
&
storage
)
{
// char32_t is guaranteed to has *at least* 32 bytes,
// but not to have *exactly* 32 bytes; thus use uint32_t
return
read_unicode_string
<
std
::
uint32_t
>
(
begin
,
end
,
storage
);
}
struct
pt_reader
{
iterator
begin
;
iterator
end
;
pt_reader
(
iterator
bbegin
,
iterator
bend
)
:
begin
(
bbegin
),
end
(
bend
)
{
}
template
<
typename
T
>
inline
void
operator
()(
T
&
value
)
{
begin
=
read
(
begin
,
end
,
value
);
}
};
}
// namespace <anonmyous>
binary_deserializer
::
binary_deserializer
(
const
char
*
buf
,
size_t
buf_size
)
:
pos
(
buf
),
end
(
buf
+
buf_size
)
{
}
binary_deserializer
::
binary_deserializer
(
const
char
*
bbegin
,
const
char
*
bend
)
:
pos
(
bbegin
),
end
(
bend
)
{
}
std
::
string
binary_deserializer
::
seek_object
()
{
std
::
string
result
;
pos
=
read
(
pos
,
end
,
result
);
return
result
;
}
std
::
string
binary_deserializer
::
peek_object
()
{
std
::
string
result
;
read
(
pos
,
end
,
result
);
return
result
;
}
void
binary_deserializer
::
begin_object
(
const
std
::
string
&
)
{
}
void
binary_deserializer
::
end_object
()
{
}
size_t
binary_deserializer
::
begin_sequence
()
{
static_assert
(
sizeof
(
size_t
)
>=
sizeof
(
std
::
uint32_t
),
"sizeof(size_t) < sizeof(uint32_t)"
);
std
::
uint32_t
result
;
pos
=
read
(
pos
,
end
,
result
);
return
static_cast
<
size_t
>
(
result
);
}
void
binary_deserializer
::
end_sequence
()
{
}
primitive_variant
binary_deserializer
::
read_value
(
primitive_type
ptype
)
{
primitive_variant
val
(
ptype
);
pt_reader
ptr
(
pos
,
end
);
val
.
apply
(
ptr
);
pos
=
ptr
.
begin
;
return
val
;
}
void
binary_deserializer
::
read_tuple
(
size_t
size
,
const
primitive_type
*
ptypes
,
primitive_variant
*
storage
)
{
for
(
auto
end
=
ptypes
+
size
;
ptypes
!=
end
;
++
ptypes
)
{
*
storage
=
std
::
move
(
read_value
(
*
ptypes
));
++
storage
;
}
}
}
// namespace cppa
src/binary_serializer.cpp
View file @
d0c322ae
...
...
@@ -52,9 +52,11 @@ class binary_writer
}
template
<
typename
T
>
void
operator
()(
const
T
&
value
,
void
operator
()(
const
T
&
,
typename
enable_if
<
std
::
is_floating_point
<
T
>
>::
type
*
=
0
)
{
throw
std
::
logic_error
(
"binary_serializer::write_floating_point "
"not implemented yet"
);
}
void
operator
()(
const
std
::
string
&
str
)
...
...
src/uniform_type_info.cpp
View file @
d0c322ae
...
...
@@ -47,6 +47,12 @@ inline const char* raw_name(const std::type_info& tinfo)
#endif
}
template
<
typename
T
>
struct
is_signed
:
std
::
integral_constant
<
bool
,
std
::
numeric_limits
<
T
>::
is_signed
>
{
};
template
<
typename
T
>
inline
const
char
*
raw_name
()
{
...
...
@@ -72,13 +78,13 @@ void push(std::map<int, std::pair<string_set, string_set>>& ints,
template
<
typename
Int
>
void
push
(
std
::
map
<
int
,
std
::
pair
<
string_set
,
string_set
>>&
ints
)
{
push
<
Int
>
(
ints
,
std
::
integral_constant
<
bool
,
std
::
numeric_limits
<
Int
>::
is_signed
>
());
push
<
Int
>
(
ints
,
is_signed
<
Int
>
());
}
template
<
typename
Int0
,
typename
Int1
,
typename
...
Ints
>
void
push
(
std
::
map
<
int
,
std
::
pair
<
string_set
,
string_set
>>&
ints
)
{
push
<
Int0
>
(
ints
,
std
::
integral_constant
<
bool
,
std
::
numeric_limits
<
Int0
>::
is_signed
>
());
push
<
Int0
>
(
ints
,
is_signed
<
Int0
>
());
push
<
Int1
,
Ints
...
>
(
ints
);
}
...
...
@@ -86,6 +92,33 @@ void push(std::map<int, std::pair<string_set, string_set>>& ints)
namespace
cppa
{
namespace
detail
{
namespace
{
class
actor_ptr_type_info_impl
:
public
util
::
uniform_type_info_base
<
actor_ptr
>
{
protected:
void
serialize
(
const
void
*
ptr
,
serializer
*
sink
)
const
{
sink
->
begin_object
(
name
());
sink
->
write_value
((
*
reinterpret_cast
<
const
actor_ptr
*>
(
ptr
))
->
id
());
sink
->
end_object
();
}
void
deserialize
(
void
*
ptr
,
deserializer
*
source
)
const
{
std
::
string
cname
=
source
->
seek_object
();
if
(
cname
!=
name
())
{
throw
std
::
logic_error
(
"wrong type name found"
);
}
source
->
begin_object
(
cname
);
auto
id
=
get
<
std
::
uint32_t
>
(
source
->
read_value
(
pt_uint32
));
*
reinterpret_cast
<
actor_ptr
*>
(
ptr
)
=
actor
::
by_id
(
id
);
source
->
end_object
();
}
};
class
uniform_type_info_map
{
...
...
@@ -127,8 +160,9 @@ class uniform_type_info_map
uniform_type_info_map
()
{
insert
<
std
::
string
>
();
//insert<wstring_obj>({std::string(raw_name<std::wstring>())});
//insert(new wstring_utype, { std::string(raw_name<std::wstring>()) });
insert
<
std
::
u16string
>
();
insert
<
std
::
u32string
>
();
insert
(
new
actor_ptr_type_info_impl
,
{
raw_name
<
actor_ptr
>
()
});
insert
<
float
>
();
insert
<
cppa
::
util
::
void_type
>
();
if
(
sizeof
(
double
)
==
sizeof
(
long
double
))
...
...
@@ -213,7 +247,9 @@ class uniform_type_info_map
{
if
(
!
m_by_rname
.
insert
(
std
::
make_pair
(
plain_name
,
what
)).
second
)
{
throw
std
::
runtime_error
(
plain_name
+
" already mapped to an uniform_type_info"
);
std
::
string
error_str
=
plain_name
;
error_str
+=
" already mapped to an uniform_type_info"
;
throw
std
::
runtime_error
(
error_str
);
}
}
return
true
;
...
...
@@ -260,7 +296,13 @@ uniform_type_info::~uniform_type_info()
{
}
uniform_type_info
*
uniform_type_info
::
by_type_info
(
const
std
::
type_info
&
tinf
)
object
uniform_type_info
::
create
()
const
{
return
{
new_instance
(),
this
};
}
const
uniform_type_info
*
uniform_type_info
::
by_type_info
(
const
std
::
type_info
&
tinf
)
{
auto
result
=
detail
::
s_uniform_type_info_map
().
by_raw_name
(
raw_name
(
tinf
));
if
(
!
result
)
...
...
@@ -281,20 +323,6 @@ uniform_type_info* uniform_type_info::by_uniform_name(const std::string& name)
return
result
;
}
/*
bool uniform_type_info::announce(const std::type_info& plain_type,
uniform_type_info* uniform_type)
{
string_set tmp = { std::string(raw_name(plain_type)) };
if (!detail::s_uniform_type_info_map().insert(tmp, uniform_type))
{
delete uniform_type;
return false;
}
return true;
}
*/
object
uniform_type_info
::
deserialize
(
deserializer
*
from
)
const
{
auto
ptr
=
new_instance
();
...
...
@@ -307,7 +335,7 @@ std::vector<uniform_type_info*> uniform_type_info::instances()
return
detail
::
s_uniform_type_info_map
().
get_all
();
}
uniform_type_info
*
uniform_typeid
(
const
std
::
type_info
&
tinfo
)
const
uniform_type_info
*
uniform_typeid
(
const
std
::
type_info
&
tinfo
)
{
return
uniform_type_info
::
by_type_info
(
tinfo
);
}
...
...
unit_testing/main.cpp
View file @
d0c322ae
...
...
@@ -55,7 +55,7 @@ int main(int argc, char** c_argv)
std
::
cout
<<
std
::
boolalpha
;
std
::
size_t
errors
=
0
;
RUN_TEST
(
test__primitive_variant
);
//
RUN_TEST(test__uniform_type);
RUN_TEST
(
test__uniform_type
);
RUN_TEST
(
test__intrusive_ptr
);
RUN_TEST
(
test__a_matches_b
);
RUN_TEST
(
test__type_list
);
...
...
unit_testing/test__serialization.cpp
View file @
d0c322ae
...
...
@@ -30,6 +30,7 @@
#include "cppa/primitive_type.hpp"
#include "cppa/primitive_variant.hpp"
#include "cppa/binary_serializer.hpp"
#include "cppa/binary_deserializer.hpp"
#include "cppa/util/apply.hpp"
#include "cppa/util/pt_token.hpp"
...
...
@@ -192,229 +193,6 @@ class string_serializer : public serializer
};
/*
class xml_serializer : public serializer
{
std::ostream& out;
std::string indentation;
inline void inc_indentation()
{
indentation.resize(indentation.size() + 4, ' ');
}
inline void dec_indentation()
{
auto isize = indentation.size();
indentation.resize((isize > 4) ? (isize - 4) : 0);
}
struct pt_writer
{
std::ostream& out;
const std::string& indentation;
pt_writer(std::ostream& ostr, const std::string& indent)
: out(ostr), indentation(indent)
{
}
template<typename T>
void operator()(const T& value)
{
out << indentation << "<value type=\""
<< primitive_type_name(type_to_ptype<T>::ptype)
<< "\">" << value << "</value>\n";
}
void operator()(const std::u16string&) { }
void operator()(const std::u32string&) { }
};
public:
xml_serializer(std::ostream& ostr) : out(ostr), indentation("") { }
void begin_object(const std::string& type_name)
{
out << indentation << "<object type=\"" << type_name << "\">\n";
inc_indentation();
}
void end_object()
{
dec_indentation();
out << indentation << "</object>\n";
}
void begin_list(size_t)
{
out << indentation << "<list>\n";
inc_indentation();
}
void end_list()
{
dec_indentation();
out << indentation << "</list>\n";
}
void write_value(const pt_value& value)
{
value.apply(pt_writer(out, indentation));
}
};
*/
class
binary_deserializer
:
public
deserializer
{
const
char
*
m_buf
;
size_t
m_rd_pos
;
size_t
m_buf_size
;
void
range_check
(
size_t
read_size
)
{
if
(
m_rd_pos
+
read_size
>=
m_buf_size
)
{
std
::
out_of_range
(
"binary_deserializer::read()"
);
}
}
template
<
typename
T
>
void
read
(
T
&
storage
,
bool
modify_rd_pos
=
true
)
{
range_check
(
sizeof
(
T
));
memcpy
(
&
storage
,
m_buf
+
m_rd_pos
,
sizeof
(
T
));
if
(
modify_rd_pos
)
m_rd_pos
+=
sizeof
(
T
);
}
void
read
(
std
::
string
&
str
,
bool
modify_rd_pos
=
true
)
{
std
::
uint32_t
str_size
;
read
(
str_size
,
modify_rd_pos
);
const
char
*
cpy_begin
;
if
(
modify_rd_pos
)
{
range_check
(
str_size
);
cpy_begin
=
m_buf
+
m_rd_pos
;
}
else
{
range_check
(
sizeof
(
std
::
uint32_t
)
+
str_size
);
cpy_begin
=
m_buf
+
m_rd_pos
+
sizeof
(
std
::
uint32_t
);
}
str
.
clear
();
str
.
reserve
(
str_size
);
const
char
*
cpy_end
=
cpy_begin
+
str_size
;
std
::
copy
(
cpy_begin
,
cpy_end
,
std
::
back_inserter
(
str
));
if
(
modify_rd_pos
)
m_rd_pos
+=
str_size
;
}
template
<
typename
CharType
,
typename
StringType
>
void
read_unicode_string
(
StringType
&
str
)
{
std
::
uint32_t
str_size
;
read
(
str_size
);
str
.
reserve
(
str_size
);
for
(
size_t
i
=
0
;
i
<
str_size
;
++
i
)
{
CharType
c
;
read
(
c
);
str
+=
static_cast
<
typename
StringType
::
value_type
>
(
c
);
}
}
void
read
(
std
::
u16string
&
str
)
{
// char16_t is guaranteed to has *at least* 16 bytes,
// but not to have *exactly* 16 bytes; thus use uint16_t
read_unicode_string
<
std
::
uint16_t
>
(
str
);
}
void
read
(
std
::
u32string
&
str
)
{
// char32_t is guaranteed to has *at least* 32 bytes,
// but not to have *exactly* 32 bytes; thus use uint32_t
read_unicode_string
<
std
::
uint32_t
>
(
str
);
}
struct
pt_reader
{
binary_deserializer
*
self
;
inline
pt_reader
(
binary_deserializer
*
mself
)
:
self
(
mself
)
{
}
template
<
typename
T
>
inline
void
operator
()(
T
&
value
)
{
self
->
read
(
value
);
}
};
public:
binary_deserializer
(
const
char
*
buf
,
size_t
buf_size
)
:
m_buf
(
buf
),
m_rd_pos
(
0
),
m_buf_size
(
buf_size
)
{
}
std
::
string
seek_object
()
{
std
::
string
result
;
read
(
result
);
return
result
;
}
std
::
string
peek_object
()
{
std
::
string
result
;
read
(
result
,
false
);
return
result
;
}
void
begin_object
(
const
std
::
string
&
)
{
}
void
end_object
()
{
}
size_t
begin_sequence
()
{
std
::
uint32_t
size
;
read
(
size
);
return
size
;
}
void
end_sequence
()
{
}
primitive_variant
read_value
(
primitive_type
ptype
)
{
primitive_variant
val
(
ptype
);
val
.
apply
(
pt_reader
(
this
));
return
val
;
}
void
read_tuple
(
size_t
size
,
const
primitive_type
*
ptypes
,
primitive_variant
*
storage
)
{
const
primitive_type
*
end
=
ptypes
+
size
;
for
(
;
ptypes
!=
end
;
++
ptypes
)
{
*
storage
=
std
::
move
(
read_value
(
*
ptypes
));
++
storage
;
}
}
};
class
string_deserializer
:
public
deserializer
{
...
...
@@ -713,6 +491,12 @@ compound_member(C Parent::*c_ptr, const Args&... args)
return
std
::
make_pair
(
c_ptr
,
meta_object
<
C
>
(
args
...));
}
template
<
typename
T
,
typename
...
Args
>
void
announce
(
const
Args
&
...
args
)
{
announce
(
meta_object
<
T
>
(
args
...));
}
std
::
size_t
test__serialization
()
{
CPPA_TEST
(
test__serialization
);
...
...
@@ -740,11 +524,11 @@ std::size_t test__serialization()
// test serializers / deserializers with struct_b
{
// get meta object for struct_b
announce
(
meta_object
<
struct_b
>
(
compound_member
(
&
struct_b
::
a
,
announce
<
struct_b
>
(
compound_member
(
&
struct_b
::
a
,
&
struct_a
::
x
,
&
struct_a
::
y
),
&
struct_b
::
z
,
&
struct_b
::
ints
)
);
&
struct_b
::
ints
);
// testees
struct_b
b1
=
{
{
1
,
2
},
3
,
{
4
,
5
,
6
,
7
,
8
,
9
,
10
}
};
struct_b
b2
;
...
...
@@ -764,7 +548,7 @@ std::size_t test__serialization()
binary_deserializer
bd
(
bs
.
data
(),
bs
.
size
());
object
res
=
root_object
.
deserialize
(
&
bd
);
CPPA_CHECK_EQUAL
(
res
.
type
().
name
(),
"struct_b"
);
b2
=
object_cast
<
const
struct_b
&
>
(
res
);
b2
=
get
<
struct_b
>
(
res
);
}
// cleanup
delete
buf
.
second
;
...
...
@@ -776,33 +560,27 @@ std::size_t test__serialization()
string_deserializer
strd
(
b1str
);
auto
res
=
root_object
.
deserialize
(
&
strd
);
CPPA_CHECK_EQUAL
(
res
.
type
().
name
(),
"struct_b"
);
b3
=
object_cast
<
const
struct_b
&
>
(
res
);
b3
=
get
<
struct_b
>
(
res
);
}
CPPA_CHECK_EQUAL
(
b1
,
b3
);
}
// test serializers / deserializers with struct_c
{
// get meta type of struct_c and "announce"
announce
(
meta_object
<
struct_c
>
(
&
struct_c
::
strings
,
&
struct_c
::
ints
)
);
announce
<
struct_c
>
(
&
struct_c
::
strings
,
&
struct_c
::
ints
);
// testees
struct_c
c1
=
{
{
{
"abc"
,
u"cba"
},
{
"x"
,
u"y"
}
},
{
9
,
4
,
5
}
};
struct_c
c2
;
// binary buffer
std
::
pair
<
size_t
,
char
*>
buf
;
// serialize c1 to buf
{
// serialize c1 to buf
binary_serializer
bs
;
root_object
.
serialize
(
c1
,
&
bs
);
buf
=
bs
.
take_buffer
();
}
// serialize c2 from buf
{
binary_deserializer
bd
(
buf
.
second
,
buf
.
first
);
binary_deserializer
bd
(
bs
.
data
(),
bs
.
size
());
auto
res
=
root_object
.
deserialize
(
&
bd
);
CPPA_CHECK_EQUAL
(
res
.
type
().
name
(),
"struct_c"
);
c2
=
object_cast
<
const
struct_c
&
>
(
res
);
c2
=
get
<
struct_c
>
(
res
);
}
delete
buf
.
second
;
// verify result of serialization / deserialization
CPPA_CHECK_EQUAL
(
c1
,
c2
);
}
...
...
unit_testing/test__uniform_type.cpp
View file @
d0c322ae
...
...
@@ -83,21 +83,12 @@ std::size_t test__uniform_type()
object obj1 = uniform_typeid<foo>()->create();
object obj2(obj1);
CPPA_CHECK_EQUAL(obj1, obj2);
get<foo>(obj1).value = 42;
CPPA_CHECK(obj1 != obj2);
CPPA_CHECK_EQUAL(get<foo>(obj1).value, 42);
CPPA_CHECK_EQUAL(get<foo>(obj2).value, 0);
}
{
object wstr_obj1 = uniform_typeid<std::wstring>()->create();
object_cast<std::wstring&>(wstr_obj1) = L"hello wstring!";
object wstr_obj2 = uniform_typeid<std::wstring>()->from_string("hello wstring!");
CPPA_CHECK_EQUAL(wstr_obj1, wstr_obj2);
const object& obj2_ref = wstr_obj2;
CPPA_CHECK_EQUAL(object_cast<std::wstring&>(wstr_obj1),
object_cast<const std::wstring&>(obj2_ref));
// couldn't be converted to ASCII
object_cast<std::wstring&>(wstr_obj1) = L"hello wstring\x05D4";
std::string narrowed = wstr_obj1.to_string();
CPPA_CHECK_EQUAL(narrowed, "hello wstring?");
}
*/
int
successful_announces
=
(
unused1
?
1
:
0
)
+
(
unused2
?
1
:
0
)
...
...
@@ -110,10 +101,10 @@ std::size_t test__uniform_type()
// the uniform_type_info implementation is correct
std
::
set
<
std
::
string
>
expected
=
{
"@_::foo",
// name of <anonymous namespace>::foo
// "@_::foo",
// name of <anonymous namespace>::foo
"@i8"
,
"@i16"
,
"@i32"
,
"@i64"
,
// signed integer names
"@u8"
,
"@u16"
,
"@u32"
,
"@u64"
,
// unsigned integer names
"@str", "@
wstr",
// strings
"@str"
,
"@
u16str"
,
"@u32str"
,
// strings
"float"
,
"double"
,
// floating points
"@0"
,
// util::void_type
// default announced cppa types
...
...
@@ -140,12 +131,15 @@ std::size_t test__uniform_type()
// compare the two sets
CPPA_CHECK_EQUAL
(
expected
.
size
(),
found
.
size
());
bool
expected_equals_found
=
false
;
if
(
expected
.
size
()
==
found
.
size
())
{
bool
expected_equals_found = std::equal(found.begin(),
expected_equals_found
=
std
::
equal
(
found
.
begin
(),
found
.
end
(),
expected
.
begin
());
CPPA_CHECK
(
expected_equals_found
);
}
if
(
!
expected_equals_found
)
{
cout
<<
"found:"
<<
endl
;
...
...
@@ -159,8 +153,5 @@ std::size_t test__uniform_type()
cout
<<
" - "
<<
tname
<<
endl
;
}
}
}
*/
return
CPPA_TEST_RESULT
;
}
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