FST  openfst-1.7.3
OpenFst Library
add-on.h
Go to the documentation of this file.
1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
3 //
4 // FST implementation class to attach an arbitrary object with a read/write
5 // method to an FST and its file representation. The FST is given a new type
6 // name.
7 
8 #ifndef FST_ADD_ON_H_
9 #define FST_ADD_ON_H_
10 
11 #include <stddef.h>
12 
13 #include <memory>
14 #include <string>
15 #include <utility>
16 
17 #include <fst/log.h>
18 
19 #include <fst/fst.h>
20 
21 
22 namespace fst {
23 
24 // Identifies stream data as an add-on FST.
25 static constexpr int32 kAddOnMagicNumber = 446681434;
26 
27 // Nothing to save.
28 class NullAddOn {
29  public:
30  NullAddOn() {}
31 
32  static NullAddOn *Read(std::istream &strm, const FstReadOptions &opts) {
33  return new NullAddOn();
34  }
35 
36  bool Write(std::ostream &ostrm, const FstWriteOptions &opts) const {
37  return true;
38  }
39 };
40 
41 // Create a new add-on from a pair of add-ons.
42 template <class A1, class A2>
43 class AddOnPair {
44  public:
45  // Argument reference count incremented.
46  AddOnPair(std::shared_ptr<A1> a1, std::shared_ptr<A2> a2)
47  : a1_(std::move(a1)), a2_(std::move(a2)) {}
48 
49  const A1 *First() const { return a1_.get(); }
50 
51  const A2 *Second() const { return a2_.get(); }
52 
53  std::shared_ptr<A1> SharedFirst() const { return a1_; }
54 
55  std::shared_ptr<A2> SharedSecond() const { return a2_; }
56 
57  static AddOnPair<A1, A2> *Read(std::istream &istrm,
58  const FstReadOptions &opts) {
59  A1 *a1 = nullptr;
60  bool have_addon1 = false;
61  ReadType(istrm, &have_addon1);
62  if (have_addon1) a1 = A1::Read(istrm, opts);
63 
64  A2 *a2 = nullptr;
65  bool have_addon2 = false;
66  ReadType(istrm, &have_addon2);
67  if (have_addon2) a2 = A2::Read(istrm, opts);
68 
69  return new AddOnPair<A1, A2>(std::shared_ptr<A1>(a1),
70  std::shared_ptr<A2>(a2));
71  }
72 
73  bool Write(std::ostream &ostrm, const FstWriteOptions &opts) const {
74  bool have_addon1 = a1_ != nullptr;
75  WriteType(ostrm, have_addon1);
76  if (have_addon1) a1_->Write(ostrm, opts);
77  bool have_addon2 = a2_ != nullptr;
78  WriteType(ostrm, have_addon2);
79  if (have_addon2) a2_->Write(ostrm, opts);
80  return true;
81  }
82 
83  private:
84  std::shared_ptr<A1> a1_;
85  std::shared_ptr<A2> a2_;
86 };
87 
88 namespace internal {
89 
90 // Adds an object of type T to an FST. T must support:
91 //
92 // T* Read(std::istream &);
93 // bool Write(std::ostream &);
94 //
95 // The resulting type is a new FST implementation.
96 template <class FST, class T>
97 class AddOnImpl : public FstImpl<typename FST::Arc> {
98  public:
99  using Arc = typename FST::Arc;
100  using Label = typename Arc::Label;
101  using StateId = typename Arc::StateId;
102  using Weight = typename Arc::Weight;
103 
104  using FstImpl<Arc>::SetType;
109 
110  // We make a thread-safe copy of the FST by default since an FST
111  // implementation is expected to not share mutable data between objects.
112  AddOnImpl(const FST &fst, const std::string &type,
113  std::shared_ptr<T> t = std::shared_ptr<T>())
114  : fst_(fst, true), t_(std::move(t)) {
115  SetType(type);
116  SetProperties(fst_.Properties(kFstProperties, false));
117  SetInputSymbols(fst_.InputSymbols());
118  SetOutputSymbols(fst_.OutputSymbols());
119  }
120 
121  // Conversion from const Fst<Arc> & to F always copies the underlying
122  // implementation.
123  AddOnImpl(const Fst<Arc> &fst, const std::string &type,
124  std::shared_ptr<T> t = std::shared_ptr<T>())
125  : fst_(fst), t_(std::move(t)) {
126  SetType(type);
127  SetProperties(fst_.Properties(kFstProperties, false));
128  SetInputSymbols(fst_.InputSymbols());
129  SetOutputSymbols(fst_.OutputSymbols());
130  }
131 
132  // We make a thread-safe copy of the FST by default since an FST
133  // implementation is expected to not share mutable data between objects.
135  : fst_(impl.fst_, true), t_(impl.t_) {
136  SetType(impl.Type());
137  SetProperties(fst_.Properties(kCopyProperties, false));
138  SetInputSymbols(fst_.InputSymbols());
139  SetOutputSymbols(fst_.OutputSymbols());
140  }
141 
142  StateId Start() const { return fst_.Start(); }
143 
144  Weight Final(StateId s) const { return fst_.Final(s); }
145 
146  size_t NumArcs(StateId s) const { return fst_.NumArcs(s); }
147 
148  size_t NumInputEpsilons(StateId s) const { return fst_.NumInputEpsilons(s); }
149 
150  size_t NumOutputEpsilons(StateId s) const {
151  return fst_.NumOutputEpsilons(s);
152  }
153 
154  size_t NumStates() const { return fst_.NumStates(); }
155 
156  static AddOnImpl<FST, T> *Read(std::istream &strm,
157  const FstReadOptions &opts) {
158  FstReadOptions nopts(opts);
159  FstHeader hdr;
160  if (!nopts.header) {
161  hdr.Read(strm, nopts.source);
162  nopts.header = &hdr;
163  }
164  std::unique_ptr<AddOnImpl<FST, T>> impl(
165  new AddOnImpl<FST, T>(nopts.header->FstType()));
166  if (!impl->ReadHeader(strm, nopts, kMinFileVersion, &hdr)) return nullptr;
167  impl.reset();
168  int32 magic_number = 0;
169  ReadType(strm, &magic_number); // Ensures this is an add-on FST.
170  if (magic_number != kAddOnMagicNumber) {
171  LOG(ERROR) << "AddOnImpl::Read: Bad add-on header: " << nopts.source;
172  return nullptr;
173  }
174  FstReadOptions fopts(opts);
175  fopts.header = nullptr; // Contained header was written out.
176  std::unique_ptr<FST> fst(FST::Read(strm, fopts));
177  if (!fst) return nullptr;
178  std::shared_ptr<T> t;
179  bool have_addon = false;
180  ReadType(strm, &have_addon);
181  if (have_addon) { // Reads add-on object if present.
182  t = std::shared_ptr<T>(T::Read(strm, fopts));
183  if (!t) return nullptr;
184  }
185  return new AddOnImpl<FST, T>(*fst, nopts.header->FstType(), t);
186  }
187 
188  bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
189  FstHeader hdr;
190  FstWriteOptions nopts(opts);
191  nopts.write_isymbols = false; // Allows contained FST to hold any symbols.
192  nopts.write_osymbols = false;
193  WriteHeader(strm, nopts, kFileVersion, &hdr);
194  WriteType(strm, kAddOnMagicNumber); // Ensures this is an add-on FST.
195  FstWriteOptions fopts(opts);
196  fopts.write_header = true; // Forces writing contained header.
197  if (!fst_.Write(strm, fopts)) return false;
198  bool have_addon = !!t_;
199  WriteType(strm, have_addon);
200  // Writes add-on object if present.
201  if (have_addon) t_->Write(strm, opts);
202  return true;
203  }
204 
206  fst_.InitStateIterator(data);
207  }
208 
210  fst_.InitArcIterator(s, data);
211  }
212 
213  FST &GetFst() { return fst_; }
214 
215  const FST &GetFst() const { return fst_; }
216 
217  const T *GetAddOn() const { return t_.get(); }
218 
219  std::shared_ptr<T> GetSharedAddOn() const { return t_; }
220 
221  void SetAddOn(std::shared_ptr<T> t) { t_ = t; }
222 
223  private:
224  explicit AddOnImpl(const std::string &type) : t_() {
225  SetType(type);
226  SetProperties(kExpanded);
227  }
228 
229  // Current file format version.
230  static constexpr int kFileVersion = 1;
231  // Minimum file format version supported.
232  static constexpr int kMinFileVersion = 1;
233 
234  FST fst_;
235  std::shared_ptr<T> t_;
236 
237  AddOnImpl &operator=(const AddOnImpl &) = delete;
238 };
239 
240 template <class FST, class T>
241 constexpr int AddOnImpl<FST, T>::kFileVersion;
242 
243 template <class FST, class T>
245 
246 } // namespace internal
247 } // namespace fst
248 
249 #endif // FST_ADD_ON_H_
bool Read(std::istream &strm, const std::string &source, bool rewind=false)
Definition: fst.cc:58
const FstHeader * header
Definition: fst.h:57
void InitStateIterator(StateIteratorData< Arc > *data) const
Definition: add-on.h:205
bool Write(std::ostream &strm, const FstWriteOptions &opts) const
Definition: add-on.h:188
std::shared_ptr< A2 > SharedSecond() const
Definition: add-on.h:55
std::string source
Definition: fst.h:56
bool Write(std::ostream &ostrm, const FstWriteOptions &opts) const
Definition: add-on.h:36
static AddOnPair< A1, A2 > * Read(std::istream &istrm, const FstReadOptions &opts)
Definition: add-on.h:57
#define LOG(type)
Definition: log.h:46
SetType
Definition: set-weight.h:36
constexpr uint64 kFstProperties
Definition: properties.h:308
constexpr uint64 kCopyProperties
Definition: properties.h:145
std::shared_ptr< A1 > SharedFirst() const
Definition: add-on.h:53
constexpr uint64 kExpanded
Definition: properties.h:28
void InitArcIterator(StateId s, ArcIteratorData< Arc > *data) const
Definition: add-on.h:209
std::ostream & WriteType(std::ostream &strm, const T t)
Definition: util.h:155
size_t NumOutputEpsilons(StateId s) const
Definition: add-on.h:150
const std::string & FstType() const
Definition: fst.h:119
AddOnImpl(const FST &fst, const std::string &type, std::shared_ptr< T > t=std::shared_ptr< T >())
Definition: add-on.h:112
AddOnPair(std::shared_ptr< A1 > a1, std::shared_ptr< A2 > a2)
Definition: add-on.h:46
bool write_osymbols
Definition: fst.h:87
size_t NumArcs(StateId s) const
Definition: add-on.h:146
bool write_isymbols
Definition: fst.h:86
StateId Start() const
Definition: add-on.h:142
size_t NumStates() const
Definition: add-on.h:154
std::shared_ptr< T > GetSharedAddOn() const
Definition: add-on.h:219
typename FST::Arc Arc
Definition: add-on.h:99
bool write_header
Definition: fst.h:85
const A2 * Second() const
Definition: add-on.h:51
const std::string & Type() const
Definition: fst.h:663
static AddOnImpl< FST, T > * Read(std::istream &strm, const FstReadOptions &opts)
Definition: add-on.h:156
const A1 * First() const
Definition: add-on.h:49
AddOnImpl(const AddOnImpl< FST, T > &impl)
Definition: add-on.h:134
typename Arc::Weight Weight
Definition: add-on.h:102
const T * GetAddOn() const
Definition: add-on.h:217
int32_t int32
Definition: types.h:26
size_t NumInputEpsilons(StateId s) const
Definition: add-on.h:148
typename Arc::Label Label
Definition: add-on.h:100
std::istream & ReadType(std::istream &strm, T *t)
Definition: util.h:47
bool Write(std::ostream &ostrm, const FstWriteOptions &opts) const
Definition: add-on.h:73
const FST & GetFst() const
Definition: add-on.h:215
static NullAddOn * Read(std::istream &strm, const FstReadOptions &opts)
Definition: add-on.h:32
AddOnImpl(const Fst< Arc > &fst, const std::string &type, std::shared_ptr< T > t=std::shared_ptr< T >())
Definition: add-on.h:123
Weight Final(StateId s) const
Definition: add-on.h:144
void SetAddOn(std::shared_ptr< T > t)
Definition: add-on.h:221
typename Arc::StateId StateId
Definition: add-on.h:101