parent
f4b80c3ec9
commit
a9b50b6672
@ -0,0 +1,59 @@
|
||||
#include "graph.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
|
||||
// format: 1 line = 1 node
|
||||
// first line followed by it's neighbours.
|
||||
// separator is an empty new line
|
||||
// std::string vertexSerializer(const V& v) converts V into std::string
|
||||
// V vertexCreator(const std::string&s) converts std::string to V
|
||||
|
||||
template <typename V, typename F>
|
||||
Graph<V> readGraphFromPlainText(const std::string& filename, F vertexCreator)
|
||||
{
|
||||
std::ifstream file(filename);
|
||||
if (!file.good())
|
||||
throw std::runtime_error("Failed to open " + filename + " to read.");
|
||||
|
||||
Graph<V> g;
|
||||
std::string line;
|
||||
while (std::getline(file, line))
|
||||
if (!line.empty())
|
||||
break;
|
||||
|
||||
bool new_entry = true;
|
||||
V current_vertex;
|
||||
while (std::getline(file, line)) {
|
||||
if (line.empty()) {
|
||||
new_entry = true;
|
||||
} else {
|
||||
if (new_entry) {
|
||||
current_vertex = vertexCreator(line);
|
||||
g.addVertex(current_vertex);
|
||||
new_entry = false;
|
||||
} else {
|
||||
g.addEdge(current_vertex, vertexCreator(line));
|
||||
}
|
||||
}
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
template <typename V, typename F>
|
||||
void writeGraphToPlainText(const Graph<V>& g, const std::string& filename, F vertexSerializer)
|
||||
{
|
||||
std::ofstream file;
|
||||
file.open (filename);
|
||||
if (!file.is_open())
|
||||
throw std::runtime_error("Failed to open " + filename + " to write.");
|
||||
|
||||
for (const auto cit : g) {
|
||||
file << vertexSerializer(cit) << std::endl;
|
||||
for (const auto cit2 : g.neighboursOf(cit))
|
||||
file << vertexSerializer(cit2) << std::endl;
|
||||
|
||||
file << std::endl;
|
||||
}
|
||||
file.close();
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
#include <graph/graph_plaintext.hpp>
|
||||
|
||||
#include "../catch.hpp"
|
||||
|
||||
#include "fixture.hpp"
|
||||
|
||||
#include <cstdio> // remove file
|
||||
|
||||
inline int intCreator(const std::string& s) { return std::stoi(s); }
|
||||
inline std::string intSerializer(int i) { return std::to_string(i); }
|
||||
|
||||
/// @note is there a smareter way to do this?
|
||||
inline std::string s2s(const std::string& s) { return s; }
|
||||
|
||||
|
||||
TEST_CASE( "Plain text import/export", "[IO]" ) {
|
||||
|
||||
SECTION("Invalid files") {
|
||||
const std::string root_file("/root/graph_dump.txt");
|
||||
const Graph<int> g1;
|
||||
CHECK_THROWS ( writeGraphToPlainText(g1, root_file, intSerializer) );
|
||||
CHECK_THROWS ( readGraphFromPlainText<int>(root_file, intCreator) );
|
||||
}
|
||||
|
||||
SECTION("vertices are strings") {
|
||||
const std::string fileName("/tmp/graph_dump.txt");
|
||||
const std::vector<std::string> v{ "one", "two", "three", "... and four"};
|
||||
Graph<std::string> g1(v);
|
||||
g1.addEdge(v[0], v[1]);
|
||||
g1.addEdge(v[0], v[2]);
|
||||
g1.addEdge(v[2], v[3]);
|
||||
|
||||
writeGraphToPlainText(g1, fileName, s2s);
|
||||
const Graph<std::string> g2 = readGraphFromPlainText<std::string>(fileName, s2s);
|
||||
REQUIRE ( g1 == g2 );
|
||||
|
||||
remove(fileName.c_str());
|
||||
}
|
||||
|
||||
SECTION("vertices are float coordinates") {
|
||||
const std::string fileName("/tmp/graph_dump.txt");
|
||||
const std::vector<typename Graph<float2>::Edge>* edges = createEdges<float2>(4, 4);
|
||||
const Graph<float2> g1(*edges);
|
||||
writeGraphToPlainText(g1, fileName, float2serializer);
|
||||
const Graph<float2> g2 = readGraphFromPlainText<float2>(fileName, float2creator);
|
||||
REQUIRE ( g1 == g2 );
|
||||
|
||||
remove(fileName.c_str());
|
||||
delete edges;
|
||||
}
|
||||
}
|
Loading…
Reference in new issue