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