register.h revision f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2
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