| // register.h |
| |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| // Copyright 2005-2010 Google, Inc. |
| // Author: riley@google.com (Michael Riley), jpr@google.com (Jake Ratkiewicz) |
| // |
| // \file |
| // Classes for registering derived Fsts for generic reading |
| // |
| |
| #ifndef FST_LIB_REGISTER_H__ |
| #define FST_LIB_REGISTER_H__ |
| |
| #include <string> |
| |
| |
| #include <fst/compat.h> |
| #include <iostream> |
| #include <fstream> |
| #include <sstream> |
| #include <fst/util.h> |
| #include <fst/generic-register.h> |
| |
| |
| #include <fst/types.h> |
| |
| namespace fst { |
| |
| template <class A> class Fst; |
| struct FstReadOptions; |
| |
| // This class represents a single entry in a FstRegister |
| template<class A> |
| struct FstRegisterEntry { |
| typedef Fst<A> *(*Reader)(istream &strm, const FstReadOptions &opts); |
| typedef Fst<A> *(*Converter)(const Fst<A> &fst); |
| |
| Reader reader; |
| Converter converter; |
| FstRegisterEntry() : reader(0), converter(0) {} |
| FstRegisterEntry(Reader r, Converter c) : reader(r), converter(c) { } |
| }; |
| |
| // This class maintains the correspondence between a string describing |
| // an FST type, and its reader and converter. |
| template<class A> |
| class FstRegister : public GenericRegister<string, FstRegisterEntry<A>, |
| FstRegister<A> > { |
| public: |
| typedef typename FstRegisterEntry<A>::Reader Reader; |
| typedef typename FstRegisterEntry<A>::Converter Converter; |
| |
| const Reader GetReader(const string &type) const { |
| return this->GetEntry(type).reader; |
| } |
| |
| const Converter GetConverter(const string &type) const { |
| return this->GetEntry(type).converter; |
| } |
| |
| protected: |
| virtual string ConvertKeyToSoFilename(const string& key) const { |
| string legal_type(key); |
| |
| ConvertToLegalCSymbol(&legal_type); |
| |
| return legal_type + "-fst.so"; |
| } |
| }; |
| |
| |
| // This class registers an Fst type for generic reading and creating. |
| // The Fst type must have a default constructor and a copy constructor |
| // from 'Fst<Arc>' for this to work. |
| template <class F> |
| class FstRegisterer |
| : public GenericRegisterer<FstRegister<typename F::Arc> > { |
| public: |
| typedef typename F::Arc Arc; |
| typedef typename FstRegister<Arc>::Entry Entry; |
| typedef typename FstRegister<Arc>::Reader Reader; |
| |
| FstRegisterer() : |
| GenericRegisterer<FstRegister<typename F::Arc> >( |
| F().Type(), BuildEntry()) { } |
| |
| private: |
| Entry BuildEntry() { |
| F *(*reader)(istream &strm, |
| const FstReadOptions &opts) = &F::Read; |
| |
| return Entry(reinterpret_cast<Reader>(reader), |
| &FstRegisterer<F>::Convert); |
| } |
| |
| static Fst<Arc> *Convert(const Fst<Arc> &fst) { return new F(fst); } |
| }; |
| |
| |
| // Convenience macro to generate static FstRegisterer instance. |
| #define REGISTER_FST(F, A) \ |
| static fst::FstRegisterer< F<A> > F ## _ ## A ## _registerer |
| |
| |
| // Converts an fst to type 'type'. |
| template <class A> |
| Fst<A> *Convert(const Fst<A> &fst, const string &ftype) { |
| FstRegister<A> *registr = FstRegister<A>::GetRegister(); |
| const typename FstRegister<A>::Converter |
| converter = registr->GetConverter(ftype); |
| if (!converter) { |
| string atype = A::Type(); |
| LOG(ERROR) << "Fst::Convert: Unknown FST type \"" << ftype |
| << "\" (arc type = \"" << atype << "\")"; |
| return 0; |
| } |
| return converter(fst); |
| } |
| |
| } // namespace fst |
| |
| #endif // FST_LIB_REGISTER_H__ |