00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef FST_LIB_ADD_ON_FST_H__
00024 #define FST_LIB_ADD_ON_FST_H__
00025
00026 #include <fst/fst.h>
00027 #include <fst/add-on.h>
00028
00029 namespace fst {
00030
00031
00032 static const int32 kAddOnMagicNumber = 446681434;
00033
00034
00035
00036
00037
00038
00039
00040 class NullAddOn {
00041 public:
00042 NullAddOn() {}
00043
00044 static NullAddOn *Read(istream &istrm) {
00045 return new NullAddOn();
00046 };
00047
00048 bool Write(ostream &ostrm) const { return true; }
00049
00050 int RefCount() const { return ref_count_.count(); }
00051 int IncrRefCount() { return ref_count_.Incr(); }
00052 int DecrRefCount() { return ref_count_.Decr(); }
00053
00054 private:
00055 RefCounter ref_count_;
00056
00057 DISALLOW_COPY_AND_ASSIGN(NullAddOn);
00058 };
00059
00060
00061
00062 template <class A1, class A2>
00063 class AddOnPair {
00064 public:
00065
00066 AddOnPair(A1 *a1, A2 *a2)
00067 : a1_(a1), a2_(a2) {
00068 if (a1_)
00069 a1_->IncrRefCount();
00070 if (a2_)
00071 a2_->IncrRefCount();
00072 }
00073
00074 ~AddOnPair() {
00075 if (a1_ && !a1_->DecrRefCount())
00076 delete a1_;
00077 if (a2_ && !a2_->DecrRefCount())
00078 delete a2_;
00079 }
00080
00081 A1 *First() const { return a1_; }
00082 A2 *Second() const { return a2_; }
00083
00084 static AddOnPair<A1, A2> *Read(istream &istrm) {
00085 A1 *a1 = 0;
00086 bool have_addon1 = false;
00087 ReadType(istrm, &have_addon1);
00088 if (have_addon1)
00089 a1 = A1::Read(istrm);
00090
00091 A2 *a2 = 0;
00092 bool have_addon2 = false;
00093 ReadType(istrm, &have_addon2);
00094 if (have_addon2)
00095 a2 = A2::Read(istrm);
00096
00097 AddOnPair<A1, A2> *a = new AddOnPair<A1, A2>(a1, a2);
00098 if (a1)
00099 a1->DecrRefCount();
00100 if (a2)
00101 a2->DecrRefCount();
00102 return a;
00103 };
00104
00105 bool Write(ostream &ostrm) const {
00106 bool have_addon1 = a1_;
00107 WriteType(ostrm, have_addon1);
00108 if (have_addon1)
00109 a1_->Write(ostrm);
00110 bool have_addon2 = a2_;
00111 WriteType(ostrm, have_addon2);
00112 if (have_addon2)
00113 a2_->Write(ostrm);
00114 return true;
00115 }
00116
00117 int RefCount() const { return ref_count_.count(); }
00118
00119 int IncrRefCount() {
00120 return ref_count_.Incr();
00121 }
00122
00123 int DecrRefCount() {
00124 return ref_count_.Decr();
00125 }
00126
00127 private:
00128 A1 *a1_;
00129 A2 *a2_;
00130 RefCounter ref_count_;
00131
00132 DISALLOW_COPY_AND_ASSIGN(AddOnPair);
00133 };
00134
00135
00136
00137
00138
00139
00140 template<class F, class T>
00141 class AddOnImpl : public FstImpl<typename F::Arc> {
00142 public:
00143 typedef typename F::Arc Arc;
00144 typedef typename Arc::Label Label;
00145 typedef typename Arc::Weight Weight;
00146 typedef typename Arc::StateId StateId;
00147
00148 using FstImpl<Arc>::SetType;
00149 using FstImpl<Arc>::SetProperties;
00150 using FstImpl<Arc>::WriteHeader;
00151
00152
00153 AddOnImpl(const F &fst, const string &type, T *t = 0)
00154 : fst_(fst), t_(t) {
00155 SetType(type);
00156 SetProperties(fst_.Properties(kFstProperties, false));
00157 if (t_)
00158 t_->IncrRefCount();
00159 }
00160
00161
00162 AddOnImpl(const Fst<Arc> &fst, const string &type, T *t = 0)
00163 : fst_(fst), t_(t) {
00164 SetType(type);
00165 SetProperties(fst_.Properties(kFstProperties, false));
00166 if (t_)
00167 t_->IncrRefCount();
00168 }
00169
00170 AddOnImpl(const AddOnImpl<F, T> &impl)
00171 : fst_(impl.fst_), t_(impl.t_) {
00172 SetType(impl.Type());
00173 SetProperties(fst_.Properties(kCopyProperties, false));
00174 if (t_)
00175 t_->IncrRefCount();
00176 }
00177
00178 ~AddOnImpl() {
00179 if (t_ && !t_->DecrRefCount())
00180 delete t_;
00181 }
00182
00183 StateId Start() const { return fst_.Start(); }
00184 Weight Final(StateId s) const { return fst_.Final(s); }
00185 size_t NumArcs(StateId s) const { return fst_.NumArcs(s); }
00186
00187 size_t NumInputEpsilons(StateId s) const {
00188 return fst_.NumInputEpsilons(s);
00189 }
00190
00191 size_t NumOutputEpsilons(StateId s) const {
00192 return fst_.NumOutputEpsilons(s);
00193 }
00194
00195 size_t NumStates() const { return fst_.NumStates(); }
00196
00197 static AddOnImpl<F, T> *Read(istream &strm, const FstReadOptions &opts) {
00198 FstReadOptions nopts(opts);
00199 FstHeader hdr;
00200 if (!nopts.header) {
00201 hdr.Read(strm, nopts.source);
00202 nopts.header = &hdr;
00203 }
00204 AddOnImpl<F, T> *impl = new AddOnImpl<F, T>(nopts.header->FstType());
00205 if (!impl->ReadHeader(strm, nopts, kMinFileVersion, &hdr))
00206 return 0;
00207 delete impl;
00208
00209 int32 magic_number = 0;
00210 ReadType(strm, &magic_number);
00211 if (magic_number != kAddOnMagicNumber) {
00212 LOG(ERROR) << "AddOnImpl::Read: Bad add-on header: " << nopts.source;
00213 return 0;
00214 }
00215
00216 FstReadOptions fopts(opts);
00217 fopts.header = 0;
00218 F *fst = F::Read(strm, fopts);
00219 if (!fst)
00220 return 0;
00221
00222 T *t = 0;
00223 bool have_addon = false;
00224 ReadType(strm, &have_addon);
00225 if (have_addon) {
00226 t = T::Read(strm);
00227 if (!t)
00228 return 0;
00229 }
00230 impl = new AddOnImpl<F, T>(*fst, nopts.header->FstType(), t);
00231 delete fst;
00232 if (t)
00233 t->DecrRefCount();
00234 return impl;
00235 }
00236
00237 bool Write(ostream &strm, const FstWriteOptions &opts) const {
00238 FstHeader hdr;
00239 FstWriteOptions nopts(opts);
00240 nopts.write_isymbols = false;
00241 nopts.write_osymbols = false;
00242 WriteHeader(strm, nopts, kFileVersion, &hdr);
00243 WriteType(strm, kAddOnMagicNumber);
00244 FstWriteOptions fopts(opts);
00245 fopts.write_header = true;
00246 if (!fst_.Write(strm, fopts))
00247 return false;
00248 bool have_addon = t_;
00249 WriteType(strm, have_addon);
00250 if (have_addon)
00251 t_->Write(strm);
00252 return true;
00253 }
00254
00255 void InitStateIterator(StateIteratorData<Arc> *data) const {
00256 fst_.InitStateIterator(data);
00257 }
00258
00259 void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const {
00260 fst_.InitArcIterator(s, data);
00261 }
00262
00263 F &GetFst() { return fst_; }
00264
00265 const F &GetFst() const { return fst_; }
00266
00267 T *GetAddOn() const { return t_; }
00268
00269
00270 void SetAddOn(T *t) {
00271 if (t == t_)
00272 return;
00273 if (t_ && !t_->DecrRefCount())
00274 delete t_;
00275 t_ = t;
00276 if (t_)
00277 t_->IncrRefCount();
00278 }
00279
00280 private:
00281 explicit AddOnImpl(const string &type) : t_(0) {
00282 SetType(type);
00283 SetProperties(kExpanded);
00284 }
00285
00286
00287 static const int kFileVersion = 1;
00288
00289 static const int kMinFileVersion = 1;
00290
00291 F fst_;
00292 T *t_;
00293
00294 void operator=(const AddOnImpl<F, T> &fst);
00295 };
00296
00297 template <class F, class T> const int AddOnImpl<F, T>::kFileVersion;
00298 template <class F, class T> const int AddOnImpl<F, T>::kMinFileVersion;
00299
00300
00301 }
00302
00303 #endif /// FST_LIB_ADD_ON_FST_H__
00304