1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// add-on.h 2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License"); 4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License. 5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at 6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// http://www.apache.org/licenses/LICENSE-2.0 8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software 10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS, 11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and 13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License. 14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc. 16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: riley@google.com (Michael Riley) 17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file 19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Fst implementation class to attach an arbitrary object with a 20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// read/write method to an FST and its file rep. The FST is given a 21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// new type name. 22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_ADD_ON_FST_H__ 24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_ADD_ON_FST_H__ 25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <stddef.h> 27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string> 28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/fst.h> 30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst { 33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Identifies stream data as an add-on fst. 35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const int32 kAddOnMagicNumber = 446681434; 36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Some useful add-on objects. 40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Nothing to save. 43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass NullAddOn { 44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson NullAddOn() {} 46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static NullAddOn *Read(istream &istrm) { 48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return new NullAddOn(); 49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson }; 50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Write(ostream &ostrm) const { return true; } 52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson int RefCount() const { return ref_count_.count(); } 54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson int IncrRefCount() { return ref_count_.Incr(); } 55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson int DecrRefCount() { return ref_count_.Decr(); } 56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson RefCounter ref_count_; 59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DISALLOW_COPY_AND_ASSIGN(NullAddOn); 61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Create a new add-on from a pair of add-ons. 65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A1, class A2> 66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass AddOnPair { 67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Argument reference count incremented. 69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson AddOnPair(A1 *a1, A2 *a2) 70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : a1_(a1), a2_(a2) { 71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (a1_) 72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson a1_->IncrRefCount(); 73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (a2_) 74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson a2_->IncrRefCount(); 75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ~AddOnPair() { 78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (a1_ && !a1_->DecrRefCount()) 79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete a1_; 80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (a2_ && !a2_->DecrRefCount()) 81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete a2_; 82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson A1 *First() const { return a1_; } 85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson A2 *Second() const { return a2_; } 86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static AddOnPair<A1, A2> *Read(istream &istrm) { 88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson A1 *a1 = 0; 89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool have_addon1 = false; 90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ReadType(istrm, &have_addon1); 91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (have_addon1) 92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson a1 = A1::Read(istrm); 93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson A2 *a2 = 0; 95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool have_addon2 = false; 96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ReadType(istrm, &have_addon2); 97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (have_addon2) 98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson a2 = A2::Read(istrm); 99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson AddOnPair<A1, A2> *a = new AddOnPair<A1, A2>(a1, a2); 101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (a1) 102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson a1->DecrRefCount(); 103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (a2) 104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson a2->DecrRefCount(); 105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return a; 106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson }; 107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Write(ostream &ostrm) const { 109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool have_addon1 = a1_; 110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson WriteType(ostrm, have_addon1); 111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (have_addon1) 112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson a1_->Write(ostrm); 113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool have_addon2 = a2_; 114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson WriteType(ostrm, have_addon2); 115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (have_addon2) 116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson a2_->Write(ostrm); 117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson int RefCount() const { return ref_count_.count(); } 121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson int IncrRefCount() { 123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ref_count_.Incr(); 124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson int DecrRefCount() { 127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ref_count_.Decr(); 128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson A1 *a1_; 132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson A2 *a2_; 133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson RefCounter ref_count_; 134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DISALLOW_COPY_AND_ASSIGN(AddOnPair); 136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Add to an Fst F a type T object. T must have a 'T* Read(istream &)', 140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// a 'bool Write(ostream &)' method, and 'int RecCount(), 'int IncrRefCount()' 141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// and 'int DecrRefCount()' methods (e.g. 'MatcherData' in matcher-fst.h). 142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The result is a new Fst implemenation with type name 'type'. 143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class F, class T> 144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass AddOnImpl : public FstImpl<typename F::Arc> { 145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Arc Arc; 147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using FstImpl<Arc>::SetType; 152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using FstImpl<Arc>::SetProperties; 153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using FstImpl<Arc>::WriteHeader; 154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // If 't' is non-zero, its reference count is incremented. 156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson AddOnImpl(const F &fst, const string &type, T *t = 0) 157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(fst), t_(t) { 158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SetType(type); 159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SetProperties(fst_.Properties(kFstProperties, false)); 160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (t_) 161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson t_->IncrRefCount(); 162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // If 't' is non-zero, its reference count is incremented. 165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson AddOnImpl(const Fst<Arc> &fst, const string &type, T *t = 0) 166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(fst), t_(t) { 167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SetType(type); 168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SetProperties(fst_.Properties(kFstProperties, false)); 169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (t_) 170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson t_->IncrRefCount(); 171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson AddOnImpl(const AddOnImpl<F, T> &impl) 174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(impl.fst_), t_(impl.t_) { 175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SetType(impl.Type()); 176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SetProperties(fst_.Properties(kCopyProperties, false)); 177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (t_) 178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson t_->IncrRefCount(); 179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ~AddOnImpl() { 182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (t_ && !t_->DecrRefCount()) 183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete t_; 184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson StateId Start() const { return fst_.Start(); } 187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Weight Final(StateId s) const { return fst_.Final(s); } 188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t NumArcs(StateId s) const { return fst_.NumArcs(s); } 189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t NumInputEpsilons(StateId s) const { 191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return fst_.NumInputEpsilons(s); 192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t NumOutputEpsilons(StateId s) const { 195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return fst_.NumOutputEpsilons(s); 196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t NumStates() const { return fst_.NumStates(); } 199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static AddOnImpl<F, T> *Read(istream &strm, const FstReadOptions &opts) { 201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FstReadOptions nopts(opts); 202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FstHeader hdr; 203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!nopts.header) { 204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson hdr.Read(strm, nopts.source); 205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson nopts.header = &hdr; 206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson AddOnImpl<F, T> *impl = new AddOnImpl<F, T>(nopts.header->FstType()); 208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!impl->ReadHeader(strm, nopts, kMinFileVersion, &hdr)) 209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return 0; 210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete impl; // Used here only for checking types. 211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson int32 magic_number = 0; 213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ReadType(strm, &magic_number); // Ensures this is an add-on Fst. 214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (magic_number != kAddOnMagicNumber) { 215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LOG(ERROR) << "AddOnImpl::Read: Bad add-on header: " << nopts.source; 216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return 0; 217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FstReadOptions fopts(opts); 220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson fopts.header = 0; // Contained header was written out. 221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson F *fst = F::Read(strm, fopts); 222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!fst) 223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return 0; 224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T *t = 0; 226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool have_addon = false; 227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ReadType(strm, &have_addon); 228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (have_addon) { // Read add-on object if present. 229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson t = T::Read(strm); 230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!t) 231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return 0; 232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson impl = new AddOnImpl<F, T>(*fst, nopts.header->FstType(), t); 234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete fst; 235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (t) 236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson t->DecrRefCount(); 237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return impl; 238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Write(ostream &strm, const FstWriteOptions &opts) const { 241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FstHeader hdr; 242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FstWriteOptions nopts(opts); 243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson nopts.write_isymbols = false; // Let contained FST hold any symbols. 244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson nopts.write_osymbols = false; 245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson WriteHeader(strm, nopts, kFileVersion, &hdr); 246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson WriteType(strm, kAddOnMagicNumber); // Ensures this is an add-on Fst. 247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FstWriteOptions fopts(opts); 248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson fopts.write_header = true; // Force writing contained header. 249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!fst_.Write(strm, fopts)) 250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool have_addon = t_; 252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson WriteType(strm, have_addon); 253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (have_addon) // Write add-on object if present. 254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson t_->Write(strm); 255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void InitStateIterator(StateIteratorData<Arc> *data) const { 259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson fst_.InitStateIterator(data); 260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const { 263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson fst_.InitArcIterator(s, data); 264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson F &GetFst() { return fst_; } 267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const F &GetFst() const { return fst_; } 269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T *GetAddOn() const { return t_; } 271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // If 't' is non-zero, its reference count is incremented. 273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetAddOn(T *t) { 274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (t == t_) 275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return; 276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (t_ && !t_->DecrRefCount()) 277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete t_; 278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson t_ = t; 279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (t_) 280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson t_->IncrRefCount(); 281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson explicit AddOnImpl(const string &type) : t_(0) { 285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SetType(type); 286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SetProperties(kExpanded); 287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Current file format version 290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const int kFileVersion = 1; 291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Minimum file format version supported 292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const int kMinFileVersion = 1; 293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson F fst_; 295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T *t_; 296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const AddOnImpl<F, T> &fst); // Disallow 298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F, class T> const int AddOnImpl<F, T>::kFileVersion; 301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F, class T> const int AddOnImpl<F, T>::kMinFileVersion; 302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace fst 305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif // FST_LIB_ADD_ON_FST_H__ 307