aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-10-22 14:00:41 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-10-22 14:00:41 +0200
commitbc02054d56118110a36aea72d21f9d5e73d07d1f (patch)
tree2fc49dd3f93307df6242b8e63bca0e26b2e62168
parentfab0fccc0aaa18e915bcd08e81e5a04177e435cd (diff)
refactor file reading factory
-rw-r--r--FileReader.cpp9
-rw-r--r--FileReader.h17
-rw-r--r--FileReaderFactory.cpp40
-rw-r--r--FileReaderFactory.h15
-rw-r--r--HTTPFileReader.cpp16
-rw-r--r--HTTPFileReader.h17
-rw-r--r--LoadFilesCommand.cpp2
-rw-r--r--LocalFileReader.cpp27
-rw-r--r--LocalFileReader.h20
-rw-r--r--docs/class-diag.puml69
10 files changed, 98 insertions, 134 deletions
diff --git a/FileReader.cpp b/FileReader.cpp
index b76de50..89ebe17 100644
--- a/FileReader.cpp
+++ b/FileReader.cpp
@@ -1,9 +1,6 @@
-#include <string>
-
#include "FileReader.h"
-#include "FileReaderFactory.h"
-FileReader::FileReader(const std::string protocol) {
- FileReaderFactory::register_strategy(protocol, this);
-}
+using namespace std;
+
+FileReader::FileReader(const string & url) : url(url) { }
diff --git a/FileReader.h b/FileReader.h
index f896ec8..ee6e550 100644
--- a/FileReader.h
+++ b/FileReader.h
@@ -5,21 +5,20 @@ class FileReaderFactory;
#include <string>
class FileReader {
-protected:
- virtual void open(const std::string url) = 0;
-public:
- virtual void close() = 0;
- virtual const std::string read() = 0;
+ friend class FileReaderFactory;
+protected:
+ FileReader(const std::string & url);
public:
virtual ~FileReader() = default;
protected:
- FileReader() = default;
- virtual FileReader * clone() const = 0;
+ virtual void open() = 0;
+public:
+ virtual void close() = 0;
+ virtual const std::string read() = 0;
protected:
- FileReader(const std::string protocol);
- friend FileReaderFactory;
+ const std::string url = "";
};
diff --git a/FileReaderFactory.cpp b/FileReaderFactory.cpp
index 4b72b11..e40dbb9 100644
--- a/FileReaderFactory.cpp
+++ b/FileReaderFactory.cpp
@@ -3,34 +3,28 @@
#include "FileReaderFactory.h"
#include "FileReader.h"
+#include "LocalFileReader.h"
+#include "HTTPFileReader.h"
+
using namespace std;
-unique_ptr<FileReader> FileReaderFactory::open(const std::string url) {
- FileReader * reader = find_reader(url)->clone();
- reader->open(url);
- return unique_ptr<FileReader>(reader);
-}
+unique_ptr<FileReader> FileReaderFactory::create(const string & url) {
+ FileReader * reader = nullptr;
-void FileReaderFactory::register_strategy(const std::string type, const FileReader * node) {
- static FactoryMap & map = get_map();
- map[type] = node;
-}
+ // protocol handlers
+ if (url.starts_with("file://"))
+ reader = new LocalFileReader(url);
+ else if (url.starts_with("http://"))
+ reader = new HTTPFileReader(url);
+ else if (url.starts_with("https://"))
+ reader = new HTTPFileReader(url);
-FactoryMap & FileReaderFactory::get_map() {
- static FactoryMap map;
- return map;
-}
-
-const FileReader * FileReaderFactory::find_reader(const std::string type) {
- static FactoryMap & map = get_map();
+ // no protocol = treat as file://
+ if (reader == nullptr)
+ reader = new LocalFileReader(url);
- // try to find protocol by prefix
- for (auto item : map) {
- if (!type.starts_with(item.first)) continue;
- return item.second;
- }
+ reader->open();
- // fallback is local file
- return map.find("file://")->second;
+ return unique_ptr<FileReader>(reader);
}
diff --git a/FileReaderFactory.h b/FileReaderFactory.h
index 0829985..85521c0 100644
--- a/FileReaderFactory.h
+++ b/FileReaderFactory.h
@@ -1,27 +1,16 @@
#pragma once
#include <string>
-#include <map>
#include <memory>
#include "FileReader.h"
-using FactoryMap = std::map<std::string, const FileReader *>;
-
class FileReaderFactory {
public:
- static std::unique_ptr<FileReader> open(const std::string url);
+ std::unique_ptr<FileReader> create(const std::string & url);
-private:
+public:
FileReaderFactory() = default;
virtual ~FileReaderFactory() = default;
-
-private:
- static void register_strategy(const std::string type, const FileReader * node);
- static FactoryMap & get_map();
- static const FileReader * find_reader(const std::string type);
-
-private:
- friend FileReader;
};
diff --git a/HTTPFileReader.cpp b/HTTPFileReader.cpp
index d7f5dd4..191e212 100644
--- a/HTTPFileReader.cpp
+++ b/HTTPFileReader.cpp
@@ -2,10 +2,10 @@
#include "HTTPFileReader.h"
-HTTPFileReader HTTPFileReader::instance(protocol);
+using namespace std;
-void HTTPFileReader::open(const std::string url) {
- _res = cpr::Get(cpr::Url{url});
+void HTTPFileReader::open() {
+ _res = cpr::Get(cpr::Url{this->url});
}
void HTTPFileReader::close() { }
@@ -14,13 +14,3 @@ const std::string HTTPFileReader::read() {
return _res.text.data();
}
-HTTPFileReader::~HTTPFileReader() {
- this->close();
-}
-
-HTTPFileReader * HTTPFileReader::clone() const {
- return new HTTPFileReader(this);
-}
-
-HTTPFileReader::HTTPFileReader(const HTTPFileReader *) : FileReader() { }
-
diff --git a/HTTPFileReader.h b/HTTPFileReader.h
index 4b05e18..59a8599 100644
--- a/HTTPFileReader.h
+++ b/HTTPFileReader.h
@@ -5,24 +5,15 @@
#include "FileReader.h"
class HTTPFileReader : FileReader {
+ friend class FileReaderFactory;
+ using FileReader::FileReader;
+
protected:
- virtual void open(const std::string url);
+ virtual void open();
public:
virtual void close();
virtual const std::string read();
-public:
- virtual ~HTTPFileReader();
-
-private:
- HTTPFileReader(const HTTPFileReader *);
- virtual HTTPFileReader * clone() const;
-
-private:
- using FileReader::FileReader;
- constexpr static const std::string protocol = "https://";
- static HTTPFileReader instance;
-
private:
cpr::Response _res;
};
diff --git a/LoadFilesCommand.cpp b/LoadFilesCommand.cpp
index 82ede60..3fb4978 100644
--- a/LoadFilesCommand.cpp
+++ b/LoadFilesCommand.cpp
@@ -28,7 +28,7 @@ void LoadFilesCommand::load_files() {
MuseumDeserializer deserializer { this->museum };
for (string url : files) {
- unique_ptr<FileReader> file = FileReaderFactory::open(url);
+ unique_ptr<FileReader> file = FileReaderFactory().create(url);
try {
ParserFactory::parse(*file, deserializer);
} catch (Exception & e) {
diff --git a/LocalFileReader.cpp b/LocalFileReader.cpp
index 1f9d574..a505616 100644
--- a/LocalFileReader.cpp
+++ b/LocalFileReader.cpp
@@ -1,17 +1,18 @@
#include <cstdio>
+#include <cstring>
#include <iterator>
#include "LocalFileReader.h"
#include "Exception.h"
-LocalFileReader LocalFileReader::instance(protocol);
+using namespace std;
-void LocalFileReader::open(const std::string url) {
- std::string path = url;
- if (path.starts_with(protocol))
- path = path.substr(protocol.size());
+void LocalFileReader::open() {
+ string path = this->url;
+ if (path.starts_with("file://"))
+ path = path.substr(strlen("file://"));
- this->file = new std::ifstream(path, std::ios::in);
+ this->file = new ifstream(path, ios::in);
if (this->file->fail() || !this->file->is_open())
throw Exception("cannot open file://%s\n", path.c_str());
}
@@ -23,7 +24,7 @@ void LocalFileReader::close() {
this->file->close();
}
-const std::string LocalFileReader::read() {
+const string LocalFileReader::read() {
if (this->content != nullptr)
return *this->content;
@@ -33,9 +34,9 @@ const std::string LocalFileReader::read() {
if (!this->file->is_open())
throw Exception("FileReader read after close\n");
- this->content = new std::string(
- std::istreambuf_iterator<char>(*this->file),
- std::istreambuf_iterator<char>()
+ this->content = new string(
+ istreambuf_iterator<char>(*this->file),
+ istreambuf_iterator<char>()
);
return *this->content;
@@ -55,9 +56,3 @@ LocalFileReader::~LocalFileReader() {
}
}
-LocalFileReader * LocalFileReader::clone() const {
- return new LocalFileReader(this);
-}
-
-LocalFileReader::LocalFileReader(const LocalFileReader *) : FileReader() { }
-
diff --git a/LocalFileReader.h b/LocalFileReader.h
index 6ea4f84..b9daa55 100644
--- a/LocalFileReader.h
+++ b/LocalFileReader.h
@@ -5,23 +5,17 @@
#include "FileReader.h"
class LocalFileReader : FileReader {
-protected:
- virtual void open(const std::string url);
-public:
- virtual void close();
- virtual const std::string read();
+ friend class FileReaderFactory;
+ using FileReader::FileReader;
public:
virtual ~LocalFileReader();
-private:
- LocalFileReader(const LocalFileReader *);
- virtual LocalFileReader * clone() const;
-
-private:
- using FileReader::FileReader;
- constexpr static const std::string protocol = "file://";
- static LocalFileReader instance;
+protected:
+ virtual void open();
+public:
+ virtual void close();
+ virtual const std::string read();
private:
std::ifstream * file = nullptr;
diff --git a/docs/class-diag.puml b/docs/class-diag.puml
index 8058e0a..6c38d9c 100644
--- a/docs/class-diag.puml
+++ b/docs/class-diag.puml
@@ -18,29 +18,31 @@ exception Exception {
}
rectangle Group_FileReading as "File reading" <<group>> {
- class FileReaderFactory <<Factory>> {
- + open(url) : FileReader&
+ class FileReaderFactory <<factory>> {
+ + create(url : const string &) : uniq<FileReader>
}
interface FileReader {
- + read() : string
+ # FileReader(url : const string &)
+ + ~FileReader()
+ --
+ # open()
+ + read() : const string
+ close()
--
- # open(string url)
- # clone() : FileReader* <<const>>
+ # url : const string
}
class LocalFileReader {
- - instance : LocalFileReader <<static>>
+ + ~LocalFileReader()
}
class HTTPFileReader {
- - instance : HTTPFileReader <<static>>
}
package CPR { }
- FileReader <|.u. LocalFileReader
- FileReader <|.u. HTTPFileReader
+ FileReader <|.d. LocalFileReader
+ FileReader <|.d. HTTPFileReader
- FileReader .l> FileReaderFactory
- FileReader <. FileReaderFactory
+ FileReaderFactory -u-> LocalFileReader
+ FileReaderFactory -u-> HTTPFileReader
HTTPFileReader -l> CPR
@@ -59,20 +61,21 @@ rectangle Group_ParsingDeserialization as "Parsing & deserialization" <<group>>
+ heuristic(FileReader &) : unsigned int <<static>>
}
- Parser .> ParserFactory
- Parser <. ParserFactory
-
- class CSVParser
class XMLParser
class TXTParser
+ class CSVParser
package pugixml { }
- CSVParser ..|> Parser
- TXTParser ..|> Parser
- XMLParser ..|> Parser
+ Parser <|.d. XMLParser
+ Parser <|.d. TXTParser
+ Parser <|.d. CSVParser
+
+ ParserFactory -u-> XMLParser
+ ParserFactory -u-> TXTParser
+ ParserFactory -u-> CSVParser
- XMLParser -> pugixml
+ XMLParser -r> pugixml
class MuseumDeserializer {
+ MuseumDeserializer(Museum &)
@@ -135,6 +138,7 @@ rectangle Group_Model as "Model" <<group>> {
- worker : thread *
- work()
}
+ together {
class Canvas {
+ Canvas(Museum &)
--
@@ -148,6 +152,10 @@ rectangle Group_Model as "Model" <<group>> {
- tiles : vector<Tile *>
- museum : Museum &
}
+ struct CanvasData {
+ + rows : unsigned int
+ + columns : unsigned int
+ }
class People {
+ People(Museum &)
--
@@ -159,6 +167,8 @@ rectangle Group_Model as "Model" <<group>> {
- artist_count : size_t
- museum : Museum &
}
+ }
+ together {
class Tile {
+ data : TileData
+ color : Color
@@ -190,11 +200,9 @@ rectangle Group_Model as "Model" <<group>> {
+ vx : float
+ vy : float
}
- struct CanvasData {
- + rows : unsigned int
- + columns : unsigned int
}
+ together {
struct Color {
red : unsigned int
green : unsigned int
@@ -204,7 +212,9 @@ rectangle Group_Model as "Model" <<group>> {
+ get_color(string) : Color <<static>>
+ register_color(string, Color) <<static>>
}
+ }
+ together {
interface TileBehavior {
+ step(Artist *)
+ update(Tile &)
@@ -214,13 +224,13 @@ rectangle Group_Model as "Model" <<group>> {
# interactions : unsigned int
# museum : Museum &
}
-
class TileBehaviorFactory {
+ TileBehaviorFactory(Museum &)
+ create(string) : uniq<TileBehavior>
--
- museum : Museum &
}
+ }
together {
class NullTileBehavior {
@@ -243,8 +253,15 @@ rectangle Group_Model as "Model" <<group>> {
--
- last_interactions : unsigned int
}
+
+ NullTileBehavior -d[hidden]- StepTileBehavior
+ StepTileBehavior -d[hidden]- DeleteArtistTileBehavior
+ DeleteArtistTileBehavior -d[hidden]- SetNeighborTileBehavior
+ SetNeighborTileBehavior -d[hidden]- CreateArtistTileBehavior
}
+ Canvas -l[hidden] People
+
Museum --> People
Museum --> Canvas
@@ -258,7 +275,7 @@ rectangle Group_Model as "Model" <<group>> {
Tile --> "state" Color
Tile .[norank].> TileColorFactory
- TileColorFactory .> Color
+ TileColorFactory -> Color
TileBehavior <|.. NullTileBehavior
TileBehavior <|.. StepTileBehavior
@@ -275,9 +292,6 @@ rectangle Group_Model as "Model" <<group>> {
Tile --> "state" TileBehavior
Tile .[norank].> TileBehaviorFactory
- TileBehaviorFactory .l> TileBehavior
- TileBehaviorFactory <. TileBehavior
-
' LAYOUT
Artist -r[hidden] Tile
}
@@ -378,6 +392,7 @@ rectangle Group_Commands as "Commands" <<group>> {
} /' LAYOUT '/
Parser .l> FileReader
+' Parser -l> FileReaderFactory
MuseumDeserializer .l> Museum
Museum --> PathfindingContext