diff options
author | Determinant <[email protected]> | 2015-08-14 11:51:42 +0800 |
---|---|---|
committer | Determinant <[email protected]> | 2015-08-14 11:51:42 +0800 |
commit | 96a32415ab43377cf1575bd3f4f2980f58028209 (patch) | |
tree | 30a2d92d73e8f40ac87b79f6f56e227bfc4eea6e /kaldi_io/src/tools/openfst/include/fst/add-on.h | |
parent | c177a7549bd90670af4b29fa813ddea32cfe0f78 (diff) |
add implementation for kaldi io (by ymz)
Diffstat (limited to 'kaldi_io/src/tools/openfst/include/fst/add-on.h')
-rw-r--r-- | kaldi_io/src/tools/openfst/include/fst/add-on.h | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/kaldi_io/src/tools/openfst/include/fst/add-on.h b/kaldi_io/src/tools/openfst/include/fst/add-on.h new file mode 100644 index 0000000..ee21a93 --- /dev/null +++ b/kaldi_io/src/tools/openfst/include/fst/add-on.h @@ -0,0 +1,306 @@ +// add-on.h + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright 2005-2010 Google, Inc. +// Author: [email protected] (Michael Riley) +// +// \file +// Fst implementation class to attach an arbitrary object with a +// read/write method to an FST and its file rep. The FST is given a +// new type name. + +#ifndef FST_LIB_ADD_ON_FST_H__ +#define FST_LIB_ADD_ON_FST_H__ + +#include <stddef.h> +#include <string> + +#include <fst/fst.h> + + +namespace fst { + +// Identifies stream data as an add-on fst. +static const int32 kAddOnMagicNumber = 446681434; + + +// +// Some useful add-on objects. +// + +// Nothing to save. +class NullAddOn { + public: + NullAddOn() {} + + static NullAddOn *Read(istream &istrm) { + return new NullAddOn(); + }; + + bool Write(ostream &ostrm) const { return true; } + + int RefCount() const { return ref_count_.count(); } + int IncrRefCount() { return ref_count_.Incr(); } + int DecrRefCount() { return ref_count_.Decr(); } + + private: + RefCounter ref_count_; + + DISALLOW_COPY_AND_ASSIGN(NullAddOn); +}; + + +// Create a new add-on from a pair of add-ons. +template <class A1, class A2> +class AddOnPair { + public: + // Argument reference count incremented. + AddOnPair(A1 *a1, A2 *a2) + : a1_(a1), a2_(a2) { + if (a1_) + a1_->IncrRefCount(); + if (a2_) + a2_->IncrRefCount(); + } + + ~AddOnPair() { + if (a1_ && !a1_->DecrRefCount()) + delete a1_; + if (a2_ && !a2_->DecrRefCount()) + delete a2_; + } + + A1 *First() const { return a1_; } + A2 *Second() const { return a2_; } + + static AddOnPair<A1, A2> *Read(istream &istrm) { + A1 *a1 = 0; + bool have_addon1 = false; + ReadType(istrm, &have_addon1); + if (have_addon1) + a1 = A1::Read(istrm); + + A2 *a2 = 0; + bool have_addon2 = false; + ReadType(istrm, &have_addon2); + if (have_addon2) + a2 = A2::Read(istrm); + + AddOnPair<A1, A2> *a = new AddOnPair<A1, A2>(a1, a2); + if (a1) + a1->DecrRefCount(); + if (a2) + a2->DecrRefCount(); + return a; + }; + + bool Write(ostream &ostrm) const { + bool have_addon1 = a1_; + WriteType(ostrm, have_addon1); + if (have_addon1) + a1_->Write(ostrm); + bool have_addon2 = a2_; + WriteType(ostrm, have_addon2); + if (have_addon2) + a2_->Write(ostrm); + return true; + } + + int RefCount() const { return ref_count_.count(); } + + int IncrRefCount() { + return ref_count_.Incr(); + } + + int DecrRefCount() { + return ref_count_.Decr(); + } + + private: + A1 *a1_; + A2 *a2_; + RefCounter ref_count_; + + DISALLOW_COPY_AND_ASSIGN(AddOnPair); +}; + + +// Add to an Fst F a type T object. T must have a 'T* Read(istream &)', +// a 'bool Write(ostream &)' method, and 'int RecCount(), 'int IncrRefCount()' +// and 'int DecrRefCount()' methods (e.g. 'MatcherData' in matcher-fst.h). +// The result is a new Fst implemenation with type name 'type'. +template<class F, class T> +class AddOnImpl : public FstImpl<typename F::Arc> { + public: + typedef typename F::Arc Arc; + typedef typename Arc::Label Label; + typedef typename Arc::Weight Weight; + typedef typename Arc::StateId StateId; + + using FstImpl<Arc>::SetType; + using FstImpl<Arc>::SetProperties; + using FstImpl<Arc>::WriteHeader; + + // If 't' is non-zero, its reference count is incremented. + AddOnImpl(const F &fst, const string &type, T *t = 0) + : fst_(fst), t_(t) { + SetType(type); + SetProperties(fst_.Properties(kFstProperties, false)); + if (t_) + t_->IncrRefCount(); + } + + // If 't' is non-zero, its reference count is incremented. + AddOnImpl(const Fst<Arc> &fst, const string &type, T *t = 0) + : fst_(fst), t_(t) { + SetType(type); + SetProperties(fst_.Properties(kFstProperties, false)); + if (t_) + t_->IncrRefCount(); + } + + AddOnImpl(const AddOnImpl<F, T> &impl) + : fst_(impl.fst_), t_(impl.t_) { + SetType(impl.Type()); + SetProperties(fst_.Properties(kCopyProperties, false)); + if (t_) + t_->IncrRefCount(); + } + + ~AddOnImpl() { + if (t_ && !t_->DecrRefCount()) + delete t_; + } + + StateId Start() const { return fst_.Start(); } + Weight Final(StateId s) const { return fst_.Final(s); } + size_t NumArcs(StateId s) const { return fst_.NumArcs(s); } + + size_t NumInputEpsilons(StateId s) const { + return fst_.NumInputEpsilons(s); + } + + size_t NumOutputEpsilons(StateId s) const { + return fst_.NumOutputEpsilons(s); + } + + size_t NumStates() const { return fst_.NumStates(); } + + static AddOnImpl<F, T> *Read(istream &strm, const FstReadOptions &opts) { + FstReadOptions nopts(opts); + FstHeader hdr; + if (!nopts.header) { + hdr.Read(strm, nopts.source); + nopts.header = &hdr; + } + AddOnImpl<F, T> *impl = new AddOnImpl<F, T>(nopts.header->FstType()); + if (!impl->ReadHeader(strm, nopts, kMinFileVersion, &hdr)) + return 0; + delete impl; // Used here only for checking types. + + int32 magic_number = 0; + ReadType(strm, &magic_number); // Ensures this is an add-on Fst. + if (magic_number != kAddOnMagicNumber) { + LOG(ERROR) << "AddOnImpl::Read: Bad add-on header: " << nopts.source; + return 0; + } + + FstReadOptions fopts(opts); + fopts.header = 0; // Contained header was written out. + F *fst = F::Read(strm, fopts); + if (!fst) + return 0; + + T *t = 0; + bool have_addon = false; + ReadType(strm, &have_addon); + if (have_addon) { // Read add-on object if present. + t = T::Read(strm); + if (!t) + return 0; + } + impl = new AddOnImpl<F, T>(*fst, nopts.header->FstType(), t); + delete fst; + if (t) + t->DecrRefCount(); + return impl; + } + + bool Write(ostream &strm, const FstWriteOptions &opts) const { + FstHeader hdr; + FstWriteOptions nopts(opts); + nopts.write_isymbols = false; // Let contained FST hold any symbols. + nopts.write_osymbols = false; + WriteHeader(strm, nopts, kFileVersion, &hdr); + WriteType(strm, kAddOnMagicNumber); // Ensures this is an add-on Fst. + FstWriteOptions fopts(opts); + fopts.write_header = true; // Force writing contained header. + if (!fst_.Write(strm, fopts)) + return false; + bool have_addon = t_; + WriteType(strm, have_addon); + if (have_addon) // Write add-on object if present. + t_->Write(strm); + return true; + } + + void InitStateIterator(StateIteratorData<Arc> *data) const { + fst_.InitStateIterator(data); + } + + void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const { + fst_.InitArcIterator(s, data); + } + + F &GetFst() { return fst_; } + + const F &GetFst() const { return fst_; } + + T *GetAddOn() const { return t_; } + + // If 't' is non-zero, its reference count is incremented. + void SetAddOn(T *t) { + if (t == t_) + return; + if (t_ && !t_->DecrRefCount()) + delete t_; + t_ = t; + if (t_) + t_->IncrRefCount(); + } + + private: + explicit AddOnImpl(const string &type) : t_(0) { + SetType(type); + SetProperties(kExpanded); + } + + // Current file format version + static const int kFileVersion = 1; + // Minimum file format version supported + static const int kMinFileVersion = 1; + + F fst_; + T *t_; + + void operator=(const AddOnImpl<F, T> &fst); // Disallow +}; + +template <class F, class T> const int AddOnImpl<F, T>::kFileVersion; +template <class F, class T> const int AddOnImpl<F, T>::kMinFileVersion; + + +} // namespace fst + +#endif // FST_LIB_ADD_ON_FST_H__ |