tudocomp
– The TU Dortmund Compression Framework
InputStream.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 
5 namespace tdc {namespace io {
7  class InputStreamInternal {
8  class Variant {
9  public:
10  virtual std::istream& stream() = 0;
11  virtual ~Variant() {}
12  };
13 
14  class Memory: public InputStreamInternal::Variant {
15  InputAllocChunkHandle m_handle;
16  ViewStream m_stream;
17 
18  friend class InputStreamInternal;
19  public:
20  inline Memory(Memory&& other):
21  m_handle(other.m_handle),
22  m_stream(std::move(other.m_stream))
23  {}
24 
25  inline Memory(InputAllocChunkHandle handle, View view):
26  m_handle(handle),
27  m_stream(view)
28  {}
29 
30  inline std::istream& stream() override {
31  return m_stream.stream();
32  }
33 
34  inline Memory(const Memory& other) = delete;
35  inline Memory() = delete;
36 
37  inline ~Memory() {
38  unregister_alloc_chunk_handle(m_handle);
39  }
40  };
41  class File: public InputStreamInternal::Variant {
42  std::string m_path;
43  std::unique_ptr<std::ifstream> m_stream;
44 
45  friend class InputStreamInternal;
46  public:
47  inline File(std::string&& path, size_t offset):
48  m_path(std::move(path)),
49  m_stream(std::make_unique<std::ifstream>(
50  m_path, std::ios::in | std::ios::binary))
51  {
52  auto& s = *m_stream;
53  s.seekg(offset, std::ios::beg);
54  if (!*m_stream) {
55  throw tdc_input_file_not_found_error(m_path);
56  }
57  }
58 
59  inline File(File&& other):
60  m_path(std::move(other.m_path)),
61  m_stream(std::move(other.m_stream))
62  {}
63 
64  inline std::istream& stream() override {
65  return *m_stream;
66  }
67 
68  inline File(const File& other) = delete;
69  inline File() = delete;
70  };
71 
72  std::unique_ptr<InputStreamInternal::Variant> m_variant;
73  std::unique_ptr<RestrictedIStreamBuf> m_restricted_istream;
74 
75  friend class InputStream;
76  friend class Input;
77 
78  inline InputStreamInternal(const InputStreamInternal& other) = delete;
79  inline InputStreamInternal() = delete;
80 
81  inline InputStreamInternal(InputStreamInternal::Memory&& mem,
82  const InputRestrictions& restrictions):
83  m_variant(std::make_unique<InputStreamInternal::Memory>(std::move(mem)))
84  {
85  if (!restrictions.has_no_restrictions()) {
86  m_restricted_istream = std::make_unique<RestrictedIStreamBuf>(
87  m_variant->stream(),
88  restrictions
89  );
90  }
91  }
92  inline InputStreamInternal(InputStreamInternal::File&& f,
93  const InputRestrictions& restrictions):
94  m_variant(std::make_unique<InputStreamInternal::File>(std::move(f)))
95  {
96  if (!restrictions.has_no_restrictions()) {
97  m_restricted_istream = std::make_unique<RestrictedIStreamBuf>(
98  m_variant->stream(),
99  restrictions
100  );
101  }
102  }
103  inline InputStreamInternal(InputStreamInternal&& s):
104  m_variant(std::move(s.m_variant)),
105  m_restricted_istream(std::move(s.m_restricted_istream)) {}
106 
107  inline std::streambuf* internal_rdbuf() {
108  if (m_restricted_istream) {
109  return &*m_restricted_istream;
110  } else {
111  return m_variant->stream().rdbuf();
112  }
113  }
114  };
116 
118  class InputStream: InputStreamInternal, public std::istream {
119  friend class Input;
120 
121  inline InputStream(InputStreamInternal&& mem):
122  InputStreamInternal(std::move(mem)),
123  std::istream(InputStreamInternal::internal_rdbuf()) {
124  }
125  public:
127  inline InputStream(InputStream&& mem):
128  InputStreamInternal(std::move(mem)),
129  std::istream(mem.rdbuf()) {}
130 
132  inline InputStream(const InputStream& other) = delete;
133 
135  inline InputStream() = delete;
136 
137  using iterator = std::istreambuf_iterator<char>;
138  inline iterator begin() {
139  return iterator(*this);
140  }
141  inline iterator end() {
142  return iterator();
143  }
144  };
145 
146  inline InputStream Input::Variant::as_stream() const {
147  // Change in such a way that restricting stream is applied
148  // for both file and memory
149 
150  if (source().is_file()) {
151  DCHECK(to_unknown())
152  << "TODO: Can not yet slice the trailing end of a stream";
153 
154  return InputStream {
155  InputStreamInternal {
156  InputStream::File {
157  std::string(source().file()),
158  from()
159  },
160  restrictions()
161  }
162  };
163  } if (source().is_view()) {
164  return InputStream {
165  InputStreamInternal {
166  InputStream::Memory {
167  nullptr,
168  source().view().slice(from(), to())
169  },
170  restrictions()
171  }
172  };
173  } else {
174  auto h = alloc().find_or_construct(
175  source(), from(), to(), restrictions());
176  auto v = h->view();
177 
178  return InputStream {
179  InputStreamInternal {
180  InputStream::Memory {
181  h,
182  v
183  },
184  // No restrictions since they are already realized in the buffer
186  }
187  };
188  }
189  }
190 
191 }}
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
io::Input Input
Convenience shortcut to io::Input.
Definition: io.hpp:17
std::istreambuf_iterator< char > iterator
Describes a set of restrictions placed on input data.
InputStream(InputStream &&mem)
Move constructor.
Provides a character stream of the underlying input.
ByteView View
Definition: View.hpp:25
An abstraction layer for algorithm input.
Definition: Input.hpp:37