23 #ifndef FST_EXTENSIONS_FAR_STLIST_H_ 24 #define FST_EXTENSIONS_FAR_STLIST_H_ 38 #include <string_view> 51 template <
class T,
class Writer>
55 : stream_(source.empty()
58 source, std::ios_base::out | std::ios_base::binary)),
63 FSTERROR() <<
"STListWriter::STListWriter: Error writing to file: " 73 void Add(std::string_view key,
const T &t) {
75 FSTERROR() <<
"STListWriter::Add: Key empty: " << key;
77 }
else if (key < last_key_) {
78 FSTERROR() <<
"STListWriter::Add: Key out of order: " << key;
83 last_key_.assign(key.data(), key.size());
85 entry_writer_(*stream_, t);
88 bool Error()
const {
return error_; }
92 if (stream_ != &std::cout)
delete stream_;
97 std::ostream *stream_;
98 std::string last_key_;
111 template <
class T,
class Reader>
115 : sources_(sources), error_(false) {
116 streams_.resize(sources.size(),
nullptr);
117 bool has_stdin =
false;
118 for (
size_t i = 0; i < sources.size(); ++i) {
119 if (sources[i].empty()) {
121 streams_[i] = &std::cin;
122 sources_[i] =
"stdin";
125 FSTERROR() <<
"STListReader::STListReader: Cannot read multiple " 126 <<
"inputs from standard input";
131 streams_[i] =
new std::ifstream(
132 sources[i], std::ios_base::in | std::ios_base::binary);
133 if (streams_[i]->fail()) {
134 FSTERROR() <<
"STListReader::STListReader: Error reading file: " 140 int32_t magic_number = 0;
141 ReadType(*streams_[i], &magic_number);
142 int32_t file_version = 0;
143 ReadType(*streams_[i], &file_version);
144 if (magic_number != kSTListMagicNumber) {
145 FSTERROR() <<
"STListReader::STListReader: Wrong file type: " 150 if (file_version != kSTListFileVersion) {
151 FSTERROR() <<
"STListReader::STListReader: Wrong file version: " 158 if (!key.empty()) heap_.push(std::make_pair(key, i));
160 FSTERROR() <<
"STListReader: Error reading file: " << sources_[i];
165 if (heap_.empty())
return;
166 const auto current = heap_.top().second;
167 entry_.reset(entry_reader_(*streams_[current]));
168 if (!entry_ || !*streams_[current]) {
169 FSTERROR() <<
"STListReader: Error reading entry for key " 170 << heap_.top().first <<
", file " << sources_[current];
176 for (
auto &stream : streams_) {
177 if (stream != &std::cin)
delete stream;
182 std::vector<std::string> sources;
183 sources.push_back(source);
188 const std::vector<std::string> &sources) {
193 FSTERROR() <<
"STListReader::Reset: Operation not supported";
197 bool Find(std::string_view key) {
198 FSTERROR() <<
"STListReader::Find: Operation not supported";
203 bool Done()
const {
return error_ || heap_.empty(); }
207 auto current = heap_.top().second;
210 ReadType(*(streams_[current]), &key);
211 if (!*streams_[current]) {
212 FSTERROR() <<
"STListReader: Error reading file: " << sources_[current];
216 if (!key.empty()) heap_.push(std::make_pair(key, current));
217 if (!heap_.empty()) {
218 current = heap_.top().second;
219 entry_.reset(entry_reader_(*streams_[current]));
220 if (!entry_ || !*streams_[current]) {
221 FSTERROR() <<
"STListReader: Error reading entry for key: " 222 << heap_.top().first <<
", file: " << sources_[current];
228 const std::string &
GetKey()
const {
return heap_.top().first; }
232 bool Error()
const {
return error_; }
235 Reader entry_reader_;
236 std::vector<std::istream *> streams_;
237 std::vector<std::string> sources_;
238 std::priority_queue<std::pair<std::string, size_t>,
239 std::vector<std::pair<std::string, size_t>>,
240 std::greater<std::pair<std::string, size_t>>>
242 mutable std::unique_ptr<T> entry_;
255 template <
class Header>
257 if (source.empty()) {
258 LOG(ERROR) <<
"ReadSTListHeader: Can't read header from standard input";
261 std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
263 LOG(ERROR) <<
"ReadSTListHeader: Could not open file: " << source;
266 int32_t magic_number = 0;
268 int32_t file_version = 0;
270 if (magic_number != kSTListMagicNumber) {
271 LOG(ERROR) <<
"ReadSTListHeader: Wrong file type: " << source;
274 if (file_version != kSTListFileVersion) {
275 LOG(ERROR) <<
"ReadSTListHeader: Wrong file version: " << source;
281 LOG(ERROR) <<
"ReadSTListHeader: Error reading key: " << source;
285 if (key.empty())
return true;
286 if (!header->Read(strm, source +
":" + key)) {
287 LOG(ERROR) <<
"ReadSTListHeader: Error reading FstHeader: " << source;
291 LOG(ERROR) <<
"ReadSTListHeader: Error reading file: " << source;
297 bool IsSTList(
const std::string &source);
301 #endif // FST_EXTENSIONS_FAR_STLIST_H_ bool Find(std::string_view key)
const T * GetEntry() const
constexpr int32_t kSTListFileVersion
static STListReader< T, Reader > * Open(const std::vector< std::string > &sources)
void Add(std::string_view key, const T &t)
std::ostream & WriteType(std::ostream &strm, const T t)
static STListReader< T, Reader > * Open(const std::string &source)
bool ReadSTListHeader(const std::string &source, Header *header)
STListWriter(const std::string &source)
const std::string & GetKey() const
static STListWriter< T, Writer > * Create(const std::string &source)
bool IsSTList(const std::string &source)
std::istream & ReadType(std::istream &strm, T *t)
STListReader(const std::vector< std::string > &sources)
constexpr int32_t kSTListMagicNumber