Commit 2cfb52d8 authored by Dominik Charousset's avatar Dominik Charousset

Implement `from_string` for new UTI interface

Add a `from_string` implementation for the new API of `uniform_type_info`.
Also improve the string deserializer to correctly parse the serialized form of
a `node_id`, i.e., correctly handle the '@' sign that separates process and
host id.
parent db1e1c08
......@@ -34,7 +34,7 @@ namespace cppa {
* @returns An {@link cppa::object object} instance that contains
* the deserialized value.
*/
uniform_value from_string(const std::string& what);
uniform_value from_string_impl(const std::string& what);
/**
* @brief Convenience function that deserializes a value from @p what and
......@@ -42,23 +42,23 @@ uniform_value from_string(const std::string& what);
* @throws std::logic_error if the result is not of type @p T.
* @returns The deserialized value as instance of @p T.
*/
/*
template<typename T>
T from_string(const std::string& what) {
any o = from_string(what);
const std::type_info& tinfo = typeid(T);
if (tinfo == *(o.type())) {
return std::move(get_ref<T>(o));
optional<T> from_string(const std::string& what) {
auto uti = uniform_typeid<T>();
auto uv = from_string_impl(what);
if (!uv || (*uv->ti) != typeid(T)) {
// try again using the type name
std::string tmp = uti->name();
tmp += " ( ";
tmp += what;
tmp += " )";
uv = from_string_impl(tmp);
}
else {
std::string error_msg = "expected type name ";
error_msg += uniform_typeid(tinfo)->name();
error_msg += " found ";
error_msg += o.type()->name();
throw std::logic_error(error_msg);
if (uv && (*uv->ti) == typeid(T)) {
return T{std::move(*reinterpret_cast<T*>(uv->val))};
}
return none;
}
*/
} // namespace cppa
......
......@@ -299,7 +299,7 @@ class string_deserializer : public deserializer, public dummy_backend {
const uniform_type_info* begin_object() override {
skip_space_and_comma();
string type_name;
// shortcuts for builtin types
// shortcuts for built-in types
if (*m_pos == '"') {
type_name = "@str";
} else if (*m_pos == '\'') {
......@@ -315,11 +315,9 @@ class string_deserializer : public deserializer, public dummy_backend {
m_pos = substr_end;
}
m_open_objects.push(type_name);
//++m_obj_count;
skip_space_and_comma();
// suppress leading parenthesis for builtin types
// suppress leading parenthesis for built-in types
m_obj_had_left_parenthesis.push(try_consume('('));
// consume('(');
return detail::singletons::get_uniform_type_info_map()->by_uniform_name(
type_name);
}
......@@ -401,6 +399,7 @@ class string_deserializer : public deserializer, public dummy_backend {
case '}':
case ' ':
case ',':
case '@':
return true;
default:
return false;
......@@ -479,21 +478,33 @@ class string_deserializer : public deserializer, public dummy_backend {
}
void read_raw(size_t buf_size, void* vbuf) override {
if (buf_size == node_id::host_id_size
&& !m_open_objects.empty()
&& m_open_objects.top() == "@node") {
// node ids are formatted as process_id@host_id
// this read_raw reads the host_id, i.e., we need
// to skip the '@' character
consume('@');
}
auto buf = reinterpret_cast<unsigned char*>(vbuf);
integrity_check();
skip_space_and_comma();
auto next_nibble = [&]()->size_t {
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]");
std::string errmsg = "unexpected character: '";
errmsg += c;
errmsg += "', expected [0-9a-f]";
throw_malformed(errmsg);
}
return static_cast<size_t>(isdigit(c) ? c - '0' : (c - 'a' + 10));
};
for (size_t i = 0; i < buf_size; ++i) {
// one byte consists of two nibbles
auto nibble = next_nibble();
*buf++ = static_cast<unsigned char>((nibble << 4) | next_nibble());
}
......@@ -503,15 +514,6 @@ class string_deserializer : public deserializer, public dummy_backend {
} // namespace <anonymous>
uniform_value from_string(const string& what) {
string_deserializer strd(what);
auto utype = strd.begin_object();
auto result = utype->deserialize(&strd);
strd.end_object();
return result;
return {};
}
namespace detail {
string to_string_impl(const void* what, const uniform_type_info* utype) {
......@@ -535,4 +537,14 @@ ostream& operator<<(ostream& out, skip_message_t) {
return out << "skip_message";
}
uniform_value from_string_impl(const string& what) {
string_deserializer strd(what);
auto utype = strd.begin_object();
if (utype) {
return utype->deserialize(&strd);
}
strd.end_object();
return {};
}
} // namespace cppa
......@@ -141,6 +141,12 @@ int main() {
announce(typeid(raw_struct),
uniform_type_info_ptr{new raw_struct_type_info});
auto nid = detail::singletons::get_node_id();
auto nid_str = to_string(nid);
CPPA_PRINT("nid_str = " << nid_str);
auto nid2 = from_string<node_id>(nid_str);
CPPA_CHECK(nid2 && nid == *nid2);
/*
auto oarr = new detail::object_array;
oarr->push_back(object::from(static_cast<uint32_t>(42)));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment