Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarDirectives.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/StarDirectives.cpp')
-rw-r--r--source/core/StarDirectives.cpp241
1 files changed, 241 insertions, 0 deletions
diff --git a/source/core/StarDirectives.cpp b/source/core/StarDirectives.cpp
new file mode 100644
index 0000000..9214abf
--- /dev/null
+++ b/source/core/StarDirectives.cpp
@@ -0,0 +1,241 @@
+#include "StarImage.hpp"
+#include "StarImageProcessing.hpp"
+#include "StarDirectives.hpp"
+#include "StarXXHash.hpp"
+#include "StarLogging.hpp"
+
+namespace Star {
+
+Directives::Entry::Entry(ImageOperation&& newOperation, String&& newString) {
+ operation = move(newOperation);
+ string = move(newString);
+}
+
+Directives::Entry::Entry(ImageOperation const& newOperation, String const& newString) {
+ operation = newOperation;
+ string = newString;
+}
+
+Directives::Entry::Entry(Entry const& other) {
+ operation = other.operation;
+ string = other.string;
+}
+
+Directives::Directives() : hash(0) {}
+Directives::Directives(String const& directives) : hash(0) {
+ string = directives;
+ parse(string);
+}
+
+Directives::Directives(String&& directives) : hash(0) {
+ string = move(directives);
+ parse(string);
+}
+
+Directives::Directives(const char* directives) : hash(0), string(directives) {
+ parse(string);
+}
+
+Directives::Directives(List<Entry>&& newEntries) {
+ entries = std::make_shared<List<Entry> const>(move(newEntries));
+ String newString;
+ string = move(buildString(newString));
+ hash = XXH3_64bits(string.utf8Ptr(), string.utf8Size());
+}
+
+void Directives::parse(String const& directives) {
+ if (directives.empty())
+ return;
+
+ List<Entry> newList;
+ StringList split = directives.split('?');
+ newList.reserve(split.size());
+ for (String& str : split) {
+ if (!str.empty()) {
+ try {
+ ImageOperation operation = imageOperationFromString(str);
+ newList.emplace_back(move(operation), move(str));
+ } catch (StarException const& e) {
+ Logger::logf(LogLevel::Error, "Error parsing image operation: %s", e.what());
+ }
+ }
+ }
+
+ if (newList.empty())
+ return;
+
+ entries = std::make_shared<List<Entry> const>(move(newList));
+ hash = XXH3_64bits(directives.utf8Ptr(), directives.utf8Size());
+ //if (directives.utf8Size() > 1000)
+ // Logger::logf(LogLevel::Debug, "Directives: Parsed %u character long string", directives.utf8Size());
+}
+
+String& Directives::buildString(String& out) const {
+ if (entries) {
+ for (auto& entry : *entries) {
+ out += "?";
+ out += entry.string;
+ }
+ }
+
+ return out;
+}
+
+String Directives::toString() const {
+ return string;
+}
+
+inline bool Directives::empty() const {
+ return !entries || entries->empty();
+}
+
+inline Directives::operator bool() const {
+ return !empty();
+}
+
+
+DataStream& operator>>(DataStream& ds, Directives& directives) {
+ String string;
+ ds.read(string);
+
+ directives.parse(string);
+
+ return ds;
+}
+
+DataStream& operator<<(DataStream& ds, Directives const& directives) {
+ ds.write(directives.toString());
+
+ return ds;
+}
+
+DirectivesGroup::DirectivesGroup() : m_count(0) {}
+DirectivesGroup::DirectivesGroup(String const& directives) : m_count(0) {
+ if (directives.empty())
+ return;
+
+ Directives parsed(directives);
+ if (parsed) {
+ m_directives.emplace_back(move(parsed));
+ m_count = m_directives.back().entries->size();
+ }
+}
+DirectivesGroup::DirectivesGroup(String&& directives) : m_count(0) {
+ if (directives.empty()) {
+ directives.clear();
+ return;
+ }
+
+ Directives parsed(move(directives));
+ if (parsed) {
+ m_directives.emplace_back(move(parsed));
+ m_count = m_directives.back().entries->size();
+ }
+}
+
+inline bool DirectivesGroup::empty() const {
+ return m_count == 0;
+}
+
+inline DirectivesGroup::operator bool() const {
+ return empty();
+}
+
+inline bool DirectivesGroup::compare(DirectivesGroup const& other) const {
+ if (m_count != other.m_count)
+ return false;
+
+ if (empty())
+ return true;
+
+ return hash() == other.hash();
+}
+
+void DirectivesGroup::append(Directives const& directives) {
+ m_directives.emplace_back(directives);
+ if (directives.entries)
+ m_count += m_directives.back().entries->size();
+}
+
+void DirectivesGroup::append(List<Directives::Entry>&& entries) {
+ size_t size = entries.size();
+ m_directives.emplace_back(move(entries));
+ m_count += size;
+}
+
+void DirectivesGroup::clear() {
+ m_directives.clear();
+ m_count = 0;
+}
+
+DirectivesGroup& DirectivesGroup::operator+=(Directives const& other) {
+ append(other);
+ return *this;
+}
+
+inline String DirectivesGroup::toString() const {
+ String string;
+ addToString(string);
+ return string;
+}
+
+void DirectivesGroup::addToString(String& string) const {
+ for (auto& directives : m_directives)
+ string += directives.string;
+}
+
+void DirectivesGroup::forEach(DirectivesCallback callback) const {
+ for (auto& directives : m_directives) {
+ if (directives.entries) {
+ for (auto& entry : *directives.entries)
+ callback(entry);
+ }
+ }
+}
+
+bool DirectivesGroup::forEachAbortable(AbortableDirectivesCallback callback) const {
+ for (auto& directives : m_directives) {
+ if (directives.entries) {
+ for (auto& entry : *directives.entries) {
+ if (!callback(entry))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+inline Image DirectivesGroup::applyNewImage(Image const& image) const {
+ Image result = image;
+ applyExistingImage(result);
+ return result;
+}
+
+void DirectivesGroup::applyExistingImage(Image& image) const {
+ forEach([&](auto const& entry) {
+ processImageOperation(entry.operation, image);
+ });
+}
+
+inline size_t DirectivesGroup::hash() const {
+ XXHash3 hasher;
+ for (auto& directives : m_directives)
+ hasher.push((const char*)&directives.hash, sizeof(directives.hash));
+
+ return hasher.digest();
+}
+
+bool operator==(DirectivesGroup const& a, DirectivesGroup const& b) {
+ return a.compare(b);
+}
+
+bool operator!=(DirectivesGroup const& a, DirectivesGroup const& b) {
+ return !a.compare(b);
+}
+
+size_t hash<DirectivesGroup>::operator()(DirectivesGroup const& s) const {
+ return s.hash();
+}
+
+} \ No newline at end of file