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