23 #ifndef FST_EXTENSIONS_FAR_STLIST_H_ 24 #define FST_EXTENSIONS_FAR_STLIST_H_ 43 #include <string_view> 56 template <
class T,
class Writer>
60 : stream_(source.empty()
64 std::ios_base::out | std::ios_base::binary)),
69 FSTERROR() <<
"STListWriter::STListWriter: Error writing to file: " 79 void Add(std::string_view key,
const T &t) {
81 FSTERROR() <<
"STListWriter::Add: Key empty: " << key;
83 }
else if (key < last_key_) {
84 FSTERROR() <<
"STListWriter::Add: Key out of order: " << key;
89 last_key_.assign(key.data(), key.size());
91 entry_writer_(*stream_, t);
94 bool Error()
const {
return error_; }
98 if (stream_ != &std::cout)
delete stream_;
102 Writer entry_writer_;
103 std::ostream *stream_;
104 std::string last_key_;
117 template <
class T,
class Reader>
121 : sources_(sources), error_(false) {
122 streams_.resize(sources.size(),
nullptr);
123 bool has_stdin =
false;
124 for (
size_t i = 0; i < sources.size(); ++i) {
125 if (sources[i].empty()) {
127 streams_[i] = &std::cin;
128 sources_[i] =
"stdin";
131 FSTERROR() <<
"STListReader::STListReader: Cannot read multiple " 132 <<
"inputs from standard input";
137 streams_[i] =
new std::ifstream(
138 sources[i], std::ios_base::in | std::ios_base::binary);
139 if (streams_[i]->fail()) {
140 FSTERROR() <<
"STListReader::STListReader: Error reading file: " 146 int32_t magic_number = 0;
147 ReadType(*streams_[i], &magic_number);
148 int32_t file_version = 0;
149 ReadType(*streams_[i], &file_version);
150 if (magic_number != kSTListMagicNumber) {
151 FSTERROR() <<
"STListReader::STListReader: Wrong file type: " 156 if (file_version != kSTListFileVersion) {
157 FSTERROR() <<
"STListReader::STListReader: Wrong file version: " 164 if (!key.empty()) heap_.push(std::make_pair(key, i));
166 FSTERROR() <<
"STListReader: Error reading file: " << sources_[i];
171 if (heap_.empty())
return;
172 const auto current = heap_.top().second;
173 entry_.reset(entry_reader_(*streams_[current]));
174 if (!entry_ || !*streams_[current]) {
175 FSTERROR() <<
"STListReader: Error reading entry for key " 176 << heap_.top().first <<
", file " << sources_[current];
182 for (
auto &stream : streams_) {
183 if (stream != &std::cin)
delete stream;
188 std::vector<std::string> sources;
189 sources.push_back(std::string(source));
194 const std::vector<std::string> &sources) {
199 FSTERROR() <<
"STListReader::Reset: Operation not supported";
203 bool Find(std::string_view key) {
204 FSTERROR() <<
"STListReader::Find: Operation not supported";
209 bool Done()
const {
return error_ || heap_.empty(); }
213 auto current = heap_.top().second;
216 ReadType(*(streams_[current]), &key);
217 if (!*streams_[current]) {
218 FSTERROR() <<
"STListReader: Error reading file: " << sources_[current];
222 if (!key.empty()) heap_.push(std::make_pair(key, current));
223 if (!heap_.empty()) {
224 current = heap_.top().second;
225 entry_.reset(entry_reader_(*streams_[current]));
226 if (!entry_ || !*streams_[current]) {
227 FSTERROR() <<
"STListReader: Error reading entry for key: " 228 << heap_.top().first <<
", file: " << sources_[current];
234 const std::string &
GetKey()
const {
return heap_.top().first; }
238 bool Error()
const {
return error_; }
241 Reader entry_reader_;
242 std::vector<std::istream *> streams_;
243 std::vector<std::string> sources_;
244 std::priority_queue<std::pair<std::string, size_t>,
245 std::vector<std::pair<std::string, size_t>>,
246 std::greater<std::pair<std::string, size_t>>>
248 mutable std::unique_ptr<T> entry_;
261 template <
class Header>
263 if (source.empty()) {
264 LOG(ERROR) <<
"ReadSTListHeader: Can't read header from standard input";
267 std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
269 LOG(ERROR) <<
"ReadSTListHeader: Could not open file: " << source;
272 int32_t magic_number = 0;
274 int32_t file_version = 0;
276 if (magic_number != kSTListMagicNumber) {
277 LOG(ERROR) <<
"ReadSTListHeader: Wrong file type: " << source;
280 if (file_version != kSTListFileVersion) {
281 LOG(ERROR) <<
"ReadSTListHeader: Wrong file version: " << source;
287 LOG(ERROR) <<
"ReadSTListHeader: Error reading key: " << source;
291 if (key.empty())
return true;
292 if (!header->Read(strm, source +
":" + key)) {
293 LOG(ERROR) <<
"ReadSTListHeader: Error reading FstHeader: " << source;
297 LOG(ERROR) <<
"ReadSTListHeader: Error reading file: " << source;
303 bool IsSTList(std::string_view source);
307 #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)
STListWriter(std::string_view source)
void Add(std::string_view key, const T &t)
std::ostream & WriteType(std::ostream &strm, const T t)
bool ReadSTListHeader(const std::string &source, Header *header)
const std::string & GetKey() const
bool IsSTList(std::string_view source)
static STListReader< T, Reader > * Open(std::string_view source)
static STListWriter< T, Writer > * Create(std::string_view source)
std::istream & ReadType(std::istream &strm, T *t)
STListReader(const std::vector< std::string > &sources)
constexpr int32_t kSTListMagicNumber