Commit e35db299 authored by Tobias WEBER's avatar Tobias WEBER
Browse files

array deserialisation

parent 17e2dacc
......@@ -9,6 +9,7 @@
#define __IN20_ALGOS_H__
#include <algorithm>
#include <string>
/**
......@@ -29,4 +30,27 @@ void copy_interleave(T1 inIter, T1 inEnd, T2 outIter, std::size_t interleave, st
}
/**
* count number of ocurrences of a sub-string in a string
*/
static std::size_t count_occurrences(const std::string &str, const std::string &tok)
{
std::size_t num = 0;
std::size_t start = 0;
const std::size_t len_tok = tok.length();
while(true)
{
std::size_t idx = str.find(tok, start);
if(idx == std::string::npos)
break;
++num;
start += idx+len_tok;
}
return num;
}
#endif
......@@ -8,6 +8,7 @@
#include "cliparser.h"
#include "tools/in20/globals.h"
#include "funcs.h"
#include "libs/algos.h"
#include "tlibs/string/string.h"
#include <cmath>
......@@ -383,18 +384,22 @@ std::string SymbolString::serialise() const
*/
std::string SymbolList::serialise() const
{
static const std::string begin_arr = "###[";
static const std::string end_arr = "###]";
static const std::string arr_next_elem = "###,";
std::ostringstream ostr;
ostr.precision(std::numeric_limits<t_real>::digits10);
ostr << Symbol::get_type_name(*this) << ":" << "###[";
ostr << Symbol::get_type_name(*this) << ":" << begin_arr;
bool firstelem = true;
for(const auto &elem : m_val)
{
if(!firstelem) ostr << "###, ";
if(!firstelem) ostr << arr_next_elem;
ostr << elem->serialise();
firstelem = false;
}
ostr << "###]";
ostr << end_arr;
return ostr.str();
}
......@@ -431,9 +436,62 @@ std::shared_ptr<Symbol> Symbol::unserialise(const std::string &str)
}
else if(ty == "list" || ty == "array")
{
static const std::string begin_arr = "###[";
static const std::size_t len_begin_arr = begin_arr.length();
static const std::string end_arr = "###]";
static const std::string arr_next_elem = "###,";
// find array boundaries in string repr
std::size_t arr_begin = val.find(begin_arr);
std::size_t arr_end = val.rfind(end_arr);
if(arr_begin == std::string::npos || arr_end == std::string::npos)
{
print_err("Invalid array begin or end indicators: \"", val, "\".");
return nullptr;
}
arr_begin += len_begin_arr;
val = val.substr(arr_begin, arr_end-arr_begin);
std::vector<std::shared_ptr<Symbol>> vec;
// TODO
// unserialise vector elements
std::vector<std::string> toks;
tl::get_tokens_seq<std::string, std::string>(val, arr_next_elem, toks);
std::string accum_tok;
for(const auto &tok : toks)
{
// chain back together elements of nested sub-array
if(accum_tok == "")
accum_tok += tok;
else
accum_tok += arr_next_elem + tok;
// balance brackets of nested arrays
int nest_level = int(count_occurrences(accum_tok, begin_arr)) - int(count_occurrences(accum_tok, end_arr));
if(nest_level < 0)
{
print_err("Unbalanced brackets in serialised array representation: \"", accum_tok, "\"");
return nullptr;
}
else if(nest_level > 0) // get next token until end bracket is found
{
continue;
}
else if(nest_level == 0) // found matching brackets
{
auto elemsym = unserialise(accum_tok);
if(elemsym == nullptr)
{
print_err("Invalid array element: \"", accum_tok, "\".");
return nullptr;
}
vec.emplace_back(elemsym);
accum_tok = "";
}
}
return std::make_shared<SymbolList>(vec, ty=="list");
}
else if(ty == "dataset")
......
......@@ -256,6 +256,7 @@ bool WorkSpaceWidget::LoadWorkspace(const std::string &basename, const tl::Prop<
m_workspace.insert(std::make_pair(*key, sym));
}
UpdateList();
return true;
}
......
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