1
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13//
14// Copyright 2005-2010 Google, Inc.
15// Author: jpr@google.com (Jake Ratkiewicz)
16
17// These classes are only recommended for use in high-level scripting
18// applications. Most users should use the lower-level templated versions
19// corresponding to these classes.
20
21#include <fst/script/fst-class.h>
22#include <fst/script/register.h>
23#include <fst/fst-decl.h>
24#include <fst/union.h>
25#include <fst/reverse.h>
26#include <fst/equal.h>
27
28namespace fst {
29namespace script {
30
31//
32//  REGISTRATION
33//
34
35REGISTER_FST_CLASSES(StdArc);
36REGISTER_FST_CLASSES(LogArc);
37REGISTER_FST_CLASSES(Log64Arc);
38
39//
40//  FST CLASS METHODS
41//
42
43template<class FstT>
44FstT *ReadFst(istream &in, const string &fname) {
45  if (!in) {
46    LOG(ERROR) << "ReadFst: Can't open file: " << fname;
47    return 0;
48  }
49
50  FstHeader hdr;
51  if (!hdr.Read(in, fname)) {
52    return 0;
53  }
54
55  FstReadOptions read_options(fname, &hdr);
56
57  typename IORegistration<FstT>::Register *reg =
58      IORegistration<FstT>::Register::GetRegister();
59
60  const typename IORegistration<FstT>::Reader reader =
61      reg->GetReader(hdr.ArcType());
62
63  if (!reader) {
64    LOG(ERROR) << "ReadFst : unknown arc type \""
65               << hdr.ArcType() << "\" : " << read_options.source;
66    return 0;
67  }
68
69  return reader(in, read_options);
70}
71
72FstClass *FstClass::Read(const string &fname) {
73  if (!fname.empty()) {
74    ifstream in(fname.c_str(), ifstream::in | ifstream::binary);
75    return ReadFst<FstClass>(in, fname);
76  } else {
77    return ReadFst<FstClass>(cin, "standard input");
78  }
79}
80
81FstClass *FstClass::Read(istream &istr, const string &source) {
82  return ReadFst<FstClass>(istr, source);
83}
84
85//
86//  MUTABLE FST CLASS METHODS
87//
88
89MutableFstClass *MutableFstClass::Read(const string &fname, bool convert) {
90  if (convert == false) {
91    if (!fname.empty()) {
92      ifstream in(fname.c_str(), ifstream::in | ifstream::binary);
93      return ReadFst<MutableFstClass>(in, fname);
94    } else {
95      return ReadFst<MutableFstClass>(cin, "standard input");
96    }
97  } else {  // Converts to VectorFstClass if not mutable.
98    FstClass *ifst = FstClass::Read(fname);
99    if (!ifst) return 0;
100    if (ifst->Properties(fst::kMutable, false)) {
101      return static_cast<MutableFstClass *>(ifst);
102    } else {
103      MutableFstClass *ofst = new VectorFstClass(*ifst);
104      delete ifst;
105      return ofst;
106    }
107  }
108}
109
110//
111// VECTOR FST CLASS METHODS
112//
113
114IORegistration<VectorFstClass>::Entry GetVFSTRegisterEntry(
115    const string &arc_type) {
116  IORegistration<VectorFstClass>::Register *reg =
117      IORegistration<VectorFstClass>::Register::GetRegister();
118  const IORegistration<VectorFstClass>::Entry &entry = reg->GetEntry(arc_type);
119
120  if (entry.converter == 0) {
121    LOG(ERROR) << "Unknown arc type " << arc_type;
122    return entry;
123  }
124
125  return entry;
126}
127
128VectorFstClass::VectorFstClass(const FstClass &other)
129    : MutableFstClass(GetVFSTRegisterEntry(other.ArcType()).converter(other)) {
130}
131
132VectorFstClass::VectorFstClass(const string &arc_type)
133    : MutableFstClass(GetVFSTRegisterEntry(arc_type).creator()) { }
134
135VectorFstClass *VectorFstClass::Read(const string &fname) {
136  if (!fname.empty()) {
137    ifstream in(fname.c_str(), ifstream::in | ifstream::binary);
138    return ReadFst<VectorFstClass>(in, fname);
139  } else {
140    return ReadFst<VectorFstClass>(cin, "standard input");
141  }
142}
143
144}  // namespace script
145}  // namespace fst
146