// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. // // These classes are only recommended for use in high-level scripting // applications. Most users should use the lower-level templated versions // corresponding to these classes. #include #include #include #include #include #include #include #include namespace fst { namespace script { // Registration. REGISTER_FST_CLASSES(StdArc); REGISTER_FST_CLASSES(LogArc); REGISTER_FST_CLASSES(Log64Arc); // Helper functions. namespace { template F *ReadFstClass(std::istream &istrm, const string &fname) { if (!istrm) { LOG(ERROR) << "ReadFstClass: Can't open file: " << fname; return nullptr; } FstHeader hdr; if (!hdr.Read(istrm, fname)) return nullptr; const FstReadOptions read_options(fname, &hdr); const auto &arc_type = hdr.ArcType(); static const auto *io_register = IORegistration::Register::GetRegister(); const auto reader = io_register->GetReader(arc_type); if (!reader) { LOG(ERROR) << "ReadFstClass: Unknown arc type: " << arc_type; return nullptr; } return reader(istrm, read_options); } template FstClassImplBase *CreateFstClass(const string &arc_type) { static const auto *io_register = IORegistration::Register::GetRegister(); auto creator = io_register->GetCreator(arc_type); if (!creator) { FSTERROR() << "CreateFstClass: Unknown arc type: " << arc_type; return nullptr; } return creator(); } template FstClassImplBase *ConvertFstClass(const FstClass &other) { static const auto *io_register = IORegistration::Register::GetRegister(); auto converter = io_register->GetConverter(other.ArcType()); if (!converter) { FSTERROR() << "ConvertFstClass: Unknown arc type: " << other.ArcType(); return nullptr; } return converter(other); } } // namespace // FstClass methods. FstClass *FstClass::Read(const string &fname) { if (!fname.empty()) { std::ifstream istrm(fname, std::ios_base::in | std::ios_base::binary); return ReadFstClass(istrm, fname); } else { return ReadFstClass(std::cin, "standard input"); } } FstClass *FstClass::Read(std::istream &istrm, const string &source) { return ReadFstClass(istrm, source); } bool FstClass::WeightTypesMatch(const WeightClass &weight, const string &op_name) const { if (WeightType() != weight.Type()) { FSTERROR() << "FST and weight with non-matching weight types passed to " << op_name << ": " << WeightType() << " and " << weight.Type(); return false; } return true; } // MutableFstClass methods. MutableFstClass *MutableFstClass::Read(const string &fname, bool convert) { if (convert == false) { if (!fname.empty()) { std::ifstream in(fname, std::ios_base::in | std::ios_base::binary); return ReadFstClass(in, fname); } else { return ReadFstClass(std::cin, "standard input"); } } else { // Converts to VectorFstClass if not mutable. std::unique_ptr ifst(FstClass::Read(fname)); if (!ifst) return nullptr; if (ifst->Properties(kMutable, false) == kMutable) { return static_cast(ifst.release()); } else { return new VectorFstClass(*ifst.release()); } } } // VectorFstClass methods. VectorFstClass *VectorFstClass::Read(const string &fname) { if (!fname.empty()) { std::ifstream in(fname, std::ios_base::in | std::ios_base::binary); return ReadFstClass(in, fname); } else { return ReadFstClass(std::cin, "standard input"); } } VectorFstClass::VectorFstClass(const string &arc_type) : MutableFstClass(CreateFstClass(arc_type)) {} VectorFstClass::VectorFstClass(const FstClass &other) : MutableFstClass(ConvertFstClass(other)) {} } // namespace script } // namespace fst