add-on.h revision f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// add-on.h 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Licensed under the Apache License, Version 2.0 (the "License"); 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// you may not use this file except in compliance with the License. 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// You may obtain a copy of the License at 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// http://www.apache.org/licenses/LICENSE-2.0 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Unless required by applicable law or agreed to in writing, software 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// distributed under the License is distributed on an "AS IS" BASIS, 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// See the License for the specific language governing permissions and 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// limitations under the License. 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Copyright 2005-2010 Google, Inc. 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Author: riley@google.com (Michael Riley) 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// \file 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Fst implementation class to attach an arbitrary object with a 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// read/write method to an FST and its file rep. The FST is given a 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// new type name. 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef FST_LIB_ADD_ON_FST_H__ 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define FST_LIB_ADD_ON_FST_H__ 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <stddef.h> 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <string> 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <fst/fst.h> 307886ad3de1aa523d5c71f1fa9f355dfcb2412d1dreed@google.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace fst { 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Identifies stream data as an add-on fst. 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const int32 kAddOnMagicNumber = 446681434; 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Some useful add-on objects. 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Nothing to save. 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass NullAddOn { 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NullAddOn() {} 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static NullAddOn *Read(istream &istrm) { 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return new NullAddOn(); 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 5004423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com 5104423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com bool Write(ostream &ostrm) const { return true; } 5204423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com 5304423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com int RefCount() const { return ref_count_.count(); } 5404423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com int IncrRefCount() { return ref_count_.Incr(); } 5504423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com int DecrRefCount() { return ref_count_.Decr(); } 5604423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com 5704423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com private: 58cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com RefCounter ref_count_; 59cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 60cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com DISALLOW_COPY_AND_ASSIGN(NullAddOn); 61cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com}; 6204423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com 6304423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com 6404423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com// Create a new add-on from a pair of add-ons. 6504423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.comtemplate <class A1, class A2> 6604423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.comclass AddOnPair { 6704423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com public: 6804423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com // Argument reference count incremented. 6904423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com AddOnPair(A1 *a1, A2 *a2) 7004423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com : a1_(a1), a2_(a2) { 713a52d68b4001afd8c7036e80558fba7c87f45a0cbsalomon@google.com if (a1_) 723a52d68b4001afd8c7036e80558fba7c87f45a0cbsalomon@google.com a1_->IncrRefCount(); 733a52d68b4001afd8c7036e80558fba7c87f45a0cbsalomon@google.com if (a2_) 743a52d68b4001afd8c7036e80558fba7c87f45a0cbsalomon@google.com a2_->IncrRefCount(); 7504423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com } 7604423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com 7704423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com ~AddOnPair() { 7804423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com if (a1_ && !a1_->DecrRefCount()) 7904423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com delete a1_; 80fffb2f1bda1982d451bc249743b8cc414995d6a8justinlin@google.com if (a2_ && !a2_->DecrRefCount()) 81fffb2f1bda1982d451bc249743b8cc414995d6a8justinlin@google.com delete a2_; 82fffb2f1bda1982d451bc249743b8cc414995d6a8justinlin@google.com } 83fffb2f1bda1982d451bc249743b8cc414995d6a8justinlin@google.com 84fffb2f1bda1982d451bc249743b8cc414995d6a8justinlin@google.com A1 *First() const { return a1_; } 85fffb2f1bda1982d451bc249743b8cc414995d6a8justinlin@google.com A2 *Second() const { return a2_; } 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static AddOnPair<A1, A2> *Read(istream &istrm) { 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com A1 *a1 = 0; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool have_addon1 = false; 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ReadType(istrm, &have_addon1); 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (have_addon1) 92c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com a1 = A1::Read(istrm); 93c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com 94c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com A2 *a2 = 0; 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool have_addon2 = false; 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ReadType(istrm, &have_addon2); 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (have_addon2) 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a2 = A2::Read(istrm); 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com AddOnPair<A1, A2> *a = new AddOnPair<A1, A2>(a1, a2); 101b1277c96b0818550190be134fd5e9a971087120bbsalomon@google.com if (a1) 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a1->DecrRefCount(); 103b1277c96b0818550190be134fd5e9a971087120bbsalomon@google.com if (a2) 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a2->DecrRefCount(); 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a; 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool Write(ostream &ostrm) const { 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool have_addon1 = a1_; 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com WriteType(ostrm, have_addon1); 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (have_addon1) 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a1_->Write(ostrm); 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool have_addon2 = a2_; 1145c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com WriteType(ostrm, have_addon2); 1155c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com if (have_addon2) 1165c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com a2_->Write(ostrm); 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12016690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com int RefCount() const { return ref_count_.count(); } 12116690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com 12216690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com int IncrRefCount() { 12316690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com return ref_count_.Incr(); 12416690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com } 12516690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int DecrRefCount() { 12716690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com return ref_count_.Decr(); 12816690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com } 12916690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com 13016690af1c21dead3eedb25ebd0a4b9a091684ed4reed@android.com private: 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com A1 *a1_; 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com A2 *a2_; 13304423805455de868b1b468cfe4057cb77f74b6b0bsalomon@google.com RefCounter ref_count_; 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 135f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com DISALLOW_COPY_AND_ASSIGN(AddOnPair); 136f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}; 137f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 138f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 139f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// Add to an Fst F a type T object. T must have a 'T* Read(istream &)', 140f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// a 'bool Write(ostream &)' method, and 'int RecCount(), 'int IncrRefCount()' 141f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// and 'int DecrRefCount()' methods (e.g. 'MatcherData' in matcher-fst.h). 142f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// The result is a new Fst implemenation with type name 'type'. 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtemplate<class F, class T> 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AddOnImpl : public FstImpl<typename F::Arc> { 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef typename F::Arc Arc; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef typename Arc::Label Label; 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef typename Arc::Weight Weight; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef typename Arc::StateId StateId; 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com using FstImpl<Arc>::SetType; 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com using FstImpl<Arc>::SetProperties; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com using FstImpl<Arc>::WriteHeader; 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // If 't' is non-zero, its reference count is incremented. 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com AddOnImpl(const F &fst, const string &type, T *t = 0) 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : fst_(fst), t_(t) { 15827661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com SetType(type); 15927661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com SetProperties(fst_.Properties(kFstProperties, false)); 16027661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com if (t_) 16127661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com t_->IncrRefCount(); 16227661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com } 16327661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com 16427661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com // If 't' is non-zero, its reference count is incremented. 16527661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com AddOnImpl(const Fst<Arc> &fst, const string &type, T *t = 0) 16627661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com : fst_(fst), t_(t) { 16727661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com SetType(type); 16827661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com SetProperties(fst_.Properties(kFstProperties, false)); 16927661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com if (t_) 17027661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com t_->IncrRefCount(); 17127661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com } 17227661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com 17327661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com AddOnImpl(const AddOnImpl<F, T> &impl) 17427661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com : fst_(impl.fst_), t_(impl.t_) { 17527661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com SetType(impl.Type()); 17627661181d757145d98f2dc3e02b88ee3fffce9e5bsalomon@google.com SetProperties(fst_.Properties(kCopyProperties, false)); 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (t_) 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com t_->IncrRefCount(); 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~AddOnImpl() { 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (t_ && !t_->DecrRefCount()) 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete t_; 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com StateId Start() const { return fst_.Start(); } 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Weight Final(StateId s) const { return fst_.Final(s); } 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t NumArcs(StateId s) const { return fst_.NumArcs(s); } 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t NumInputEpsilons(StateId s) const { 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fst_.NumInputEpsilons(s); 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t NumOutputEpsilons(StateId s) const { 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fst_.NumOutputEpsilons(s); 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t NumStates() const { return fst_.NumStates(); } 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static AddOnImpl<F, T> *Read(istream &strm, const FstReadOptions &opts) { 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FstReadOptions nopts(opts); 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FstHeader hdr; 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!nopts.header) { 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com hdr.Read(strm, nopts.source); 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com nopts.header = &hdr; 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com AddOnImpl<F, T> *impl = new AddOnImpl<F, T>(nopts.header->FstType()); 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!impl->ReadHeader(strm, nopts, kMinFileVersion, &hdr)) 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete impl; // Used here only for checking types. 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32 magic_number = 0; 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ReadType(strm, &magic_number); // Ensures this is an add-on Fst. 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (magic_number != kAddOnMagicNumber) { 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com LOG(ERROR) << "AddOnImpl::Read: Bad add-on header: " << nopts.source; 2165c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com return 0; 2175c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com } 2185c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com 2195c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com FstReadOptions fopts(opts); 2205c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com fopts.header = 0; // Contained header was written out. 2215c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com F *fst = F::Read(strm, fopts); 2225c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com if (!fst) 2235c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com return 0; 2245c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com 2255c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com T *t = 0; 2265c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com bool have_addon = false; 2275c80ea17d4e4a795bfaeb260fc27e952ba471f1dreed@android.com ReadType(strm, &have_addon); 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (have_addon) { // Read add-on object if present. 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com t = T::Read(strm); 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!t) 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com impl = new AddOnImpl<F, T>(*fst, nopts.header->FstType(), t); 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete fst; 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (t) 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com t->DecrRefCount(); 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return impl; 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool Write(ostream &strm, const FstWriteOptions &opts) const { 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FstHeader hdr; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FstWriteOptions nopts(opts); 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com nopts.write_isymbols = false; // Let contained FST hold any symbols. 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com nopts.write_osymbols = false; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com WriteHeader(strm, nopts, kFileVersion, &hdr); 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com WriteType(strm, kAddOnMagicNumber); // Ensures this is an add-on Fst. 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FstWriteOptions fopts(opts); 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fopts.write_header = true; // Force writing contained header. 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fst_.Write(strm, fopts)) 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool have_addon = t_; 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com WriteType(strm, have_addon); 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (have_addon) // Write add-on object if present. 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com t_->Write(strm); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void InitStateIterator(StateIteratorData<Arc> *data) const { 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fst_.InitStateIterator(data); 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const { 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fst_.InitArcIterator(s, data); 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com F &GetFst() { return fst_; } 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const F &GetFst() const { return fst_; } 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T *GetAddOn() const { return t_; } 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // If 't' is non-zero, its reference count is incremented. 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void SetAddOn(T *t) { 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (t == t_) 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (t_ && !t_->DecrRefCount()) 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete t_; 2781341304449a60713bf9c8ea2e9489f35533f037atomhudson@google.com t_ = t; 2791341304449a60713bf9c8ea2e9489f35533f037atomhudson@google.com if (t_) 2801341304449a60713bf9c8ea2e9489f35533f037atomhudson@google.com t_->IncrRefCount(); 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2831341304449a60713bf9c8ea2e9489f35533f037atomhudson@google.com private: 2841341304449a60713bf9c8ea2e9489f35533f037atomhudson@google.com explicit AddOnImpl(const string &type) : t_(0) { 2851341304449a60713bf9c8ea2e9489f35533f037atomhudson@google.com SetType(type); 286ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com SetProperties(kExpanded); 287ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com } 288ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com 289ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com // Current file format version 290ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com static const int kFileVersion = 1; 291ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com // Minimum file format version supported 292ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com static const int kMinFileVersion = 1; 293ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com 294ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com F fst_; 295ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com T *t_; 296ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com 297ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com void operator=(const AddOnImpl<F, T> &fst); // Disallow 298ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com}; 299ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.com 300ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.comtemplate <class F, class T> const int AddOnImpl<F, T>::kFileVersion; 301ece0100c22e2184245efc380c8dede0fe47517b2george@mozilla.comtemplate <class F, class T> const int AddOnImpl<F, T>::kMinFileVersion; 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 304d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com} // namespace fst 305d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com 3063a67a668dbdc3a6bba68700a6dfdef8164ae0c69senorblanco@chromium.org#endif // FST_LIB_ADD_ON_FST_H__ 3073a67a668dbdc3a6bba68700a6dfdef8164ae0c69senorblanco@chromium.org