14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// const-fst.h
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License");
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License.
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//      http://www.apache.org/licenses/LICENSE-2.0
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS,
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License.
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Simple concrete immutable FST whose states and arcs are each stored
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// in single arrays.
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_CONST_FST_H__
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_CONST_FST_H__
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/expanded-fst.h"
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/test-properties.h"
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst {
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A> class ConstFst;
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// States and arcs each implemented by single arrays, templated on the
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Arc definition.
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ConstFstImpl : public FstImpl<A> {
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::SetType;
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::SetProperties;
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::Properties;
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::WriteHeaderAndSymbols;
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight Weight;
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ConstFstImpl()
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : states_(0), arcs_(0), nstates_(0), narcs_(0), start_(kNoStateId) {
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetType("const");
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(kNullProperties | kStaticProperties);
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit ConstFstImpl(const Fst<A> &fst);
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ~ConstFstImpl() {
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    delete[] states_;
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    delete[] arcs_;
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId Start() const { return start_; }
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Weight Final(StateId s) const { return states_[s].final; }
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId NumStates() const { return nstates_; }
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumArcs(StateId s) const { return states_[s].narcs; }
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumInputEpsilons(StateId s) const { return states_[s].niepsilons; }
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumOutputEpsilons(StateId s) const { return states_[s].noepsilons; }
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static ConstFstImpl<A> *Read(istream &strm, const FstReadOptions &opts);
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Write(ostream &strm, const FstWriteOptions &opts) const;
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  A *Arcs(StateId s) { return arcs_ + states_[s].pos; }
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Provide information needed for generic state iterator
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void InitStateIterator(StateIteratorData<A> *data) const {
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->base = 0;
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->nstates = nstates_;
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Provide information needed for the generic arc iterator
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->base = 0;
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->arcs = arcs_ + states_[s].pos;
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->narcs = states_[s].narcs;
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->ref_count = 0;
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // States implemented by array *states_ below, arcs by (single) *arcs_.
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  struct State {
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Weight final;                // Final weight
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    uint32 pos;                  // Start of state's arcs in *arcs_
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    uint32 narcs;                // Number of arcs (per state)
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    uint32 niepsilons;           // # of input epsilons
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    uint32 noepsilons;           // # of output epsilons
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    State() : final(Weight::Zero()), niepsilons(0), noepsilons(0) {}
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  };
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Properties always true of this Fst class
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const uint64 kStaticProperties = kExpanded;
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Current file format version
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kFileVersion = 1;
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Minimum file format version supported
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kMinFileVersion = 1;
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Byte alignment for states and arcs in file format
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kFileAlign = 16;
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  State *states_;                // States represenation
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  A *arcs_;                      // Arcs representation
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId nstates_;              // Number of states
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t narcs_;                 // Number of arcs (per FST)
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId start_;                // Initial state
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(ConstFstImpl);
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class A>
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectConstFstImpl<A>::ConstFstImpl(const Fst<A> &fst) : nstates_(0), narcs_(0) {
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  SetType("const");
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  uint64 copy_properties = fst.Properties(kCopyProperties, true);
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  SetProperties(copy_properties | kStaticProperties);
122ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton  this->SetInputSymbols(fst.InputSymbols());
123ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton  this->SetOutputSymbols(fst.OutputSymbols());
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  start_ = fst.Start();
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // count # of states and arcs
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (StateIterator< Fst<A> > siter(fst);
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       !siter.Done();
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       siter.Next()) {
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ++nstates_;
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    StateId s = siter.Value();
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ArcIterator< Fst<A> > aiter(fst, s);
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         !aiter.Done();
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         aiter.Next())
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ++narcs_;
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  states_ = new State[nstates_];
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arcs_ = new A[narcs_];
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t pos = 0;
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (StateId s = 0; s < nstates_; ++s) {
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_[s].final = fst.Final(s);
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_[s].pos = pos;
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_[s].narcs = 0;
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_[s].niepsilons = 0;
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_[s].noepsilons = 0;
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ArcIterator< Fst<A> > aiter(fst, s);
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         !aiter.Done();
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         aiter.Next()) {
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      const A &arc = aiter.Value();
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ++states_[s].narcs;
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.ilabel == 0)
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ++states_[s].niepsilons;
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.olabel == 0)
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ++states_[s].noepsilons;
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      arcs_[pos++] = arc;
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class A>
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectConstFstImpl<A> *ConstFstImpl<A>::Read(istream &strm,
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                       const FstReadOptions &opts) {
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ConstFstImpl<A> *impl = new ConstFstImpl<A>;
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FstHeader hdr;
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!impl->ReadHeaderAndSymbols(strm, opts, kMinFileVersion, &hdr))
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  impl->start_ = hdr.Start();
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  impl->nstates_ = hdr.NumStates();
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  impl->narcs_ = hdr.NumArcs();
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  impl->states_ = new State[impl->nstates_];
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  impl->arcs_ = new A[impl->narcs_];
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  char c;
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (int i = 0; i < kFileAlign && strm.tellg() % kFileAlign; ++i)
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    strm.read(&c, 1);
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // TODO: memory map this
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t b = impl->nstates_ * sizeof(typename ConstFstImpl<A>::State);
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  strm.read(reinterpret_cast<char *>(impl->states_), b);
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!strm) {
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LOG(ERROR) << "ConstFst::Read: Read failed: " << opts.source;
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // TODO: memory map this
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  b = impl->narcs_ * sizeof(A);
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (int i = 0; i < kFileAlign && strm.tellg() % kFileAlign; ++i)
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    strm.read(&c, 1);
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  strm.read(reinterpret_cast<char *>(impl->arcs_), b);
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!strm) {
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LOG(ERROR) << "ConstFst::Read: Read failed: " << opts.source;
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return impl;
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class A>
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectbool ConstFstImpl<A>::Write(ostream &strm,
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            const FstWriteOptions &opts) const {
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FstHeader hdr;
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  hdr.SetStart(start_);
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  hdr.SetNumStates(nstates_);
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  hdr.SetNumArcs(narcs_);
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  WriteHeaderAndSymbols(strm, opts, kFileVersion, &hdr);
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!strm)
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return false;
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (int i = 0; i < kFileAlign && strm.tellp() % kFileAlign; ++i)
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    strm.write("", 1);
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  strm.write(reinterpret_cast<char *>(states_),
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             nstates_ * sizeof(State));
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (int i = 0; i < kFileAlign && strm.tellp() % kFileAlign; ++i)
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    strm.write("", 1);
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  strm.write(reinterpret_cast<char *>(arcs_), narcs_ * sizeof(A));
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  strm.flush();
21431124d583cfcd1ea9407856747c178d0125c1070Ian Rogers  if (!strm) {
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LOG(ERROR) << "ConstFst::Write: Write failed: " << opts.source;
21631124d583cfcd1ea9407856747c178d0125c1070Ian Rogers    return false;
21731124d583cfcd1ea9407856747c178d0125c1070Ian Rogers  }
21831124d583cfcd1ea9407856747c178d0125c1070Ian Rogers  return true;
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Simple concrete immutable FST.  This class attaches interface to
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// implementation and handles reference counting.
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ConstFst : public ExpandedFst<A> {
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class StateIterator< ConstFst<A> >;
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class ArcIterator< ConstFst<A> >;
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef A Arc;
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight Weight;
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ConstFst() : impl_(new ConstFstImpl<A>()) {}
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ConstFst(const ConstFst<A> &fst) : impl_(fst.impl_) {
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->IncrRefCount();
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit ConstFst(const Fst<A> &fst) : impl_(new ConstFstImpl<A>(fst)) {}
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual ~ConstFst() { if (!impl_->DecrRefCount()) delete impl_;  }
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual StateId Start() const { return impl_->Start(); }
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual Weight Final(StateId s) const { return impl_->Final(s); }
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId NumStates() const { return impl_->NumStates(); }
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumArcs(StateId s) const { return impl_->NumArcs(s); }
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumInputEpsilons(StateId s) const {
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->NumInputEpsilons(s);
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumOutputEpsilons(StateId s) const {
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->NumOutputEpsilons(s);
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual uint64 Properties(uint64 mask, bool test) const {
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (test) {
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      uint64 known, test = TestProperties(*this, mask, &known);
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_->SetProperties(test, known);
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return test & mask;
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } else {
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return impl_->Properties(mask);
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const string& Type() const { return impl_->Type(); }
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Get a copy of this ConstFst
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual ConstFst<A> *Copy() const {
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->IncrRefCount();
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return new ConstFst<A>(impl_);
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Read a ConstFst from an input stream; return NULL on error
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static ConstFst<A> *Read(istream &strm, const FstReadOptions &opts) {
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ConstFstImpl<A>* impl = ConstFstImpl<A>::Read(strm, opts);
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl ? new ConstFst<A>(impl) : 0;
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Read a ConstFst from a file; returno NULL on error
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static ConstFst<A> *Read(const string &filename) {
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ifstream strm(filename.c_str());
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!strm) {
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "ConstFst::Write: Can't open file: " << filename;
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return 0;
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return Read(strm, FstReadOptions(filename));
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Write a ConstFst to an output stream; return false on error
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual bool Write(ostream &strm, const FstWriteOptions &opts) const {
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->Write(strm, opts);
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Write a ConstFst to a file; return false on error
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual bool Write(const string &filename) const {
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!filename.empty()) {
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ofstream strm(filename.c_str());
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (!strm) {
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LOG(ERROR) << "ConstrFst::Write: Can't open file: " << filename;
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return false;
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return Write(strm, FstWriteOptions(filename));
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } else {
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return Write(std::cout, FstWriteOptions("standard output"));
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const SymbolTable* InputSymbols() const {
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->InputSymbols();
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const SymbolTable* OutputSymbols() const {
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->OutputSymbols();
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void InitStateIterator(StateIteratorData<A> *data) const {
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->InitStateIterator(data);
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->InitArcIterator(s, data);
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ConstFst(ConstFstImpl<A> *impl) : impl_(impl) {}
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ConstFstImpl<A> *impl_;  // FST's impl
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void operator=(const ConstFst<A> &fst);  // disallow
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for ConstFst; see generic version in fst.h
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// for sample usage (but use the ConstFst type!). This version
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// should inline.
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass StateIterator< ConstFst<A> > {
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit StateIterator(const ConstFst<A> &fst)
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : nstates_(fst.impl_->NumStates()), s_(0) {}
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Done() const { return s_ >= nstates_; }
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId Value() const { return s_; }
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Next() { ++s_; }
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Reset() { s_ = 0; }
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId nstates_;
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId s_;
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(StateIterator);
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for ConstFst; see generic version in fst.h
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// for sample usage (but use the ConstFst type!). This version
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// should inline.
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ArcIterator< ConstFst<A> > {
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ArcIterator(const ConstFst<A> &fst, StateId s)
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : arcs_(fst.impl_->Arcs(s)), narcs_(fst.impl_->NumArcs(s)), i_(0) {}
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Done() const { return i_ >= narcs_; }
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const A& Value() const { return arcs_[i_]; }
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Next() { ++i_; }
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Reset() { i_ = 0; }
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Seek(size_t a) { i_ = a; }
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const A *arcs_;
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t narcs_;
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t i_;
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(ArcIterator);
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// A useful alias when using StdArc.
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef ConstFst<StdArc> StdConstFst;
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}  // namespace fst;
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif  // FST_LIB_CONST_FST_H__
397