Browse files

implemented read_raw & write_raw

  • Loading branch information...
1 parent 89316ed commit 620c42b517688ffd37b5bf6489b04755d8d16ff0 @Neverlord Neverlord committed Sep 6, 2012
Showing with 86 additions and 61 deletions.
  1. +86 −61 src/string_serialization.cpp
View
147 src/string_serialization.cpp
@@ -29,7 +29,9 @@
#include <stack>
+#include <cctype>
#include <sstream>
+#include <iomanip>
#include <algorithm>
#include "cppa/atom.hpp"
@@ -41,26 +43,28 @@
#include "cppa/primitive_variant.hpp"
#include "cppa/uniform_type_info.hpp"
+using namespace std;
+
namespace cppa {
namespace {
class string_serializer : public serializer {
- std::ostream& out;
+ ostream& out;
struct pt_writer {
- std::ostream& out;
+ ostream& out;
- pt_writer(std::ostream& mout) : out(mout) { }
+ pt_writer(ostream& mout) : out(mout) { }
template<typename T>
void operator()(const T& value) {
out << value;
}
- void operator()(const std::string& str) {
+ void operator()(const string& str) {
out << "\"";// << str << "\"";
for (char c : str) {
if (c == '"') out << "\\\"";
@@ -69,15 +73,15 @@ class string_serializer : public serializer {
out << '"';
}
- void operator()(const std::u16string&) { }
+ void operator()(const u16string&) { }
- void operator()(const std::u32string&) { }
+ void operator()(const u32string&) { }
};
bool m_after_value;
bool m_obj_just_opened;
- std::stack<std::string> m_open_objects;
+ stack<string> m_open_objects;
inline void clear() {
if (m_after_value) {
@@ -92,11 +96,11 @@ class string_serializer : public serializer {
public:
- string_serializer(std::ostream& mout)
+ string_serializer(ostream& mout)
: out(mout), m_after_value(false), m_obj_just_opened(false) {
}
- void begin_object(const std::string& type_name) {
+ void begin_object(const string& type_name) {
clear();
m_open_objects.push(type_name);
out << type_name;// << " ( ";
@@ -129,14 +133,14 @@ class string_serializer : public serializer {
void write_value(const primitive_variant& value) {
clear();
if (m_open_objects.empty()) {
- throw std::runtime_error("write_value(): m_open_objects.empty()");
+ throw runtime_error("write_value(): m_open_objects.empty()");
}
if (m_open_objects.top() == "@atom") {
if (value.ptype() != pt_uint64) {
- throw std::runtime_error("expected uint64 value after @atom");
+ throw runtime_error("expected uint64 value after @atom");
}
// write atoms as strings instead of integer values
- auto av = static_cast<atom_value>(get<std::uint64_t>(value));
+ auto av = static_cast<atom_value>(get<uint64_t>(value));
(pt_writer(out))(to_string(av));
}
else {
@@ -155,33 +159,39 @@ class string_serializer : public serializer {
out << (m_after_value ? " }" : "}");
}
- void write_raw(size_t, const void*) {
- throw std::runtime_error("string_serializer::write_raw: "
- "not implemented yet");
+ void write_raw(size_t num_bytes, const void* buf) {
+ clear();
+ auto first = reinterpret_cast<const unsigned char*>(buf);
+ auto last = first + num_bytes;
+ out << hex;
+ out << setfill('0');
+ copy(first, last, ostream_iterator<size_t>(out));
+ out << dec;
+ m_after_value = true;
}
};
class string_deserializer : public deserializer {
- std::string m_str;
- std::string::iterator m_pos;
+ string m_str;
+ string::iterator m_pos;
//size_t m_obj_count;
- std::stack<bool> m_obj_had_left_parenthesis;
- std::stack<std::string> m_open_objects;
+ stack<bool> m_obj_had_left_parenthesis;
+ stack<string> m_open_objects;
void skip_space_and_comma() {
while (*m_pos == ' ' || *m_pos == ',') ++m_pos;
}
- void throw_malformed(const std::string& error_msg) {
- throw std::logic_error("malformed string: " + error_msg);
+ void throw_malformed(const string& error_msg) {
+ throw logic_error("malformed string: " + error_msg);
}
void consume(char c) {
skip_space_and_comma();
if (*m_pos != c) {
- std::string error;
+ string error;
error += "expected '";
error += c;
error += "' found '";
@@ -205,8 +215,8 @@ class string_deserializer : public deserializer {
return false;
}
- inline std::string::iterator next_delimiter() {
- return std::find_if(m_pos, m_str.end(), [] (char c) -> bool {
+ inline string::iterator next_delimiter() {
+ return find_if(m_pos, m_str.end(), [] (char c) -> bool {
switch (c) {
case '(':
case ')':
@@ -235,33 +245,33 @@ class string_deserializer : public deserializer {
public:
- string_deserializer(const std::string& str) : m_str(str) {
+ string_deserializer(const string& str) : m_str(str) {
m_pos = m_str.begin();
}
- string_deserializer(std::string&& str) : m_str(std::move(str)) {
+ string_deserializer(string&& str) : m_str(move(str)) {
m_pos = m_str.begin();
}
- std::string seek_object() {
+ string seek_object() {
skip_space_and_comma();
auto substr_end = next_delimiter();
if (m_pos == substr_end) {
throw_malformed("could not seek object type name");
}
- std::string result(m_pos, substr_end);
+ string result(m_pos, substr_end);
m_pos = substr_end;
return result;
}
- std::string peek_object() {
- std::string result = seek_object();
+ string peek_object() {
+ string result = seek_object();
// restore position in stream
m_pos -= result.size();
return result;
}
- void begin_object(const std::string& type_name) {
+ void begin_object(const string& type_name) {
m_open_objects.push(type_name);
//++m_obj_count;
skip_space_and_comma();
@@ -280,7 +290,7 @@ class string_deserializer : public deserializer {
m_obj_had_left_parenthesis.pop();
}
if (m_open_objects.empty()) {
- throw std::runtime_error("no object to end");
+ throw runtime_error("no object to end");
}
m_open_objects.pop();
if (m_open_objects.empty()) {
@@ -294,7 +304,7 @@ class string_deserializer : public deserializer {
size_t begin_sequence() {
integrity_check();
consume('{');
- return std::count(m_pos, std::find(m_pos, m_str.end(), '}'), ',') + 1;
+ return count(m_pos, find(m_pos, m_str.end(), '}'), ',') + 1;
}
void end_sequence() {
@@ -303,18 +313,18 @@ class string_deserializer : public deserializer {
}
struct from_string {
- const std::string& str;
- from_string(const std::string& s) : str(s) { }
+ const string& str;
+ from_string(const string& s) : str(s) { }
template<typename T>
void operator()(T& what) {
- std::istringstream s(str);
+ istringstream s(str);
s >> what;
}
- void operator()(std::string& what) {
+ void operator()(string& what) {
what = str;
}
- void operator()(std::u16string&) { }
- void operator()(std::u32string&) { }
+ void operator()(u16string&) { }
+ void operator()(u32string&) { }
};
primitive_variant read_value(primitive_type ptype) {
@@ -323,14 +333,14 @@ class string_deserializer : public deserializer {
if (ptype != pt_uint64) {
throw_malformed("expected read of pt_uint64 after @atom");
}
- auto str_val = get<std::string>(read_value(pt_u8string));
+ auto str_val = get<string>(read_value(pt_u8string));
if (str_val.size() > 10) {
throw_malformed("atom string size > 10");
}
return detail::atom_val(str_val.c_str());
}
skip_space_and_comma();
- std::string::iterator substr_end;
+ string::iterator substr_end;
auto find_if_cond = [] (char c) -> bool {
switch (c) {
case ')':
@@ -352,28 +362,28 @@ class string_deserializer : public deserializer {
last_char = c;
return false;
};
- substr_end = std::find_if(m_pos, m_str.end(), find_if_str_cond);
+ substr_end = find_if(m_pos, m_str.end(), find_if_str_cond);
}
else {
- substr_end = std::find_if(m_pos, m_str.end(), find_if_cond);
+ substr_end = find_if(m_pos, m_str.end(), find_if_cond);
}
}
else {
- substr_end = std::find_if(m_pos, m_str.end(), find_if_cond);
+ substr_end = find_if(m_pos, m_str.end(), find_if_cond);
}
if (substr_end == m_str.end()) {
- throw std::logic_error("malformed string (unterminated value)");
+ throw logic_error("malformed string (unterminated value)");
}
- std::string substr(m_pos, substr_end);
+ string substr(m_pos, substr_end);
m_pos += substr.size();
if (ptype == pt_u8string) {
// skip trailing "
if (*m_pos != '"') {
- std::string error_msg;
+ string error_msg;
error_msg = "malformed string, expected '\"' found '";
error_msg += *m_pos;
error_msg += "'";
- throw std::logic_error(error_msg);
+ throw logic_error(error_msg);
}
++m_pos;
// replace '\"' by '"'
@@ -385,12 +395,12 @@ class string_deserializer : public deserializer {
last_char = c;
return false;
};
- std::string tmp;
+ string tmp;
auto sbegin = substr.begin();
auto send = substr.end();
- for (auto i = std::find_if(sbegin, send, cond);
+ for (auto i = find_if(sbegin, send, cond);
i != send;
- i = std::find_if(i, send, cond)) {
+ i = find_if(i, send, cond)) {
--i;
tmp.append(sbegin, i);
tmp += '"';
@@ -401,7 +411,7 @@ class string_deserializer : public deserializer {
tmp.append(sbegin, send);
}
if (!tmp.empty()) {
- substr = std::move(tmp);
+ substr = move(tmp);
}
}
primitive_variant result(ptype);
@@ -416,35 +426,50 @@ class string_deserializer : public deserializer {
consume('{');
const primitive_type* end = begin + size;
for ( ; begin != end; ++begin) {
- *storage = std::move(read_value(*begin));
+ *storage = move(read_value(*begin));
++storage;
}
consume('}');
}
- void read_raw(size_t, void*) {
- throw std::runtime_error("string_deserializer::read_raw: "
- "not implemented yet");
+ void read_raw(size_t buf_size, void* vbuf) {
+ auto buf = reinterpret_cast<unsigned char*>(vbuf);
+ integrity_check();
+ skip_space_and_comma();
+ auto next_nibble = [&]() -> size_t {
+ if (*m_pos == '\0') {
+ throw_malformed("unexpected end-of-string");
+ }
+ char c = *m_pos++;
+ if (!isxdigit(c)) {
+ throw_malformed("unexpected character, expected [0-9a-f]");
+ }
+ return static_cast<size_t>(isdigit(c) ? c - '0' : (c - 'a' + 10));
+ };
+ for (size_t i = 0; i < buf_size; ++i) {
+ auto nibble = next_nibble();
+ *buf++ = static_cast<unsigned char>((nibble << 4) | next_nibble());
+ }
}
};
} // namespace <anonymous>
-object from_string(const std::string& what) {
+object from_string(const string& what) {
string_deserializer strd(what);
- std::string uname = strd.peek_object();
+ string uname = strd.peek_object();
auto utype = uniform_type_info::from(uname);
if (utype == nullptr) {
- throw std::logic_error(uname + " is not announced");
+ throw logic_error(uname + " is not announced");
}
return utype->deserialize(&strd);
}
namespace detail {
-std::string to_string_impl(const void *what, const uniform_type_info *utype) {
- std::ostringstream osstr;
+string to_string_impl(const void *what, const uniform_type_info *utype) {
+ ostringstream osstr;
string_serializer strs(osstr);
utype->serialize(what, &strs);
return osstr.str();

0 comments on commit 620c42b

Please sign in to comment.