1 // register.h 2 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Copyright 2005-2010 Google, Inc. 16 // Author: riley (at) google.com (Michael Riley), jpr (at) google.com (Jake Ratkiewicz) 17 // 18 // \file 19 // Classes for registering derived Fsts for generic reading 20 // 21 22 #ifndef FST_LIB_REGISTER_H__ 23 #define FST_LIB_REGISTER_H__ 24 25 #include <string> 26 27 28 #include <fst/compat.h> 29 #include <iostream> 30 #include <fstream> 31 #include <sstream> 32 #include <fst/util.h> 33 #include <fst/generic-register.h> 34 35 36 #include <fst/types.h> 37 38 namespace fst { 39 40 template <class A> class Fst; 41 struct FstReadOptions; 42 43 // This class represents a single entry in a FstRegister 44 template<class A> 45 struct FstRegisterEntry { 46 typedef Fst<A> *(*Reader)(istream &strm, const FstReadOptions &opts); 47 typedef Fst<A> *(*Converter)(const Fst<A> &fst); 48 49 Reader reader; 50 Converter converter; 51 FstRegisterEntry() : reader(0), converter(0) {} 52 FstRegisterEntry(Reader r, Converter c) : reader(r), converter(c) { } 53 }; 54 55 // This class maintains the correspondence between a string describing 56 // an FST type, and its reader and converter. 57 template<class A> 58 class FstRegister : public GenericRegister<string, FstRegisterEntry<A>, 59 FstRegister<A> > { 60 public: 61 typedef typename FstRegisterEntry<A>::Reader Reader; 62 typedef typename FstRegisterEntry<A>::Converter Converter; 63 64 const Reader GetReader(const string &type) const { 65 return this->GetEntry(type).reader; 66 } 67 68 const Converter GetConverter(const string &type) const { 69 return this->GetEntry(type).converter; 70 } 71 72 protected: 73 virtual string ConvertKeyToSoFilename(const string& key) const { 74 string legal_type(key); 75 76 ConvertToLegalCSymbol(&legal_type); 77 78 return legal_type + "-fst.so"; 79 } 80 }; 81 82 83 // This class registers an Fst type for generic reading and creating. 84 // The Fst type must have a default constructor and a copy constructor 85 // from 'Fst<Arc>' for this to work. 86 template <class F> 87 class FstRegisterer 88 : public GenericRegisterer<FstRegister<typename F::Arc> > { 89 public: 90 typedef typename F::Arc Arc; 91 typedef typename FstRegister<Arc>::Entry Entry; 92 typedef typename FstRegister<Arc>::Reader Reader; 93 94 FstRegisterer() : 95 GenericRegisterer<FstRegister<typename F::Arc> >( 96 F().Type(), BuildEntry()) { } 97 98 private: 99 Entry BuildEntry() { 100 F *(*reader)(istream &strm, 101 const FstReadOptions &opts) = &F::Read; 102 103 return Entry(reinterpret_cast<Reader>(reader), 104 &FstRegisterer<F>::Convert); 105 } 106 107 static Fst<Arc> *Convert(const Fst<Arc> &fst) { return new F(fst); } 108 }; 109 110 111 // Convenience macro to generate static FstRegisterer instance. 112 #define REGISTER_FST(F, A) \ 113 static fst::FstRegisterer< F<A> > F ## _ ## A ## _registerer 114 115 116 // Converts an fst to type 'type'. 117 template <class A> 118 Fst<A> *Convert(const Fst<A> &fst, const string &ftype) { 119 FstRegister<A> *registr = FstRegister<A>::GetRegister(); 120 const typename FstRegister<A>::Converter 121 converter = registr->GetConverter(ftype); 122 if (!converter) { 123 string atype = A::Type(); 124 LOG(ERROR) << "Fst::Convert: Unknown FST type \"" << ftype 125 << "\" (arc type = \"" << atype << "\")"; 126 return 0; 127 } 128 return converter(fst); 129 } 130 131 } // namespace fst 132 133 #endif // FST_LIB_REGISTER_H__ 134