#include "tpl_encoder.h"
namespace parser {
namespace internal {
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::parse_version
/////////////////////////////////////////////////////////////////////////////////////////
std::string::size_type
tpl_encoder_helper::parse_version(model_version & version, unsigned int & last_key, std::string const& buffer, std::string::size_type ipos)const
{
// format: V{model x, 1}
ipos = ipos + 2; // "V{".length()
std::string::size_type epos = buffer.find(',', ipos);
if(epos==std::string::npos || epos==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Invalid version section, version name is missing");
// get the encoder model name and version
version.name = buffer.substr(ipos, epos-ipos);
boost::trim(version.name);
ipos = epos+1;
epos = buffer.find(',', ipos);
if(epos==std::string::npos || epos==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Invalid version section; ',' is missing or section is empty");
version.version = boost::lexical_cast<unsigned int>(buffer.substr(ipos, epos-ipos));
ipos = epos+1;
epos = buffer.find(',', ipos);
if(epos==std::string::npos || epos==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Invalid next_key; ',' is missing or section is empty");
version.next_key = boost::lexical_cast<unsigned int>(buffer.substr(ipos, epos-ipos));
ipos = epos+1;
epos = buffer.find('}', ipos);
if(epos==std::string::npos || epos==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Invalid resource base::last_key section; '}' is missing or section is empty");
last_key = boost::lexical_cast<unsigned int>(buffer.substr(ipos, epos-ipos));
return epos+1;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::encode_version
/////////////////////////////////////////////////////////////////////////////////////////
void
tpl_encoder_helper::encode_version(model_version const& version, std::stringstream & sbuf, unsigned int last_key)const
{
sbuf << "V{"
<< version.name << ","
<< version.version << ","
<< version.next_key << ","
<< last_key << "}" << std::endl;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::get_index
/////////////////////////////////////////////////////////////////////////////////////////
rdf::index_type
tpl_encoder_helper::get_index(std::string const& key) const
{
rdf::index_type index = NULL;
if(m_has_model) index = m_model_p->get_helper_ptr()->get_index(key);
if(index) return index;
key_index_map_t::const_iterator itor = m_key_index_map.find(key);
if(itor == m_key_index_map.end()) return NULL;
return itor->second;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::get_str
/////////////////////////////////////////////////////////////////////////////////////////
std::string
tpl_encoder_helper::get_str(std::string const& key) const
{
std::string str = "";
if(m_has_model) str = m_model_p->get_helper_ptr()->get_str(key);
if(str.size() > 0) return str;
str_pool_map_t::const_iterator itor = m_key_str_map.find(key);
if(itor == m_key_str_map.end()) return str;
return itor->second;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::get_key_for
/////////////////////////////////////////////////////////////////////////////////////////
std::string const&
tpl_encoder_helper::get_key_for(std::string const& str)
{
if(m_has_model) {
str_pool_map_t::const_iterator itor = m_model_p->get_helper_ptr()->m_str_key_map.find(str);
if(itor != m_model_p->get_helper_ptr()->m_str_key_map.end()) return itor->second;
}
str_pool_map_t::iterator itor = m_str_key_map.find(str);
if(itor == m_str_key_map.end()) {
std::string key;
if(m_has_model) key = "U";
else key = "S";
key = key + boost::lexical_cast<std::string>(++m_next_key);
m_key_str_map.insert(std::make_pair(key, str));
itor = m_str_key_map.insert(std::make_pair(str, key)).first;
}
return itor->second;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::get_key_for
/////////////////////////////////////////////////////////////////////////////////////////
std::string const&
tpl_encoder_helper::get_key_for(rdf::index_type index)
{
if(m_has_model) {
index_key_map_t::const_iterator itor = m_model_p->get_helper_ptr()->m_index_key_map.find(index);
if(itor != m_model_p->get_helper_ptr()->m_index_key_map.end()) return itor->second;
}
index_key_map_t::iterator itor = m_index_key_map.find(index);
if(itor == m_index_key_map.end()) {
std::string key;
if(m_has_model) key = "W";
else key = "R";
key = key + boost::lexical_cast<std::string>(++m_next_key);
itor = m_index_key_map.insert(std::make_pair(index, key)).first;
m_key_index_map.insert(std::make_pair(key, index));
}
return itor->second;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::encode_resource
//
// Encode the index argument and returns the encoded key.
// Add the (key, encoded-resource) pair into m_key_encoded_index_map
/////////////////////////////////////////////////////////////////////////////////////////
std::string const&
tpl_encoder_helper::encode_resource(rdf::index_type index)
{
std::string const& key = get_key_for(index);
if(m_has_model) {
str_pool_map_t::const_iterator itor = m_model_p->get_helper_ptr()->m_key_encoded_index_map.find(key);
if(itor != m_model_p->get_helper_ptr()->m_key_encoded_index_map.end()) return key;
}
str_pool_map_t::iterator itor = m_key_encoded_index_map.find(key);
if(itor != m_key_encoded_index_map.end()) return key;
std::stringstream sbuf(std::stringstream::out);
// resource name
std::string encoded_name;
std::string const& name = index->get_name();
if(index->has_local_name()) {
encoded_name = "*";
} else {
std::string::size_type ipos = name.find('#');
if(ipos==std::string::npos) {
encoded_name = get_key_for(name);
} else if(ipos==0) {
encoded_name = name;
} else {
encoded_name = get_key_for(name.substr(0, ipos)) + name.substr(ipos);
}
}
sbuf << key << ":";
if(index->is_literal()) {
rdf::literal const& l = m_graph_p->get_literal(index);
// literal type
switch(l.get_type()) {
case rdf::unset:
sbuf << "LV:" << encoded_name << ":"<< l.get_key() << ":;";
break;
case rdf::integer:
sbuf << "LI:" << encoded_name << ":"<< l.get_key() << ":"<< l.get_int() << ";";
break;
case rdf::unsigned_integer:
sbuf << "LU:" << encoded_name << ":"<< l.get_key() << ":"<< l.get_uint() << ";";
break;
case rdf::real:
sbuf << "LR:" << encoded_name << ":"<< l.get_key() << ":"<< l.get_real() << ";";
break;
case rdf::date:
sbuf << "LD:" << encoded_name << ":"<< l.get_key() << ":"<< l.get_date().d << ";";
break;
case rdf::time:
sbuf << "LT:" << encoded_name << ":"<< l.get_key() << ":"<< l.get_time().d << ";";
break;
case rdf::duration:
sbuf << "LN:" << encoded_name << ":"<< l.get_key() << ":"<< l.get_duration().d << ";";
break;
default:
sbuf << "LS:" << encoded_name << ":"<< l.get_key() << ":"<< get_key_for(l.get_string()) << ";";
}
} else {
sbuf << "R:" << encoded_name << ":"<< index->get_key() << ":;";
}
std::string encoded_index = sbuf.str();
m_key_encoded_index_map.insert(std::make_pair(key, encoded_index));
return key;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::create_index
//
// Create or retrieve existing index matching argument
/////////////////////////////////////////////////////////////////////////////////////////
rdf::index_type
tpl_encoder_helper::create_index(unsigned int rb_key, std::string const& encoded_name, std::string const& type, std::string const& content)
{
// decode the name
std::string name = "*";
if(encoded_name != "*") {
std::string::size_type ipos = encoded_name.find('#');
if(ipos==std::string::npos) {
name = get_str(encoded_name);
} else if(ipos==0) {
name = encoded_name;
} else {
name = get_str(encoded_name.substr(0, ipos)) + encoded_name.substr(ipos);
}
}
if(name.size() == 0) throw rdf::rdf_exception(rdf::parsing_error, "tpl_encoder_helper::create_index: Error decoding encoded_name: "+encoded_name);
rdf::internal::resource_base_map_ptr_type rbase_p = m_graph_p->get_resource_map_ptr();
if(type == "R") {
if(name == "*") return rbase_p->create_bnode_as_index(rb_key);
return rbase_p->create_resource_as_index(rb_key, name);
}
if(type == "LS") {
std::string data = get_str(content);
if(name == "*") return rbase_p->create_string_literal_as_index(rb_key, data);
return rbase_p->create_string_literal_as_index(rb_key, name, data);
}
if(type == "LI") {
int data = boost::lexical_cast<int>(content);
if(name == "*") return rbase_p->create_int_literal_as_index(rb_key, data);
return rbase_p->create_int_literal_as_index(rb_key, name, data);
}
if(type == "LU") {
unsigned int data = boost::lexical_cast<unsigned int>(content);
if(name == "*") return rbase_p->create_uint_literal_as_index(rb_key, data);
return rbase_p->create_uint_literal_as_index(rb_key, name, data);
}
if(type == "LR") {
float data = boost::lexical_cast<float>(content);
if(name == "*") return rbase_p->create_real_literal_as_index(rb_key, data);
return rbase_p->create_real_literal_as_index(rb_key, name, data);
}
if(type == "LD") {
rdf::date_type data;
data.d = boost::lexical_cast<unsigned int>(content);
if(name == "*") return rbase_p->create_date_literal_as_index(rb_key, data);
return rbase_p->create_date_literal_as_index(rb_key, name, data);
}
if(type == "LT") {
rdf::time_type data;
data.d = boost::lexical_cast<unsigned int>(content);
if(name == "*") return rbase_p->create_time_literal_as_index(rb_key, data);
return rbase_p->create_time_literal_as_index(rb_key, name, data);
}
if(type == "LN") {
rdf::duration_type data;
data.d = boost::lexical_cast<unsigned int>(content);
if(name == "*") return rbase_p->create_duration_literal_as_index(rb_key, data);
return rbase_p->create_duration_literal_as_index(rb_key, name, data);
}
if(type == "LV") {
rdf::internal::no_value data;
return rbase_p->create_nv_literal_as_index(rb_key, name, data);
}
throw rdf::rdf_exception(rdf::parsing_error, "tpl_encoder_helper::create_index: Unknown type: "+type);
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::parse_string_pool
//
// format: SP{<key>:<length>:<string>;}
// key starting w/ S are from model pool;
// key starting w/ U are from session pool;
// example: SP{S1:8:string 1;S2:8:string 2;S3:8:http://S;}
/////////////////////////////////////////////////////////////////////////////////////////
std::string::size_type
tpl_encoder_helper::parse_string_pool(std::string const& buffer, std::string::size_type ipos)
{
std::string::size_type lbuf = buffer.length();
ipos = ipos + 3; // "SP{".length()
while(true) {
if(ipos > lbuf) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_string_pool: Past end of buffer");
if(buffer[ipos] == '}') return ipos;
std::string::size_type m1 = buffer.find(':', ipos);
if(m1==std::string::npos || m1==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_string_pool: Expecting ':' to mark end of string key; ':' is missing");
std::string key = buffer.substr(ipos, m1-ipos);
std::string::size_type m2 = buffer.find(':', m1+1);
if(m2 == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_string_pool: Expecting ':' to mark end of string length; ':' is missing");
int l = boost::lexical_cast<int>(buffer.substr(m1+1, m2-m1-1));
std::string str = buffer.substr(m2+1, l);
ipos = m2+1+l;
if(buffer[ipos] != ';') throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_string_pool: Expecting ';' at end of encoded string");
ipos++;
// save the parsed key, string pair
m_key_str_map.insert(std::make_pair(key, str));
m_str_key_map.insert(std::make_pair(str, key));
}
throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, unreachable code!");
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::encode_string_pool
/////////////////////////////////////////////////////////////////////////////////////////
void
tpl_encoder_helper::encode_string_pool(std::stringstream & sbuf)
{
sbuf << "SP{";
str_pool_map_t::const_iterator itor = m_key_str_map.begin();
str_pool_map_t::const_iterator end = m_key_str_map.end();
for(;itor != end; ++itor) {
std::string const& skey = itor->first;
std::string const& str = itor->second;
sbuf << skey << ":" << str.size() << ":" << str << ";";
}
sbuf << "}" << std::endl;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::parse_resource_pool
//
// format: RP{<key>:<type>:<name>:<resource_base::key>:<content>;}
// key starting w/ R are from model pool;
// key starting w/ W are from session pool;
// types:
// 'R' for resources, <content> is empty;
// 'LS' for literal string, <content> is string pool key for data;
// 'LI' for literal int, <content> is literal data (int);
// 'LU' for literal unsigned int, <content> is literal data (unsigned int);
// 'LR' for real, <content> is literal data (float);
// 'LD' for date, <content> is literal data (unsigned int);
// 'LT' for time, <content> is literal data (unsigned int);
// 'LN' for duration, <content> is literal data (unsigned int);
// 'LV' for 'no_value' literal, <content> is empty;
// If name starts with '*' then it is a blank node and name is ignored.
// If name contains '#', then the base (left portion) is a string pool key
// else name is a string pool key
/////////////////////////////////////////////////////////////////////////////////////////
std::string::size_type
tpl_encoder_helper::parse_resource_pool(std::string const& buffer, std::string::size_type ipos)
{
std::string::size_type lbuf = buffer.length();
ipos = ipos + 3; // "RP{".length()
while(true) {
if(ipos > lbuf) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_resource_pool: Past end of buffer");
if(buffer[ipos] == '}') return ipos;
// resource key
std::string::size_type m1 = buffer.find(':', ipos);
if(m1==std::string::npos || m1==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_resource_pool: Expecting ':' to mark end of string key; ':' is missing");
std::string key = buffer.substr(ipos, m1-ipos);
m1++;
// resource type
std::string::size_type m2 = buffer.find(':', m1);
if(m2==std::string::npos || m2==m1) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_resource_pool: Expecting ':' to mark end of resource type; ':' is missing");
std::string type = buffer.substr(m1, m2-m1);
m2++;
// resource name
std::string::size_type m3 = buffer.find(':', m2);
if(m3==std::string::npos || m3==m2) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_resource_pool: Expecting ':' to mark end of resource name; ':' is missing");
std::string name = buffer.substr(m2, m3-m2);
m3++;
// resource rb_key
std::string::size_type m4 = buffer.find(':', m3);
if(m4==std::string::npos || m4==m3) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_resource_pool: Expecting ':' to mark end of resource_base::key; ':' is missing");
unsigned int rbkey = boost::lexical_cast<unsigned int>(buffer.substr(m3, m4-m3));
m4++;
std::string content = "";
std::string::size_type m5 = m4;
if(buffer[m5] != ';') {
m5 = buffer.find(';', m4);
if(m5 == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_resource_pool: Expecting ':' to mark end of resource name; ':' is missing");
content = buffer.substr(m4, m5-m4);
}
if(buffer[m5] != ';') throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_resource_pool: Expecting ';' at end of encoded string");
ipos = m5 + 1;
// save the resource
rdf::index_type index = create_index(rbkey, name, type, content);
m_key_index_map.insert(std::make_pair(key, index));
m_index_key_map.insert(std::make_pair(index, key));
if(m_verbose) std::cout << "tpl_encoder_helper::parse_resource_pool: " << key << " <--> " << (*index) << std::endl;
}
throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, unreachable code!");
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::encode_resource_pool
/////////////////////////////////////////////////////////////////////////////////////////
void
tpl_encoder_helper::encode_resource_pool(std::stringstream & sbuf)
{
sbuf << "RP{";
str_pool_map_t::const_iterator itor = m_key_encoded_index_map.begin();
str_pool_map_t::const_iterator end = m_key_encoded_index_map.end();
for(;itor != end; ++itor) {
sbuf << itor->second;
}
sbuf << "}" << std::endl;
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::parse_triples
//
// format: TPL{<subject key>:<predicate key>,<object key>:[<predicate key>,<object key>];}
// TPL{R1:R2,R3:R2,R4:;R3:R2,R5:R2,R6:;}
/////////////////////////////////////////////////////////////////////////////////////////
std::string::size_type
tpl_encoder_helper::parse_triples(rdf::rdf_graph_ptr_type & graph_p, std::string const& buffer, std::string::size_type ipos)
{
std::string::size_type lbuf = buffer.length();
ipos = ipos + 4; // "TPL{".length()
while(true) {
if(ipos > lbuf) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_triple_pool: Past end of buffer");
if(buffer[ipos] == '}') return ipos;
// subject key
std::string::size_type m1 = buffer.find(':', ipos);
if(m1==std::string::npos || m1==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_triple_pool: Expecting ':' to mark end of subject key; ':' is missing");
std::string skey = buffer.substr(ipos, m1-ipos);
ipos = m1 + 1;
// all (predicate, object) pairs
bool hasmore = true;
while(hasmore) {
// predicate key
std::string::size_type m2 = buffer.find(',', ipos);
if(m2==std::string::npos || m2==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_triple_pool: Expecting ':' to mark end of predicate key; ':' is missing");
std::string pkey = buffer.substr(ipos, m2-ipos);
++m2;
// object key
std::string::size_type m3 = buffer.find(':', m2);
if(m3==std::string::npos || m3==ipos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_helper::parse_triple_pool: Expecting ':' to mark end of object key; ':' is missing");
std::string okey = buffer.substr(m2, m3-m2);
ipos = m3 + 1;
if(buffer[ipos] == ';') {
hasmore = false;
++ipos;
}
// insert the triple into the graph
if(m_verbose) std::cout << "tpl_encoder_helper::parse_triples: triple(" << skey << ", " << pkey << ", " << okey << ") found" << std::endl;
rdf::index_type s = get_index(skey);
rdf::index_type p = get_index(pkey);
rdf::index_type o = get_index(okey);
graph_p->insert(s, p, o);
}
}
throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, unreachable code!");
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_helper::encode_triples
/////////////////////////////////////////////////////////////////////////////////////////
void
tpl_encoder_helper::encode_triples(std::stringstream & sbuf, spo_map_t const& spo_map)
{
sbuf << "TPL{";
spo_map_t::const_iterator spo_itor = spo_map.begin();
spo_map_t::const_iterator spo_end = spo_map.end();
for(;spo_itor != spo_end; ++spo_itor) {
std::string const& skey = spo_itor->first;
po_map_t const& po_map = spo_itor->second;
sbuf << skey << ":";
po_map_t::const_iterator po_itor = po_map.begin();
po_map_t::const_iterator po_end = po_map.end();
for(;po_itor != po_end; ++po_itor) {
std::string const& pkey = po_itor->first;
std::string const& okey = po_itor->second;
sbuf << pkey << "," << okey << ":";
}
sbuf << ";";
}
sbuf << "}" << std::endl;
};
}; /* internal namespace */
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder::decode
//
/////////////////////////////////////////////////////////////////////////////////////////
void
tpl_encoder::decode(std::string const& buffer)
{
// parse the version name and number
internal::model_version version;
unsigned int last_key;
std::string::size_type ipos = buffer.find("V{");
if(ipos == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: missing 'V{' (parser version name and number section is missing)");
ipos = m_helper_p->parse_version(version, last_key, buffer, ipos);
if(m_verbose) std::cout << "tpl_encoder::decode model_name and version is " << version.name << ", " << version.version << std::endl;
if(!m_tpl_encoder_model_p) {
throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Invalid encoder model, requiring model name: "+ version.name);
}
if(m_tpl_encoder_model_p->get_version().name != version.name || m_tpl_encoder_model_p->get_version().version < version.version) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Invalid version, version name or number not supported by model");
// set next key
m_helper_p->set_next_key(version.next_key);
m_graph_p->get_resource_map_ptr()->set_next_key(last_key);
// parse the string pool
ipos = buffer.find("SP{", ipos);
if(ipos == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Expecting 'SP{', string pool section is missing");
ipos = m_helper_p->parse_string_pool(buffer, ipos);
// parse the resource pool
ipos = buffer.find("RP{", ipos);
if(ipos == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Expecting 'RP{', resource pool section is missing");
ipos = m_helper_p->parse_resource_pool(buffer, ipos);
// parse the triples
ipos = buffer.find("TPL{", ipos);
if(ipos == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::decode: Expecting 'TPL{', triples section is missing");
ipos = m_helper_p->parse_triples(m_graph_p, buffer, ipos);
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder::encode
//
/////////////////////////////////////////////////////////////////////////////////////////
std::string
tpl_encoder::encode()
{
// visit all triples, collect the encoded keys
internal::spo_map_t triples;
rdf::rdf_graph::index_iterator itor = m_graph_p->find_index();
while(!itor.is_end()) {
rdf::index_triple t3 = itor.get_triple();
// get s, p, o keys
std::string skey = m_helper_p->encode_resource(t3.get_subject());
std::string pkey = m_helper_p->encode_resource(t3.get_predicate());
std::string okey = m_helper_p->encode_resource(t3.get_object());
add_triple(triples, skey, pkey, okey);
itor.next();
}
std::stringstream sbuf(std::stringstream::out);
// encode the model version used and the string and resource pools
if(!m_tpl_encoder_model_p) {
throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder::encode: Invalid encoder model, cannot be null!");
}
internal::model_version version;
version.name = m_tpl_encoder_model_p->get_version().name;
version.version = m_tpl_encoder_model_p->get_version().version;
version.next_key = m_helper_p->get_last_key();
m_helper_p->encode_version(version, sbuf, m_graph_p->get_resource_map_ptr()->get_next_key());
m_helper_p->encode_string_pool(sbuf);
m_helper_p->encode_resource_pool(sbuf);
// encode the triples
m_helper_p->encode_triples(sbuf, triples);
if(m_verbose) {
std::cout << "tpl_encoder::encode >>" << std::endl << sbuf.str();
}
return sbuf.str();
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_model::decode
//
/////////////////////////////////////////////////////////////////////////////////////////
void
tpl_encoder_model::decode(std::string const& buffer)
{
// creating a new helper
m_helper_p = internal::tpl_encoder_helper_ptr_type(new internal::tpl_encoder_helper(m_graph_p, m_verbose));
// parse the version name and number
unsigned int last_key;
std::string::size_type ipos = buffer.find("V{");
if(ipos == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_model::decode: missing 'V{' (parser version name and number section is missing)");
ipos = m_helper_p->parse_version(m_model_version, last_key, buffer, ipos);
if(m_verbose) std::cout << "tpl_encoder::decode model_name and version is " << m_model_version.name << ", " << m_model_version.version << std::endl;
// set next key
m_helper_p->set_next_key(m_model_version.next_key);
m_graph_p->get_resource_map_ptr()->set_next_key(last_key);
// parse the string pool
ipos = buffer.find("SP{", ipos);
if(ipos == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_model::decode: Expecting 'SP{', string pool section is missing");
ipos = m_helper_p->parse_string_pool(buffer, ipos);
// parse the resource pool
ipos = buffer.find("RP{", ipos);
if(ipos == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_model::decode: Expecting 'RP{', resource pool section is missing");
ipos = m_helper_p->parse_resource_pool(buffer, ipos);
// parse the triples
ipos = buffer.find("TPL{", ipos);
if(ipos == std::string::npos) throw rdf::rdf_exception(rdf::parsing_error, "E_TPLE, tpl_encoder_model::decode: Expecting 'TPL{', triples section is missing");
ipos = m_helper_p->parse_triples(m_graph_p, buffer, ipos);
};
/////////////////////////////////////////////////////////////////////////////////////////
// tpl_encoder_model::encode
//
/////////////////////////////////////////////////////////////////////////////////////////
std::string
tpl_encoder_model::encode(rdf::rdf_graph_ptr_type & graph_p)
{
if(graph_p) {
m_graph_p = graph_p;
m_model_version.version++;
}
// visit all resources, collect the encoded keys
rdf::rdf_graph::resource_ptr_const_iterator r_itor = m_graph_p->get_resources_iterator_begin();
rdf::rdf_graph::resource_ptr_const_iterator r_end = m_graph_p->get_resources_iterator_end();
for(; r_itor!=r_end; ++r_itor) {
rdf::index_type index = (*r_itor)->get_index();
m_helper_p->encode_resource(index);
}
// visit all triples, collect the encoded keys
internal::spo_map_t triples;
rdf::rdf_graph::index_iterator itor = m_graph_p->find_index();
while(!itor.is_end()) {
rdf::index_triple t3 = itor.get_triple();
// get s, p, o keys
std::string skey = m_helper_p->encode_resource(t3.get_subject());
std::string pkey = m_helper_p->encode_resource(t3.get_predicate());
std::string okey = m_helper_p->encode_resource(t3.get_object());
add_triple(triples, skey, pkey, okey);
itor.next();
}
std::stringstream sbuf(std::stringstream::out);
// encode the model version used and the string and resource pools
m_model_version.next_key = m_helper_p->get_last_key();
m_helper_p->encode_version(m_model_version, sbuf, m_graph_p->get_resource_map_ptr()->get_next_key());
m_helper_p->encode_string_pool(sbuf);
m_helper_p->encode_resource_pool(sbuf);
// encode the triples
m_helper_p->encode_triples(sbuf, triples);
if(m_verbose) {
std::cout << "tpl_encoder_model::encode >>" << std::endl << sbuf.str();
}
return sbuf.str();
};
}; /* parser namespace */