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

summaryrefslogtreecommitdiff
path: root/source/core/StarDirectives.hpp
blob: dafa2a0c51acd02f11478cd076edfd3b6b05a0e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#ifndef STAR_DIRECTIVES_HPP
#define STAR_DIRECTIVES_HPP

#include "StarImageProcessing.hpp"
#include "StarHash.hpp"
#include "StarDataStream.hpp"

namespace Star {

STAR_CLASS(Directives);
STAR_CLASS(DirectivesGroup);
STAR_EXCEPTION(DirectivesException, StarException);

// Kae: My attempt at reducing memory allocation and per-frame string parsing for extremely long directives
class Directives {
public:
  struct Entry {
    ImageOperation operation;
    String string; // One day, we can make this a string_view pointing to Entry::string.

    Entry(ImageOperation&& newOperation, String&& newString);
    Entry(ImageOperation const& newOperation, String const& newString);
    Entry(Entry const& other);
  };

  Directives();
  Directives(String const& directives);
  Directives(String&& directives);
  Directives(const char* directives);
  Directives(List<Entry>&& entries);

  void parse(String const& directives);
  String& buildString(String& out) const;
  String toString() const;
  inline bool empty() const;
  inline operator bool() const;

  friend DataStream& operator>>(DataStream& ds, Directives& directives);
  friend DataStream& operator<<(DataStream& ds, Directives const& directives);

  std::shared_ptr<List<Entry> const> entries;
  size_t hash = 0;
  String string;
};

class DirectivesGroup {
public:
  DirectivesGroup();
  DirectivesGroup(String const& directives);
  DirectivesGroup(String&& directives);

  void parseDirectivesIntoLeaf(String const& directives);

  inline bool empty() const;
  inline operator bool() const;
  bool compare(DirectivesGroup const& other) const;
  void append(Directives const& other);
  void append(List<Directives::Entry>&& entries);
  void clear();

  DirectivesGroup& operator+=(Directives const& other);

  inline String toString() const;
  void addToString(String& string) const;

  typedef function<void(Directives::Entry const&)> DirectivesCallback;
  typedef function<bool(Directives::Entry const&)> AbortableDirectivesCallback;

  void forEach(DirectivesCallback callback) const;
  bool forEachAbortable(AbortableDirectivesCallback callback) const;

  inline Image applyNewImage(const Image& image) const;
  void applyExistingImage(Image& image) const;
  
  inline size_t hash() const;
  const List<Directives>& list() const;

  friend bool operator==(DirectivesGroup const& a, DirectivesGroup const& b);
  friend bool operator!=(DirectivesGroup const& a, DirectivesGroup const& b);

  friend DataStream& operator>>(DataStream& ds, DirectivesGroup& directives);
  friend DataStream& operator<<(DataStream& ds, DirectivesGroup const& directives);
private:
  void buildString(String& string, const DirectivesGroup& directives) const;

  List<Directives> m_directives;
  size_t m_count;
};


template <>
struct hash<DirectivesGroup> {
  size_t operator()(DirectivesGroup const& s) const;
};

typedef DirectivesGroup ImageDirectives;

}

#endif