const-fst.h revision dfd8b8327b93660601d016cdc6f29f433b45a8d8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// const-fst.h 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Licensed under the Apache License, Version 2.0 (the "License"); 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// you may not use this file except in compliance with the License. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You may obtain a copy of the License at 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://www.apache.org/licenses/LICENSE-2.0 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Unless required by applicable law or agreed to in writing, software 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// distributed under the License is distributed on an "AS IS" BASIS, 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// See the License for the specific language governing permissions and 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// limitations under the License. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2005-2010 Google, Inc. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: riley@google.com (Michael Riley) 176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// \file 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple concrete immutable FST whose states and arcs are each stored 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in single arrays. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef FST_LIB_CONST_FST_H__ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FST_LIB_CONST_FST_H__ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fst/expanded-fst.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fst/fst-decl.h> // For optional argument declarations 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fst/test-properties.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fst/util.h> 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace fst { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class U> class ConstFst; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class F, class G> void Cast(const F &, G *); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// States and arcs each implemented by single arrays, templated on the 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Arc definition. The unsigned type U is used to represent indices into 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the arc array. 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochtemplate <class A, class U> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ConstFstImpl : public FstImpl<A> { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch using FstImpl<A>::SetInputSymbols; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using FstImpl<A>::SetOutputSymbols; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using FstImpl<A>::SetType; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using FstImpl<A>::SetProperties; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using FstImpl<A>::Properties; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef A Arc; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef typename A::Weight Weight; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef typename A::StateId StateId; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef U Unsigned; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConstFstImpl() 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : states_(0), arcs_(0), nstates_(0), narcs_(0), start_(kNoStateId) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string type = "const"; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizeof(U) != sizeof(uint32)) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string size; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Int64ToStr(8 * sizeof(U), &size); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type += size; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetType(type); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetProperties(kNullProperties | kStaticProperties); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ConstFstImpl(const Fst<A> &fst); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ConstFstImpl() { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] states_; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] arcs_; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StateId Start() const { return start_; } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Weight Final(StateId s) const { return states_[s].final; } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StateId NumStates() const { return nstates_; } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t NumArcs(StateId s) const { return states_[s].narcs; } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t NumInputEpsilons(StateId s) const { return states_[s].niepsilons; } 851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t NumOutputEpsilons(StateId s) const { return states_[s].noepsilons; } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static ConstFstImpl<A, U> *Read(istream &strm, const FstReadOptions &opts); 891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) A *Arcs(StateId s) { return arcs_ + states_[s].pos; } 911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Provide information needed for generic state iterator 931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void InitStateIterator(StateIteratorData<A> *data) const { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->base = 0; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->nstates = nstates_; 961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Provide information needed for the generic arc iterator 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitArcIterator(StateId s, ArcIteratorData<A> *data) const { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->base = 0; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->arcs = arcs_ + states_[s].pos; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->narcs = states_[s].narcs; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->ref_count = 0; 1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private: 1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) friend class ConstFst<A, U>; // Allow finding narcs_, nstates_ during Write 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // States implemented by array *states_ below, arcs by (single) *arcs_. 1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) struct State { 1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Weight final; // Final weight 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Unsigned pos; // Start of state's arcs in *arcs_ 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Unsigned narcs; // Number of arcs (per state) 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Unsigned niepsilons; // # of input epsilons 1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Unsigned noepsilons; // # of output epsilons 1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) State() : final(Weight::Zero()), niepsilons(0), noepsilons(0) {} 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }; 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Properties always true of this Fst class 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static const uint64 kStaticProperties = kExpanded; 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Current unaligned file format version. The unaligned version was added and 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // made the default since the aligned version does not work on pipes. 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static const int kFileVersion = 2; 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Current aligned file format version 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static const int kAlignedFileVersion = 1; 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Minimum file format version supported 1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static const int kMinFileVersion = 1; 1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Byte alignment for states and arcs in file format (version 1 only) 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static const int kFileAlign = 16; 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) State *states_; // States represenation 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) A *arcs_; // Arcs representation 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) StateId nstates_; // Number of states 1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t narcs_; // Number of arcs (per FST) 1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) StateId start_; // Initial state 1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ConstFstImpl); 1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}; 1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class U> 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const uint64 ConstFstImpl<A, U>::kStaticProperties; 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class A, class U> 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int ConstFstImpl<A, U>::kFileVersion; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class U> 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int ConstFstImpl<A, U>::kAlignedFileVersion; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class U> 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int ConstFstImpl<A, U>::kMinFileVersion; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class U> 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int ConstFstImpl<A, U>::kFileAlign; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class A, class U> 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ConstFstImpl<A, U>::ConstFstImpl(const Fst<A> &fst) : nstates_(0), narcs_(0) { 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch string type = "const"; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizeof(U) != sizeof(uint32)) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string size; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Int64ToStr(sizeof(U) * 8, &size); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type += size; 1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetType(type); 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SetInputSymbols(fst.InputSymbols()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetOutputSymbols(fst.OutputSymbols()); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_ = fst.Start(); 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Count # of states and arcs. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (StateIterator< Fst<A> > siter(fst); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !siter.Done(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) siter.Next()) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++nstates_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StateId s = siter.Value(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ArcIterator< Fst<A> > aiter(fst, s); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !aiter.Done(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aiter.Next()) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++narcs_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch states_ = new State[nstates_]; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arcs_ = new A[narcs_]; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t pos = 0; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (StateId s = 0; s < nstates_; ++s) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states_[s].final = fst.Final(s); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states_[s].pos = pos; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states_[s].narcs = 0; 1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) states_[s].niepsilons = 0; 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) states_[s].noepsilons = 0; 18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (ArcIterator< Fst<A> > aiter(fst, s); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !aiter.Done(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aiter.Next()) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const A &arc = aiter.Value(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++states_[s].narcs; 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (arc.ilabel == 0) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++states_[s].niepsilons; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arc.olabel == 0) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++states_[s].noepsilons; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arcs_[pos++] = arc; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetProperties(fst.Properties(kCopyProperties, true) | kStaticProperties); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<class A, class U> 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ConstFstImpl<A, U> *ConstFstImpl<A, U>::Read(istream &strm, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FstReadOptions &opts) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConstFstImpl<A, U> *impl = new ConstFstImpl<A, U>; 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FstHeader hdr; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete impl; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) impl->start_ = hdr.Start(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) impl->nstates_ = hdr.NumStates(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) impl->narcs_ = hdr.NumArcs(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) impl->states_ = new State[impl->nstates_]; 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) impl->arcs_ = new A[impl->narcs_]; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensures compatibility 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hdr.Version() == kAlignedFileVersion) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hdr.SetFlags(hdr.GetFlags() | FstHeader::IS_ALIGNED); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((hdr.GetFlags() & FstHeader::IS_ALIGNED) && 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !AlignInput(strm, kFileAlign)) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ConstFst::Read: Alignment failed: " << opts.source; 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delete impl; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t b = impl->nstates_ * sizeof(typename ConstFstImpl<A, U>::State); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strm.read(reinterpret_cast<char *>(impl->states_), b); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!strm) { 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << "ConstFst::Read: Read failed: " << opts.source; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete impl; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((hdr.GetFlags() & FstHeader::IS_ALIGNED) && 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !AlignInput(strm, kFileAlign)) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ConstFst::Read: Alignment failed: " << opts.source; 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delete impl; 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return 0; 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) b = impl->narcs_ * sizeof(A); 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) strm.read(reinterpret_cast<char *>(impl->arcs_), b); 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!strm) { 2426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) LOG(ERROR) << "ConstFst::Read: Read failed: " << opts.source; 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delete impl; 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return 0; 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return impl; 2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Simple concrete immutable FST. This class attaches interface to 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementation and handles reference counting, delegating most 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// methods to ImplToExpandedFst. The unsigned type U is used to 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// represent indices into the arc array (uint32 by default, declared 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in fst-decl.h). 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class U> 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ConstFst : public ImplToExpandedFst< ConstFstImpl<A, U> > { 2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) friend class StateIterator< ConstFst<A, U> >; 2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) friend class ArcIterator< ConstFst<A, U> >; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class F, class G> void friend Cast(const F &, G *); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch typedef A Arc; 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch typedef typename A::StateId StateId; 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch typedef ConstFstImpl<A, U> Impl; 264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch typedef U Unsigned; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ConstFst() : ImplToExpandedFst<Impl>(new Impl()) {} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ConstFst(const Fst<A> &fst) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ImplToExpandedFst<Impl>(new Impl(fst)) {} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConstFst(const ConstFst<A, U> &fst) : ImplToExpandedFst<Impl>(fst) {} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get a copy of this ConstFst. See Fst<>::Copy() for further doc. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ConstFst<A, U> *Copy(bool safe = false) const { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ConstFst<A, U>(*this); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read a ConstFst from an input stream; return NULL on error 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ConstFst<A, U> *Read(istream &strm, const FstReadOptions &opts) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Impl* impl = Impl::Read(strm, opts); 28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return impl ? new ConstFst<A, U>(impl) : 0; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read a ConstFst from a file; return NULL on error 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Empty filename reads from standard input 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ConstFst<A, U> *Read(const string &filename) { 28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Impl* impl = ImplToExpandedFst<Impl>::Read(filename); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return impl ? new ConstFst<A, U>(impl) : 0; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Write(ostream &strm, const FstWriteOptions &opts) const { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteFst(*this, strm, opts); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Write(const string &filename) const { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Fst<A>::WriteFile(filename); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class F> 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch static bool WriteFst(const F &fst, ostream &strm, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FstWriteOptions &opts); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void InitStateIterator(StateIteratorData<Arc> *data) const { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetImpl()->InitStateIterator(data); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetImpl()->InitArcIterator(s, data); 309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 312c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch explicit ConstFst(Impl *impl) : ImplToExpandedFst<Impl>(impl) {} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Makes visible to friends. 315c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Impl *GetImpl() const { return ImplToFst<Impl, ExpandedFst<A> >::GetImpl(); } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetImpl(Impl *impl, bool own_impl = true) { 318c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ImplToFst< Impl, ExpandedFst<A> >::SetImpl(impl, own_impl); 319c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator=(const ConstFst<A, U> &fst); // disallow 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Writes Fst in Const format, potentially with a pass over the machine 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// before writing to compute number of states and arcs. 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class U> 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class F> 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ConstFst<A, U>::WriteFst(const F &fst, ostream &strm, 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FstWriteOptions &opts) { 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int file_version = opts.align ? ConstFstImpl<A, U>::kAlignedFileVersion : 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConstFstImpl<A, U>::kFileVersion; 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t num_arcs = -1, num_states = -1; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t start_offset = 0; 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool update_header = true; 336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (fst.Type() == ConstFst<A, U>().Type()) { 337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const ConstFst<A, U> *const_fst = 338c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch reinterpret_cast<const ConstFst<A, U> *>(&fst); 339c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch num_arcs = const_fst->GetImpl()->narcs_; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_states = const_fst->GetImpl()->nstates_; 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_header = false; 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if ((start_offset = strm.tellp()) == -1) { 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // precompute values needed for header when we cannot seek to rewrite it. 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_arcs = 0; 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_states = 0; 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_arcs += fst.NumArcs(siter.Value()); 348c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++num_states; 349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 350c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch update_header = false; 351c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FstHeader hdr; 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hdr.SetStart(fst.Start()); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hdr.SetNumStates(num_states); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hdr.SetNumArcs(num_arcs); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string type = "const"; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sizeof(U) != sizeof(uint32)) { 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string size; 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Int64ToStr(8 * sizeof(U), &size); 360c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch type += size; 361c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 362c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uint64 properties = fst.Properties(kCopyProperties, true) | 363c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ConstFstImpl<A, U>::kStaticProperties; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FstImpl<A>::WriteFstHeader(fst, strm, opts, file_version, type, properties, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &hdr); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (opts.align && !AlignOutput(strm, ConstFstImpl<A, U>::kFileAlign)) { 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Could not align file during write after header"; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t pos = 0, states = 0; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename ConstFstImpl<A, U>::State state; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.final = fst.Final(siter.Value()); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.pos = pos; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.narcs = fst.NumArcs(siter.Value()); 3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) state.niepsilons = fst.NumInputEpsilons(siter.Value()); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.noepsilons = fst.NumOutputEpsilons(siter.Value()); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strm.write(reinterpret_cast<const char *>(&state), sizeof(state)); 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pos += state.narcs; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++states; 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hdr.SetNumStates(states); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hdr.SetNumArcs(pos); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (opts.align && !AlignOutput(strm, ConstFstImpl<A, U>::kFileAlign)) { 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Could not align file during write after writing states"; 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) { 388c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StateId s = siter.Value(); 389c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (ArcIterator<F> aiter(fst, s); !aiter.Done(); aiter.Next()) { 390c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const A &arc = aiter.Value(); 391c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch strm.write(reinterpret_cast<const char *>(&arc), sizeof(arc)); 392c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strm.flush(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!strm) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ConstFst Write write failed: " << opts.source; 3971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (update_header) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FstImpl<A>::UpdateFstHeader(fst, strm, opts, file_version, type, 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) properties, &hdr, start_offset); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (hdr.NumStates() != num_states) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Inconsistent number of states observed during write"; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (hdr.NumArcs() != num_arcs) { 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Inconsistent number of arcs observed during write"; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 411c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return true; 413c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 414c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specialization for ConstFst; see generic version in fst.h 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for sample usage (but use the ConstFst type!). This version 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should inline. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class U> 4191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class StateIterator< ConstFst<A, U> > { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef typename A::StateId StateId; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit StateIterator(const ConstFst<A, U> &fst) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : nstates_(fst.GetImpl()->NumStates()), s_(0) {} 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Done() const { return s_ >= nstates_; } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StateId Value() const { return s_; } 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Next() { ++s_; } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 432c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch void Reset() { s_ = 0; } 433c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 434c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private: 435c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StateId nstates_; 436c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StateId s_; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(StateIterator); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specialization for ConstFst; see generic version in fst.h 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for sample usage (but use the ConstFst type!). This version 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should inline. 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class A, class U> 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ArcIterator< ConstFst<A, U> > { 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef typename A::StateId StateId; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ArcIterator(const ConstFst<A, U> &fst, StateId s) 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : arcs_(fst.GetImpl()->Arcs(s)), 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) narcs_(fst.GetImpl()->NumArcs(s)), i_(0) {} 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 454c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool Done() const { return i_ >= narcs_; } 455c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 456c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const A& Value() const { return arcs_[i_]; } 457c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 458c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch void Next() { ++i_; } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t Position() const { return i_; } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reset() { i_ = 0; } 4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Seek(size_t a) { i_ = a; } 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 Flags() const { 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kArcValueFlags; 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetFlags(uint32 f, uint32 m) {} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const A *arcs_; 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t narcs_; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t i_; 476c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 477c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DISALLOW_COPY_AND_ASSIGN(ArcIterator); 478c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 479c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 480c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// A useful alias when using StdArc. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ConstFst<StdArc> StdConstFst; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace fst 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // FST_LIB_CONST_FST_H__ 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)