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)