• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 //
14 // Copyright 2005-2010 Google, Inc.
15 // Author: jpr@google.com (Jake Ratkiewicz)
16 
17 #ifndef FST_SCRIPT_FST_CLASS_H_
18 #define FST_SCRIPT_FST_CLASS_H_
19 
20 #include <string>
21 
22 #include <fst/fst.h>
23 #include <fst/mutable-fst.h>
24 #include <fst/vector-fst.h>
25 #include <iostream>
26 #include <fstream>
27 #include <sstream>
28 
29 // Classes to support "boxing" all existing types of FST arcs in a single
30 // FstClass which hides the arc types. This allows clients to load
31 // and work with FSTs without knowing the arc type.
32 
33 // These classes are only recommended for use in high-level scripting
34 // applications. Most users should use the lower-level templated versions
35 // corresponding to these classes.
36 
37 namespace fst {
38 namespace script {
39 
40 //
41 // Abstract base class defining the set of functionalities implemented
42 // in all impls, and passed through by all bases Below FstClassBase
43 // the class hierarchy bifurcates; FstClassImplBase serves as the base
44 // class for all implementations (of which FstClassImpl is currently
45 // the only one) and FstClass serves as the base class for all
46 // interfaces.
47 //
48 class FstClassBase {
49  public:
50   virtual const string &ArcType() const = 0;
51   virtual const string &FstType() const = 0;
52   virtual const string &WeightType() const = 0;
53   virtual const SymbolTable *InputSymbols() const = 0;
54   virtual const SymbolTable *OutputSymbols() const = 0;
55   virtual bool Write(const string& fname) const = 0;
56   virtual bool Write(ostream &ostr, const FstWriteOptions &opts) const = 0;
57   virtual uint64 Properties(uint64 mask, bool test) const = 0;
~FstClassBase()58   virtual ~FstClassBase() { }
59 };
60 
61 class FstClassImplBase : public FstClassBase {
62  public:
63   virtual FstClassImplBase *Copy() = 0;
64   virtual void SetInputSymbols(SymbolTable *is) = 0;
65   virtual void SetOutputSymbols(SymbolTable *is) = 0;
~FstClassImplBase()66   virtual ~FstClassImplBase() { }
67 };
68 
69 
70 //
71 // CONTAINER CLASS
72 // Wraps an Fst<Arc>, hiding its arc type. Whether this Fst<Arc>
73 // pointer refers to a special kind of FST (e.g. a MutableFst) is
74 // known by the type of interface class that owns the pointer to this
75 // container.
76 //
77 
78 template<class Arc>
79 class FstClassImpl : public FstClassImplBase {
80  public:
81   explicit FstClassImpl(Fst<Arc> *impl,
82                         bool should_own = false) :
83       impl_(should_own ? impl : impl->Copy()) { }
84 
FstClassImpl(const Fst<Arc> & impl)85   explicit FstClassImpl(const Fst<Arc> &impl) : impl_(impl.Copy()) {  }
86 
ArcType()87   virtual const string &ArcType() const {
88     return Arc::Type();
89   }
90 
FstType()91   virtual const string &FstType() const {
92     return impl_->Type();
93   }
94 
WeightType()95   virtual const string &WeightType() const {
96     return Arc::Weight::Type();
97   }
98 
InputSymbols()99   virtual const SymbolTable *InputSymbols() const {
100     return impl_->InputSymbols();
101   }
102 
OutputSymbols()103   virtual const SymbolTable *OutputSymbols() const {
104     return impl_->OutputSymbols();
105   }
106 
107   // Warning: calling this method casts the FST to a mutable FST.
SetInputSymbols(SymbolTable * is)108   virtual void SetInputSymbols(SymbolTable *is) {
109     static_cast<MutableFst<Arc> *>(impl_)->SetInputSymbols(is);
110   }
111 
112   // Warning: calling this method casts the FST to a mutable FST.
SetOutputSymbols(SymbolTable * os)113   virtual void SetOutputSymbols(SymbolTable *os) {
114     static_cast<MutableFst<Arc> *>(impl_)->SetOutputSymbols(os);
115   }
116 
Write(const string & fname)117   virtual bool Write(const string &fname) const {
118     return impl_->Write(fname);
119   }
120 
Write(ostream & ostr,const FstWriteOptions & opts)121   virtual bool Write(ostream &ostr, const FstWriteOptions &opts) const {
122     return impl_->Write(ostr, opts);
123   }
124 
Properties(uint64 mask,bool test)125   virtual uint64 Properties(uint64 mask, bool test) const {
126     return impl_->Properties(mask, test);
127   }
128 
~FstClassImpl()129   virtual ~FstClassImpl() { delete impl_; }
130 
GetImpl()131   Fst<Arc> *GetImpl() const { return impl_; }
132 
GetImpl()133   Fst<Arc> *GetImpl() { return impl_; }
134 
Copy()135   virtual FstClassImpl *Copy() {
136     return new FstClassImpl<Arc>(impl_);
137   }
138 
139  private:
140   Fst<Arc> *impl_;
141 };
142 
143 //
144 // BASE CLASS DEFINITIONS
145 //
146 
147 class MutableFstClass;
148 
149 class FstClass : public FstClassBase {
150  public:
151   template<class Arc>
Read(istream & stream,const FstReadOptions & opts)152   static FstClass *Read(istream &stream,
153                         const FstReadOptions &opts) {
154     if (!opts.header) {
155       FSTERROR() << "FstClass::Read: options header not specified";
156       return 0;
157     }
158     const FstHeader &hdr = *opts.header;
159 
160     if (hdr.Properties() & kMutable) {
161       return ReadTypedFst<MutableFstClass, MutableFst<Arc> >(stream, opts);
162     } else {
163       return ReadTypedFst<FstClass, Fst<Arc> >(stream, opts);
164     }
165   }
166 
FstClass()167   FstClass() : impl_(NULL) {
168   }
169 
170   template<class Arc>
FstClass(const Fst<Arc> & fst)171   explicit FstClass(const Fst<Arc> &fst) : impl_(new FstClassImpl<Arc>(fst)) {
172   }
173 
FstClass(const FstClass & other)174   FstClass(const FstClass &other) : impl_(other.impl_->Copy()) { }
175 
176   FstClass &operator=(const FstClass &other) {
177     delete impl_;
178     impl_ = other.impl_->Copy();
179     return *this;
180   }
181 
182   static FstClass *Read(const string &fname);
183 
184   static FstClass *Read(istream &istr, const string &source);
185 
ArcType()186   virtual const string &ArcType() const {
187     return impl_->ArcType();
188   }
189 
FstType()190   virtual const string& FstType() const {
191     return impl_->FstType();
192   }
193 
InputSymbols()194   virtual const SymbolTable *InputSymbols() const {
195     return impl_->InputSymbols();
196   }
197 
OutputSymbols()198   virtual const SymbolTable *OutputSymbols() const {
199     return impl_->OutputSymbols();
200   }
201 
WeightType()202   virtual const string& WeightType() const {
203     return impl_->WeightType();
204   }
205 
Write(const string & fname)206   virtual bool Write(const string &fname) const {
207     return impl_->Write(fname);
208   }
209 
Write(ostream & ostr,const FstWriteOptions & opts)210   virtual bool Write(ostream &ostr, const FstWriteOptions &opts) const {
211     return impl_->Write(ostr, opts);
212   }
213 
Properties(uint64 mask,bool test)214   virtual uint64 Properties(uint64 mask, bool test) const {
215     return impl_->Properties(mask, test);
216   }
217 
218   template<class Arc>
GetFst()219   const Fst<Arc> *GetFst() const {
220     if (Arc::Type() != ArcType()) {
221       return NULL;
222     } else {
223       FstClassImpl<Arc> *typed_impl = static_cast<FstClassImpl<Arc> *>(impl_);
224       return typed_impl->GetImpl();
225     }
226   }
227 
~FstClass()228   virtual ~FstClass() { delete impl_; }
229 
230   // These methods are required by IO registration
231   template<class Arc>
Convert(const FstClass & other)232   static FstClassImplBase *Convert(const FstClass &other) {
233     LOG(ERROR) << "Doesn't make sense to convert any class to type FstClass.";
234     return 0;
235   }
236 
237   template<class Arc>
Create()238   static FstClassImplBase *Create() {
239     LOG(ERROR) << "Doesn't make sense to create an FstClass with a "
240                << "particular arc type.";
241     return 0;
242   }
243 
244 
245  protected:
FstClass(FstClassImplBase * impl)246   explicit FstClass(FstClassImplBase *impl) : impl_(impl) { }
247 
248   // Generic template method for reading an arc-templated FST of type
249   // UnderlyingT, and returning it wrapped as FstClassT, with appropriate
250   // error checking. Called from arc-templated Read() static methods.
251   template<class FstClassT, class UnderlyingT>
ReadTypedFst(istream & stream,const FstReadOptions & opts)252   static FstClassT* ReadTypedFst(istream &stream,
253                                      const FstReadOptions &opts) {
254     UnderlyingT *u = UnderlyingT::Read(stream, opts);
255     if (!u) {
256       return 0;
257     } else {
258       FstClassT *r = new FstClassT(*u);
259       delete u;
260       return r;
261     }
262   }
263 
GetImpl()264   FstClassImplBase *GetImpl() const { return impl_; }
265 
GetImpl()266   FstClassImplBase *GetImpl() { return impl_; }
267 
268 //  friend ostream &operator<<(ostream&, const FstClass&);
269 
270  private:
271   FstClassImplBase *impl_;
272 };
273 
274 //
275 // Specific types of FstClass with special properties
276 //
277 
278 class MutableFstClass : public FstClass {
279  public:
280   template<class Arc>
MutableFstClass(const MutableFst<Arc> & fst)281   explicit MutableFstClass(const MutableFst<Arc> &fst) :
282       FstClass(fst) { }
283 
284   template<class Arc>
GetMutableFst()285   MutableFst<Arc> *GetMutableFst() {
286     Fst<Arc> *fst = const_cast<Fst<Arc> *>(this->GetFst<Arc>());
287     MutableFst<Arc> *mfst = static_cast<MutableFst<Arc> *>(fst);
288 
289     return mfst;
290   }
291 
292   template<class Arc>
Read(istream & stream,const FstReadOptions & opts)293   static MutableFstClass *Read(istream &stream,
294                                const FstReadOptions &opts) {
295     MutableFst<Arc> *mfst = MutableFst<Arc>::Read(stream, opts);
296     if (!mfst) {
297       return 0;
298     } else {
299       MutableFstClass *retval = new MutableFstClass(*mfst);
300       delete mfst;
301       return retval;
302     }
303   }
304 
Write(const string & fname)305   virtual bool Write(const string &fname) const {
306     return GetImpl()->Write(fname);
307   }
308 
Write(ostream & ostr,const FstWriteOptions & opts)309   virtual bool Write(ostream &ostr, const FstWriteOptions &opts) const {
310     return GetImpl()->Write(ostr, opts);
311   }
312 
313   static MutableFstClass *Read(const string &fname, bool convert = false);
314 
SetInputSymbols(SymbolTable * is)315   virtual void SetInputSymbols(SymbolTable *is) {
316     GetImpl()->SetInputSymbols(is);
317   }
318 
SetOutputSymbols(SymbolTable * os)319   virtual void SetOutputSymbols(SymbolTable *os) {
320     GetImpl()->SetOutputSymbols(os);
321   }
322 
323   // These methods are required by IO registration
324   template<class Arc>
Convert(const FstClass & other)325   static FstClassImplBase *Convert(const FstClass &other) {
326     LOG(ERROR) << "Doesn't make sense to convert any class to type "
327                << "MutableFstClass.";
328     return 0;
329   }
330 
331   template<class Arc>
Create()332   static FstClassImplBase *Create() {
333     LOG(ERROR) << "Doesn't make sense to create a MutableFstClass with a "
334                << "particular arc type.";
335     return 0;
336   }
337 
338  protected:
MutableFstClass(FstClassImplBase * impl)339   explicit MutableFstClass(FstClassImplBase *impl) : FstClass(impl) { }
340 };
341 
342 
343 class VectorFstClass : public MutableFstClass {
344  public:
345   explicit VectorFstClass(const FstClass &other);
346   explicit VectorFstClass(const string &arc_type);
347 
348   template<class Arc>
VectorFstClass(const VectorFst<Arc> & fst)349   explicit VectorFstClass(const VectorFst<Arc> &fst) :
350       MutableFstClass(fst) { }
351 
352   template<class Arc>
Read(istream & stream,const FstReadOptions & opts)353   static VectorFstClass *Read(istream &stream,
354                               const FstReadOptions &opts) {
355     VectorFst<Arc> *vfst = VectorFst<Arc>::Read(stream, opts);
356     if (!vfst) {
357       return 0;
358     } else {
359       VectorFstClass *retval = new VectorFstClass(*vfst);
360       delete vfst;
361       return retval;
362     }
363   }
364 
365   static VectorFstClass *Read(const string &fname);
366 
367   // Converter / creator for known arc types
368   template<class Arc>
Convert(const FstClass & other)369   static FstClassImplBase *Convert(const FstClass &other) {
370     return new FstClassImpl<Arc>(new VectorFst<Arc>(
371         *other.GetFst<Arc>()), true);
372   }
373 
374   template<class Arc>
Create()375   static FstClassImplBase *Create() {
376     return new FstClassImpl<Arc>(new VectorFst<Arc>(), true);
377   }
378 };
379 
380 }  // namespace script
381 }  // namespace fst
382 #endif  // FST_SCRIPT_FST_CLASS_H_
383