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
690dfbd7
Commit
690dfbd7
authored
Sep 10, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nicer and less verbose string serialization
parent
bb1056d2
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
64 additions
and
29 deletions
+64
-29
src/string_serialization.cpp
src/string_serialization.cpp
+55
-24
unit_testing/test__serialization.cpp
unit_testing/test__serialization.cpp
+9
-5
No files found.
src/string_serialization.cpp
View file @
690dfbd7
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#include <cctype>
#include <cctype>
#include <sstream>
#include <sstream>
#include <iomanip>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <algorithm>
#include "cppa/atom.hpp"
#include "cppa/atom.hpp"
...
@@ -49,6 +50,13 @@ namespace cppa {
...
@@ -49,6 +50,13 @@ namespace cppa {
namespace
{
namespace
{
bool
isbuiltin
(
const
string
&
type_name
)
{
return
type_name
==
"@str"
||
type_name
==
"@atom"
||
type_name
==
"@<>"
;
}
// serializes types as type_name(...) except:
// - strings are serialized "..."
// - atoms are serialized '...'
class
string_serializer
:
public
serializer
{
class
string_serializer
:
public
serializer
{
ostream
&
out
;
ostream
&
out
;
...
@@ -56,8 +64,9 @@ class string_serializer : public serializer {
...
@@ -56,8 +64,9 @@ class string_serializer : public serializer {
struct
pt_writer
{
struct
pt_writer
{
ostream
&
out
;
ostream
&
out
;
bool
suppress_quotes
;
pt_writer
(
ostream
&
mout
)
:
out
(
mout
)
{
}
pt_writer
(
ostream
&
mout
,
bool
suppress_quotes
=
false
)
:
out
(
mout
),
suppress_quotes
(
suppress_quotes
)
{
}
template
<
typename
T
>
template
<
typename
T
>
void
operator
()(
const
T
&
value
)
{
void
operator
()(
const
T
&
value
)
{
...
@@ -65,12 +74,12 @@ class string_serializer : public serializer {
...
@@ -65,12 +74,12 @@ class string_serializer : public serializer {
}
}
void
operator
()(
const
string
&
str
)
{
void
operator
()(
const
string
&
str
)
{
out
<<
"
\"
"
;
// << str
<< "\"";
if
(
!
suppress_quotes
)
out
<<
"
\"
"
;
for
(
char
c
:
str
)
{
for
(
char
c
:
str
)
{
if
(
c
==
'"'
)
out
<<
"
\\\"
"
;
if
(
c
==
'"'
)
out
<<
"
\\\"
"
;
else
out
<<
c
;
else
out
<<
c
;
}
}
out
<<
'"'
;
if
(
!
suppress_quotes
)
out
<<
"
\"
"
;
}
}
void
operator
()(
const
u16string
&
)
{
}
void
operator
()(
const
u16string
&
)
{
}
...
@@ -89,7 +98,9 @@ class string_serializer : public serializer {
...
@@ -89,7 +98,9 @@ class string_serializer : public serializer {
m_after_value
=
false
;
m_after_value
=
false
;
}
}
else
if
(
m_obj_just_opened
)
{
else
if
(
m_obj_just_opened
)
{
if
(
!
m_open_objects
.
empty
()
&&
!
isbuiltin
(
m_open_objects
.
top
()))
{
out
<<
" ( "
;
out
<<
" ( "
;
}
m_obj_just_opened
=
false
;
m_obj_just_opened
=
false
;
}
}
}
}
...
@@ -103,19 +114,21 @@ class string_serializer : public serializer {
...
@@ -103,19 +114,21 @@ class string_serializer : public serializer {
void
begin_object
(
const
string
&
type_name
)
{
void
begin_object
(
const
string
&
type_name
)
{
clear
();
clear
();
m_open_objects
.
push
(
type_name
);
m_open_objects
.
push
(
type_name
);
out
<<
type_name
;
// << " ( ";
// do not print type names for strings and atoms
if
(
!
isbuiltin
(
type_name
))
out
<<
type_name
;
m_obj_just_opened
=
true
;
m_obj_just_opened
=
true
;
}
}
void
end_object
()
{
void
end_object
()
{
if
(
m_obj_just_opened
)
{
if
(
m_obj_just_opened
)
{
// no open brackets to close
// no open brackets to close
m_obj_just_opened
=
false
;
m_obj_just_opened
=
false
;
}
}
else
{
out
<<
(
m_after_value
?
" )"
:
")"
);
}
m_after_value
=
true
;
m_after_value
=
true
;
if
(
!
m_open_objects
.
empty
())
{
if
(
!
m_open_objects
.
empty
())
{
if
(
!
isbuiltin
(
m_open_objects
.
top
()))
{
out
<<
(
m_after_value
?
" )"
:
")"
);
}
m_open_objects
.
pop
();
m_open_objects
.
pop
();
}
}
}
}
...
@@ -141,7 +154,9 @@ class string_serializer : public serializer {
...
@@ -141,7 +154,9 @@ class string_serializer : public serializer {
}
}
// write atoms as strings instead of integer values
// write atoms as strings instead of integer values
auto
av
=
static_cast
<
atom_value
>
(
get
<
uint64_t
>
(
value
));
auto
av
=
static_cast
<
atom_value
>
(
get
<
uint64_t
>
(
value
));
(
pt_writer
(
out
))(
to_string
(
av
));
out
<<
"'"
;
(
pt_writer
(
out
,
true
))(
to_string
(
av
));
out
<<
"'"
;
}
}
else
{
else
{
value
.
apply
(
pt_writer
(
out
));
value
.
apply
(
pt_writer
(
out
));
...
@@ -239,7 +254,8 @@ class string_deserializer : public deserializer {
...
@@ -239,7 +254,8 @@ class string_deserializer : public deserializer {
if
(
m_open_objects
.
empty
()
||
m_obj_had_left_parenthesis
.
empty
())
{
if
(
m_open_objects
.
empty
()
||
m_obj_had_left_parenthesis
.
empty
())
{
throw_malformed
(
"missing begin_object()"
);
throw_malformed
(
"missing begin_object()"
);
}
}
if
(
m_obj_had_left_parenthesis
.
top
()
==
false
)
{
if
(
m_obj_had_left_parenthesis
.
top
()
==
false
&&
!
isbuiltin
(
m_open_objects
.
top
()))
{
throw_malformed
(
"expected left parenthesis after "
throw_malformed
(
"expected left parenthesis after "
"begin_object call or void value"
);
"begin_object call or void value"
);
}
}
...
@@ -257,6 +273,17 @@ class string_deserializer : public deserializer {
...
@@ -257,6 +273,17 @@ class string_deserializer : public deserializer {
string
seek_object
()
{
string
seek_object
()
{
skip_space_and_comma
();
skip_space_and_comma
();
// shortcuts for builtin types
if
(
*
m_pos
==
'"'
)
{
return
"@str"
;
}
else
if
(
*
m_pos
==
'\''
)
{
return
"@atom"
;
}
else
if
(
*
m_pos
==
'{'
)
{
return
"@<>"
;
}
// default case
auto
substr_end
=
next_delimiter
();
auto
substr_end
=
next_delimiter
();
if
(
m_pos
==
substr_end
)
{
if
(
m_pos
==
substr_end
)
{
throw_malformed
(
"could not seek object type name"
);
throw_malformed
(
"could not seek object type name"
);
...
@@ -267,9 +294,10 @@ class string_deserializer : public deserializer {
...
@@ -267,9 +294,10 @@ class string_deserializer : public deserializer {
}
}
string
peek_object
()
{
string
peek_object
()
{
auto
pos
=
m_pos
;
string
result
=
seek_object
();
string
result
=
seek_object
();
// restore position in stream
// restore position in stream
m_pos
-=
result
.
size
()
;
m_pos
=
pos
;
return
result
;
return
result
;
}
}
...
@@ -277,28 +305,24 @@ class string_deserializer : public deserializer {
...
@@ -277,28 +305,24 @@ class string_deserializer : public deserializer {
m_open_objects
.
push
(
type_name
);
m_open_objects
.
push
(
type_name
);
//++m_obj_count;
//++m_obj_count;
skip_space_and_comma
();
skip_space_and_comma
();
// suppress leading parenthesis for builtin types
m_obj_had_left_parenthesis
.
push
(
try_consume
(
'('
));
m_obj_had_left_parenthesis
.
push
(
try_consume
(
'('
));
//consume('(');
//consume('(');
}
}
void
end_object
()
{
void
end_object
()
{
if
(
m_o
bj_had_left_parenthesi
s
.
empty
())
{
if
(
m_o
pen_object
s
.
empty
())
{
throw
_malformed
(
"missing begin_object()
"
);
throw
runtime_error
(
"no object to end
"
);
}
}
else
{
if
(
m_obj_had_left_parenthesis
.
top
()
==
true
)
{
if
(
m_obj_had_left_parenthesis
.
top
()
==
true
)
{
consume
(
')'
);
consume
(
')'
);
}
}
m_obj_had_left_parenthesis
.
pop
();
}
if
(
m_open_objects
.
empty
())
{
throw
runtime_error
(
"no object to end"
);
}
m_open_objects
.
pop
();
m_open_objects
.
pop
();
m_obj_had_left_parenthesis
.
pop
();
if
(
m_open_objects
.
empty
())
{
if
(
m_open_objects
.
empty
())
{
skip_space_and_comma
();
skip_space_and_comma
();
if
(
m_pos
!=
m_str
.
end
())
{
if
(
m_pos
!=
m_str
.
end
())
{
throw_malformed
(
"expected end of of string"
);
throw_malformed
(
string
(
"expected end of of string, found: "
)
+
*
m_pos
);
}
}
}
}
}
}
...
@@ -335,11 +359,18 @@ class string_deserializer : public deserializer {
...
@@ -335,11 +359,18 @@ class string_deserializer : public deserializer {
if
(
ptype
!=
pt_uint64
)
{
if
(
ptype
!=
pt_uint64
)
{
throw_malformed
(
"expected read of pt_uint64 after @atom"
);
throw_malformed
(
"expected read of pt_uint64 after @atom"
);
}
}
auto
str_val
=
get
<
string
>
(
read_value
(
pt_u8string
));
consume
(
'\''
);
if
(
str_val
.
size
()
>
10
)
{
auto
substr_end
=
find
(
m_pos
,
m_str
.
end
(),
'\''
);
if
(
substr_end
==
m_str
.
end
())
{
throw_malformed
(
"couldn't find trailing ' for atom"
);
}
else
if
((
substr_end
-
m_pos
)
>
10
)
{
throw_malformed
(
"atom string size > 10"
);
throw_malformed
(
"atom string size > 10"
);
}
}
return
detail
::
atom_val
(
str_val
.
c_str
());
string
substr
(
m_pos
,
substr_end
);
std
::
cout
<<
"atom string: "
<<
substr
<<
std
::
endl
;
m_pos
+=
substr
.
size
()
+
1
;
return
detail
::
atom_val
(
substr
.
c_str
(),
0xF
);
}
}
skip_space_and_comma
();
skip_space_and_comma
();
string
::
iterator
substr_end
;
string
::
iterator
substr_end
;
...
...
unit_testing/test__serialization.cpp
View file @
690dfbd7
...
@@ -78,6 +78,10 @@ struct struct_b {
...
@@ -78,6 +78,10 @@ struct struct_b {
list
<
int
>
ints
;
list
<
int
>
ints
;
};
};
string
to_string
(
const
struct_b
&
what
)
{
return
to_string
(
object
::
from
(
what
));
}
bool
operator
==
(
const
struct_b
&
lhs
,
const
struct_b
&
rhs
)
{
bool
operator
==
(
const
struct_b
&
lhs
,
const
struct_b
&
rhs
)
{
return
lhs
.
a
==
rhs
.
a
&&
lhs
.
z
==
rhs
.
z
&&
lhs
.
ints
==
rhs
.
ints
;
return
lhs
.
a
==
rhs
.
a
&&
lhs
.
z
==
rhs
.
z
&&
lhs
.
ints
==
rhs
.
ints
;
}
}
...
@@ -101,7 +105,7 @@ bool operator!=(const struct_c& lhs, const struct_c& rhs) {
...
@@ -101,7 +105,7 @@ bool operator!=(const struct_c& lhs, const struct_c& rhs) {
return
!
(
lhs
==
rhs
);
return
!
(
lhs
==
rhs
);
}
}
static
const
char
*
msg1str
=
u8R"__(
@<> ( { @i32 ( 42 ), @str ( "Hello \"World\"!" ) } )
)__"
;
static
const
char
*
msg1str
=
u8R"__(
{ @i32 ( 42 ), "Hello \"World\"!" }
)__"
;
struct
raw_struct
{
struct
raw_struct
{
string
str
;
string
str
;
...
@@ -170,7 +174,7 @@ int main() {
...
@@ -170,7 +174,7 @@ int main() {
raw_struct
rs2
;
raw_struct
rs2
;
uniform_typeid
<
raw_struct
>
()
->
deserialize
(
&
rs2
,
&
bd
);
uniform_typeid
<
raw_struct
>
()
->
deserialize
(
&
rs2
,
&
bd
);
CPPA_CHECK_EQUAL
(
rs
.
str
,
rs2
.
str
);
CPPA_CHECK_EQUAL
(
rs
.
str
,
rs2
.
str
);
auto
rsstr
=
to_string
(
object
::
from
(
rs
));
auto
rsstr
=
cppa
::
to_string
(
object
::
from
(
rs
));
rs2
.
str
=
"foobar"
;
rs2
.
str
=
"foobar"
;
cout
<<
"rs as string: "
<<
rsstr
<<
endl
;
cout
<<
"rs as string: "
<<
rsstr
<<
endl
;
rs2
=
from_string
<
raw_struct
>
(
rsstr
);
rs2
=
from_string
<
raw_struct
>
(
rsstr
);
...
@@ -266,7 +270,7 @@ int main() {
...
@@ -266,7 +270,7 @@ int main() {
if
(
meta_int
)
{
if
(
meta_int
)
{
auto
o
=
meta_int
->
create
();
auto
o
=
meta_int
->
create
();
get_ref
<
uint32_t
>
(
o
)
=
42
;
get_ref
<
uint32_t
>
(
o
)
=
42
;
auto
str
=
cppa
::
to_string
(
object
::
from
(
get
<
uint32_t
>
(
o
)));
auto
str
=
to_string
(
object
::
from
(
get
<
uint32_t
>
(
o
)));
CPPA_CHECK_EQUAL
(
"@u32 ( 42 )"
,
str
);
CPPA_CHECK_EQUAL
(
"@u32 ( 42 )"
,
str
);
}
}
}
}
...
@@ -285,7 +289,7 @@ int main() {
...
@@ -285,7 +289,7 @@ int main() {
auto
b1str
=
"struct_b ( struct_a ( 1, 2 ), 3, "
auto
b1str
=
"struct_b ( struct_a ( 1, 2 ), 3, "
"{ 4, 5, 6, 7, 8, 9, 10 } )"
;
"{ 4, 5, 6, 7, 8, 9, 10 } )"
;
// verify
// verify
CPPA_CHECK_EQUAL
((
to_string
(
object
::
from
(
b1
)
)),
b1str
);
{
CPPA_CHECK_EQUAL
((
to_string
(
b1
)),
b1str
);
{
// serialize b1 to buf
// serialize b1 to buf
util
::
buffer
wr_buf
;
util
::
buffer
wr_buf
;
binary_serializer
bs
(
&
wr_buf
);
binary_serializer
bs
(
&
wr_buf
);
...
@@ -299,7 +303,7 @@ int main() {
...
@@ -299,7 +303,7 @@ int main() {
}
}
// verify result of serialization / deserialization
// verify result of serialization / deserialization
CPPA_CHECK
(
b1
==
b2
);
CPPA_CHECK
(
b1
==
b2
);
CPPA_CHECK_EQUAL
(
to_string
(
object
::
from
(
b2
)
),
b1str
);
CPPA_CHECK_EQUAL
(
to_string
(
b2
),
b1str
);
{
// deserialize b3 from string
{
// deserialize b3 from string
object
res
=
from_string
(
b1str
);
object
res
=
from_string
(
b1str
);
CPPA_CHECK_EQUAL
(
res
.
type
()
->
name
(),
"struct_b"
);
CPPA_CHECK_EQUAL
(
res
.
type
()
->
name
(),
"struct_b"
);
...
...
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