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@google.com (Michael Riley), jpr@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 <fst/util.h> 32#include <fst/generic-register.h> 33 34 35#include <fst/types.h> 36 37namespace fst { 38 39template <class A> class Fst; 40struct FstReadOptions; 41 42// This class represents a single entry in a FstRegister 43template<class A> 44struct FstRegisterEntry { 45 typedef Fst<A> *(*Reader)(istream &strm, const FstReadOptions &opts); 46 typedef Fst<A> *(*Converter)(const Fst<A> &fst); 47 48 Reader reader; 49 Converter converter; 50 FstRegisterEntry() : reader(0), converter(0) {} 51 FstRegisterEntry(Reader r, Converter c) : reader(r), converter(c) { } 52}; 53 54// This class maintains the correspondence between a string describing 55// an FST type, and its reader and converter. 56template<class A> 57class FstRegister : public GenericRegister<string, FstRegisterEntry<A>, 58 FstRegister<A> > { 59 public: 60 typedef typename FstRegisterEntry<A>::Reader Reader; 61 typedef typename FstRegisterEntry<A>::Converter Converter; 62 63 const Reader GetReader(const string &type) const { 64 return this->GetEntry(type).reader; 65 } 66 67 const Converter GetConverter(const string &type) const { 68 return this->GetEntry(type).converter; 69 } 70 71 protected: 72 virtual string ConvertKeyToSoFilename(const string& key) const { 73 string legal_type(key); 74 75 ConvertToLegalCSymbol(&legal_type); 76 77 return legal_type + "-fst.so"; 78 } 79}; 80 81 82// This class registers an Fst type for generic reading and creating. 83// The Fst type must have a default constructor and a copy constructor 84// from 'Fst<Arc>' for this to work. 85template <class F> 86class FstRegisterer 87 : public GenericRegisterer<FstRegister<typename F::Arc> > { 88 public: 89 typedef typename F::Arc Arc; 90 typedef typename FstRegister<Arc>::Entry Entry; 91 typedef typename FstRegister<Arc>::Reader Reader; 92 93 FstRegisterer() : 94 GenericRegisterer<FstRegister<typename F::Arc> >( 95 F().Type(), BuildEntry()) { } 96 97 private: 98 Entry BuildEntry() { 99 F *(*reader)(istream &strm, 100 const FstReadOptions &opts) = &F::Read; 101 102 return Entry(reinterpret_cast<Reader>(reader), 103 &FstRegisterer<F>::Convert); 104 } 105 106 static Fst<Arc> *Convert(const Fst<Arc> &fst) { return new F(fst); } 107}; 108 109 110// Convenience macro to generate static FstRegisterer instance. 111#define REGISTER_FST(F, A) \ 112static fst::FstRegisterer< F<A> > F ## _ ## A ## _registerer 113 114 115// Converts an fst to type 'type'. 116template <class A> 117Fst<A> *Convert(const Fst<A> &fst, const string &ftype) { 118 FstRegister<A> *registr = FstRegister<A>::GetRegister(); 119 const typename FstRegister<A>::Converter 120 converter = registr->GetConverter(ftype); 121 if (!converter) { 122 string atype = A::Type(); 123 LOG(ERROR) << "Fst::Convert: Unknown FST type \"" << ftype 124 << "\" (arc type = \"" << atype << "\")"; 125 return 0; 126 } 127 return converter(fst); 128} 129 130} // namespace fst 131 132#endif // FST_LIB_REGISTER_H__ 133