Home | History | Annotate | Download | only in fst
      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 <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;
     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.
     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 
     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.
     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 
     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) \
    112 static fst::FstRegisterer< F<A> > F ## _ ## A ## _registerer
    113 
    114 
    115 // Converts an fst to type 'type'.
    116 template <class A>
    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