NuriKit v0.1.0b2
Loading...
Searching...
No Matches
base.h
Go to the documentation of this file.
1//
2// Project NuriKit - Copyright 2023 SNU Compbio Lab.
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#ifndef NURI_FMT_BASE_H_
7#define NURI_FMT_BASE_H_
8
10#include <cstddef>
11#include <filesystem>
12#include <fstream>
13#include <istream>
14#include <memory>
15#include <sstream>
16#include <string>
17#include <string_view>
18#include <vector>
19
20#include <absl/base/attributes.h>
21#include <absl/base/optimization.h>
22#include <absl/log/absl_log.h>
24
26#include "nuri/core/molecule.h"
27#include "nuri/utils.h"
28
29namespace nuri {
30class MoleculeReader;
31
32template <class Reader = MoleculeReader>
34public:
35 MoleculeStream(Reader &reader): reader_(&reader) { }
36
37 MoleculeStream(const MoleculeStream &) = delete;
39 MoleculeStream(MoleculeStream &&) noexcept = default;
40 MoleculeStream &operator=(MoleculeStream &&) noexcept = default;
41 ~MoleculeStream() noexcept = default;
42
49 ABSL_MUST_USE_RESULT bool advance() {
50 if (!reader_->getnext(block_)) {
51 return false;
52 }
53
54 mol_ = reader_->parse(block_);
55 return true;
56 }
57
64 Molecule &current() { return mol_; }
65
72 const Molecule &current() const { return mol_; }
73
74private:
75 Reader *reader_;
76 std::vector<std::string> block_;
77 Molecule mol_;
78};
79
80template <class Stream>
81Stream &operator>>(Stream &stream, Molecule &mol) {
82 if (stream.advance()) {
83 mol = std::move(stream.current());
84 }
85 return stream;
86}
87
89public:
90 MoleculeReader() = default;
91 MoleculeReader(const MoleculeReader &) = delete;
93 MoleculeReader(MoleculeReader &&) noexcept = default;
94 MoleculeReader &operator=(MoleculeReader &&) noexcept = default;
95 virtual ~MoleculeReader() noexcept = default;
96
102 std::vector<std::string> next() {
103 std::vector<std::string> block;
104 if (!getnext(block)) {
105 block.clear();
106 }
107 return block;
108 }
109
122 ABSL_MUST_USE_RESULT virtual bool
123 getnext(std::vector<std::string> &block) = 0;
124
131 virtual Molecule parse(const std::vector<std::string> &block) const = 0;
132
137 virtual bool bond_valid() const = 0;
138
143};
144
145template <auto parser>
147public:
148 DefaultReaderImpl() = default;
149 DefaultReaderImpl(std::istream &is): is_(&is) { }
150
151 Molecule parse(const std::vector<std::string> &block) const final {
152 return parser(block);
153 }
154
155protected:
156 // NOLINTBEGIN(*-non-private-member-variables-in-classes)
157 std::istream *is_;
158 // NOLINTEND(*-non-private-member-variables-in-classes)
159};
160
162public:
167 MoleculeReaderFactory &operator=(MoleculeReaderFactory &&) noexcept = default;
168 virtual ~MoleculeReaderFactory() noexcept = default;
169
176 virtual std::unique_ptr<MoleculeReader>
177 from_stream(std::istream &is) const = 0;
178
185 static const MoleculeReaderFactory *find_factory(std::string_view name);
186
204 static bool register_factory(std::unique_ptr<MoleculeReaderFactory> factory,
205 const std::vector<std::string> &names);
206
222 void register_for(std::string_view alias) const {
223 register_for_name(this, alias);
224 }
225
226private:
227 static void register_for_name(const MoleculeReaderFactory *factory,
228 std::string_view name);
229};
230
231template <class ReaderFactoryImpl>
232bool register_reader_factory(const std::vector<std::string> &names) {
234 std::make_unique<ReaderFactoryImpl>(), names);
235}
236
237template <class MoleculeReaderImpl>
239public:
240 std::unique_ptr<MoleculeReader> from_stream(std::istream &is) const final {
241 return std::make_unique<MoleculeReaderImpl>(is);
242 }
243};
244
245template <class SourceStream, class Reader = MoleculeReader>
247public:
248 template <class... Args>
249 MoleculeReaderWrapper(std::string_view fmt, Args &&...args)
250 : is_(std::forward<Args>(args)...) {
251 const MoleculeReaderFactory *factory =
253
254 if (ABSL_PREDICT_FALSE(factory == nullptr)) {
255 ABSL_LOG(WARNING) << "No factory found for " << fmt;
256 return;
257 }
258
259 reader_ = static_unique_ptr_cast<Reader>(factory->from_stream(is_));
260 }
261
267 std::vector<std::string> next() { return reader_->next(); }
268
277 bool getnext(std::vector<std::string> &block) {
278 return reader_->getnext(block);
279 }
280
287 Molecule parse(const std::vector<std::string> &block) const {
288 return reader_->parse(block);
289 }
290
291 MoleculeStream<Reader> stream() { return { *reader_ }; }
292
293 operator bool() const { return is_ && reader_; }
294
295private:
296 SourceStream is_;
297 std::unique_ptr<Reader> reader_;
298};
299
300template <class Reader>
301class MoleculeReaderWrapper<std::ifstream, Reader> {
302public:
303 explicit MoleculeReaderWrapper(const std::filesystem::path &path): is_(path) {
304 const std::filesystem::path full_ext = path.extension();
305 const std::string_view ext = extension_no_dot(full_ext);
306
307 const MoleculeReaderFactory *factory =
309
310 if (ABSL_PREDICT_FALSE(factory == nullptr)) {
311 ABSL_LOG(WARNING) << "No factory found for " << ext;
312 return;
313 }
314
315 reader_ = static_unique_ptr_cast<Reader>(factory->from_stream(is_));
316 }
317
318 MoleculeReaderWrapper(std::string_view fmt, const std::filesystem::path &path)
319 : is_(path) {
320 const MoleculeReaderFactory *factory =
322
323 if (ABSL_PREDICT_FALSE(factory == nullptr)) {
324 ABSL_LOG(WARNING) << "No factory found for " << fmt;
325 return;
326 }
327
328 reader_ = static_unique_ptr_cast<Reader>(factory->from_stream(is_));
329 }
330
336 std::vector<std::string> next() { return reader_->next(); }
337
346 bool getnext(std::vector<std::string> &block) {
347 return reader_->getnext(block);
348 }
349
356 Molecule parse(const std::vector<std::string> &block) const {
357 return reader_->parse(block);
358 }
359
360 MoleculeStream<Reader> stream() { return { *reader_ }; }
361
362 operator bool() const { return is_ && reader_; }
363
364private:
365 std::ifstream is_;
366 std::unique_ptr<Reader> reader_;
367};
368
369template <class Reader = MoleculeReader>
371
372template <class Reader = MoleculeReader>
374
376public:
377 ReversedStream(std::istream &is, char delim = '\n', std::size_t bufsz = 4096)
378 : is_(&is), delim_(delim), buf_(bufsz) {
379 reset();
380 }
381
382 void reset();
383
384 bool getline(std::string &line);
385
386private:
387 void read_block();
388
389 std::istream *is_;
390 std::size_t prev_;
391 char delim_;
392 internal::DumbBuffer<char> buf_;
393};
394
395namespace internal {
403 extern std::string ascii_safe(std::string_view str);
404
412 extern std::string ascii_newline_safe(std::string_view str);
413} // namespace internal
414} // namespace nuri
415
416#endif /* NURI_FMT_BASE_H_ */
Definition base.h:238
std::unique_ptr< MoleculeReader > from_stream(std::istream &is) const final
Create a new reader from the given istream object.
Definition base.h:240
DefaultReaderImpl(std::istream &is)
Definition base.h:149
Molecule parse(const std::vector< std::string > &block) const final
Parse the current block and return the molecule.
Definition base.h:151
std::istream * is_
Definition base.h:157
Definition base.h:161
static bool register_factory(std::unique_ptr< MoleculeReaderFactory > factory, const std::vector< std::string > &names)
Register the factory for the given format name(s).
MoleculeReaderFactory(const MoleculeReaderFactory &)=default
virtual std::unique_ptr< MoleculeReader > from_stream(std::istream &is) const =0
Create a new reader from the given istream object.
MoleculeReaderFactory(MoleculeReaderFactory &&) noexcept=default
MoleculeReaderFactory & operator=(const MoleculeReaderFactory &)=default
void register_for(std::string_view alias) const
Register this factory for the given alias name.
Definition base.h:222
static const MoleculeReaderFactory * find_factory(std::string_view name)
Find the factory for the given format name.
MoleculeReaderWrapper(const std::filesystem::path &path)
Definition base.h:303
MoleculeStream< Reader > stream()
Definition base.h:360
Molecule parse(const std::vector< std::string > &block) const
Parse the current block and return the molecule.
Definition base.h:356
std::vector< std::string > next()
Advance the stream to the next molecule.
Definition base.h:336
MoleculeReaderWrapper(std::string_view fmt, const std::filesystem::path &path)
Definition base.h:318
bool getnext(std::vector< std::string > &block)
Advance the reader to the next molecule.
Definition base.h:346
Definition base.h:246
std::vector< std::string > next()
Advance the stream to the next molecule.
Definition base.h:267
MoleculeReaderWrapper(std::string_view fmt, Args &&...args)
Definition base.h:249
bool getnext(std::vector< std::string > &block)
Advance the reader to the next molecule.
Definition base.h:277
Molecule parse(const std::vector< std::string > &block) const
Parse the current block and return the molecule.
Definition base.h:287
MoleculeStream< Reader > stream()
Definition base.h:291
Definition base.h:88
MoleculeReader()=default
MoleculeReader(const MoleculeReader &)=delete
MoleculeReader & operator=(const MoleculeReader &)=delete
std::vector< std::string > next()
Advance the reader to the next molecule.
Definition base.h:102
virtual ABSL_MUST_USE_RESULT bool getnext(std::vector< std::string > &block)=0
Advance the reader to the next molecule.
virtual bool bond_valid() const =0
Test whether the reader implementation can provide valid bond information.
MoleculeReader(MoleculeReader &&) noexcept=default
virtual Molecule parse(const std::vector< std::string > &block) const =0
Parse the current block and return the molecule.
MoleculeStream< MoleculeReader > stream()
Convert the reader to a stream object.
Definition base.h:142
Definition base.h:33
const Molecule & current() const
Get the current molecule.
Definition base.h:72
MoleculeStream(const MoleculeStream &)=delete
MoleculeStream(MoleculeStream &&) noexcept=default
Molecule & current()
Get the current molecule.
Definition base.h:64
ABSL_MUST_USE_RESULT bool advance()
Advance the stream to the next molecule.
Definition base.h:49
MoleculeStream & operator=(const MoleculeStream &)=delete
MoleculeStream(Reader &reader)
Definition base.h:35
Read-only molecule class.
Definition molecule.h:943
ReversedStream(std::istream &is, char delim='\n', std::size_t bufsz=4096)
Definition base.h:377
bool getline(std::string &line)
Definition crdgen.h:16
bool register_reader_factory(const std::vector< std::string > &names)
Definition base.h:232
MoleculeReaderWrapper< std::ifstream, Reader > FileMoleculeReader
Definition base.h:370
Stream & operator>>(Stream &stream, Molecule &mol)
Definition base.h:81
MoleculeReaderWrapper< std::istringstream, Reader > StringMoleculeReader
Definition base.h:373