// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. // // Scripting API support for FarReader and FarWriter. #ifndef FST_EXTENSIONS_FAR_FAR_CLASS_H_ #define FST_EXTENSIONS_FAR_FAR_CLASS_H_ #include #include #include #include #include #include namespace fst { namespace script { // FarReader API. // Virtual interface implemented by each concrete FarReaderImpl. // See the FarReader interface in far.h for the exact semantics. class FarReaderImplBase { public: virtual const string &ArcType() const = 0; virtual bool Done() const = 0; virtual bool Error() const = 0; virtual const string &GetKey() const = 0; virtual const FstClass *GetFstClass() const = 0; virtual bool Find(const string &key) = 0; virtual void Next() = 0; virtual void Reset() = 0; virtual FarType Type() const = 0; virtual ~FarReaderImplBase() {} }; // Templated implementation. template class FarReaderClassImpl : public FarReaderImplBase { public: explicit FarReaderClassImpl(const string &filename) : impl_(FarReader::Open(filename)) {} explicit FarReaderClassImpl(const std::vector &filenames) : impl_(FarReader::Open(filenames)) {} const string &ArcType() const final { return Arc::Type(); } bool Done() const final { return impl_->Done(); } bool Error() const final { return impl_->Error(); } bool Find(const string &key) final { return impl_->Find(key); } const FstClass *GetFstClass() const final { fstc_.reset(new FstClass(*impl_->GetFst())); return fstc_.get(); } const string &GetKey() const final { return impl_->GetKey(); } void Next() final { return impl_->Next(); } void Reset() final { impl_->Reset(); } FarType Type() const final { return impl_->Type(); } const FarReader *GetImpl() const { return impl_.get(); } FarReader *GetImpl() { return impl_.get(); } private: std::unique_ptr> impl_; mutable std::unique_ptr fstc_; }; class FarReaderClass; using OpenFarReaderClassArgs = WithReturnValue &>; // Untemplated user-facing class holding a templated pimpl. class FarReaderClass { public: const string &ArcType() const { return impl_->ArcType(); } bool Done() const { return impl_->Done(); } // Returns True if the impl is null (i.e., due to read failure). // Attempting to call any other function will result in null dereference. bool Error() const { return (impl_) ? impl_->Error() : true; } bool Find(const string &key) { return impl_->Find(key); } const FstClass *GetFstClass() const { return impl_->GetFstClass(); } const string &GetKey() const { return impl_->GetKey(); } void Next() { impl_->Next(); } void Reset() { impl_->Reset(); } FarType Type() const { return impl_->Type(); } template const FarReader *GetFarReader() const { if (Arc::Type() != ArcType()) return nullptr; const FarReaderClassImpl *typed_impl = static_cast *>(impl_.get()); return typed_impl->GetImpl(); } template FarReader *GetFarReader() { if (Arc::Type() != ArcType()) return nullptr; FarReaderClassImpl *typed_impl = static_cast *>(impl_.get()); return typed_impl->GetImpl(); } template friend void OpenFarReaderClass(OpenFarReaderClassArgs *args); // Defined in the CC. static FarReaderClass *Open(const string &filename); static FarReaderClass *Open(const std::vector &filenames); private: template explicit FarReaderClass(FarReaderClassImpl *impl) : impl_(impl) {} std::unique_ptr impl_; }; // These exist solely for registration purposes; users should call the // static method FarReaderClass::Open instead. template void OpenFarReaderClass(OpenFarReaderClassArgs *args) { args->retval = new FarReaderClass(new FarReaderClassImpl(args->args)); } // FarWriter API. // Virtual interface implemented by each concrete FarWriterImpl. class FarWriterImplBase { public: // Unlike the lower-level library, this returns a boolean to signal failure // due to non-conformant arc types. virtual bool Add(const string &key, const FstClass &fst) = 0; virtual const string &ArcType() const = 0; virtual bool Error() const = 0; virtual FarType Type() const = 0; virtual ~FarWriterImplBase() {} }; // Templated implementation. template class FarWriterClassImpl : public FarWriterImplBase { public: explicit FarWriterClassImpl(const string &filename, FarType type = FAR_DEFAULT) : impl_(FarWriter::Create(filename, type)) {} bool Add(const string &key, const FstClass &fst) final { if (ArcType() != fst.ArcType()) { FSTERROR() << "Cannot write FST with " << fst.ArcType() << " arcs to " << "FAR with " << ArcType() << " arcs"; return false; } impl_->Add(key, *(fst.GetFst())); return true; } const string &ArcType() const final { return Arc::Type(); } bool Error() const final { return impl_->Error(); } FarType Type() const final { return impl_->Type(); } const FarWriter *GetImpl() const { return impl_.get(); } FarWriter *GetImpl() { return impl_.get(); } private: std::unique_ptr> impl_; }; class FarWriterClass; using CreateFarWriterClassInnerArgs = std::pair; using CreateFarWriterClassArgs = WithReturnValue; // Untemplated user-facing class holding a templated pimpl. class FarWriterClass { public: static FarWriterClass *Create(const string &filename, const string &arc_type, FarType type = FAR_DEFAULT); bool Add(const string &key, const FstClass &fst) { return impl_->Add(key, fst); } // Returns True if the impl is null (i.e., due to construction failure). // Attempting to call any other function will result in null dereference. bool Error() const { return (impl_) ? impl_->Error() : true; } const string &ArcType() const { return impl_->ArcType(); } FarType Type() const { return impl_->Type(); } template const FarWriter *GetFarWriter() const { if (Arc::Type() != ArcType()) return nullptr; const FarWriterClassImpl *typed_impl = static_cast *>(impl_.get()); return typed_impl->GetImpl(); } template FarWriter *GetFarWriter() { if (Arc::Type() != ArcType()) return nullptr; FarWriterClassImpl *typed_impl = static_cast *>(impl_.get()); return typed_impl->GetImpl(); } template friend void CreateFarWriterClass(CreateFarWriterClassArgs *args); private: template explicit FarWriterClass(FarWriterClassImpl *impl) : impl_(impl) {} std::unique_ptr impl_; }; // This exists solely for registration purposes; users should call the // static method FarWriterClass::Create instead. template void CreateFarWriterClass(CreateFarWriterClassArgs *args) { args->retval = new FarWriterClass(new FarWriterClassImpl( std::get<0>(args->args), std::get<1>(args->args))); } } // namespace script } // namespace fst #endif // FST_EXTENSIONS_FAR_FAR_CLASS_H_