• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
37 namespace fst {
38 
39 template <class A> class Fst;
40 struct FstReadOptions;
41 
42 // This class represents a single entry in a FstRegister
43 template<class A>
44 struct 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;
FstRegisterEntryFstRegisterEntry50   FstRegisterEntry() : reader(0), converter(0) {}
FstRegisterEntryFstRegisterEntry51   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.
56 template<class A>
57 class 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 
GetReader(const string & type)63   const Reader GetReader(const string &type) const {
64     return this->GetEntry(type).reader;
65   }
66 
GetConverter(const string & type)67   const Converter GetConverter(const string &type) const {
68     return this->GetEntry(type).converter;
69   }
70 
71  protected:
ConvertKeyToSoFilename(const string & key)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.
85 template <class F>
86 class 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 
FstRegisterer()93   FstRegisterer() :
94       GenericRegisterer<FstRegister<typename F::Arc> >(
95           F().Type(), BuildEntry()) {  }
96 
97  private:
BuildEntry()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 
Convert(const Fst<Arc> & fst)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) \
112 static fst::FstRegisterer< F<A> > F ## _ ## A ## _registerer
113 
114 
115 // Converts an fst to type 'type'.
116 template <class A>
Convert(const Fst<A> & fst,const string & ftype)117 Fst<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