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>(std::cin, "standard input");
78  }
79}
80
81//
82//  MUTABLE FST CLASS METHODS
83//
84
85MutableFstClass *MutableFstClass::Read(const string &fname, bool convert) {
86  if (convert == false) {
87    if (!fname.empty()) {
88      ifstream in(fname.c_str(), ifstream::in | ifstream::binary);
89      return ReadFst<MutableFstClass>(in, fname);
90    } else {
91      return ReadFst<MutableFstClass>(std::cin, "standard input");
92    }
93  } else {  // Converts to VectorFstClass if not mutable.
94    FstClass *ifst = FstClass::Read(fname);
95    if (!ifst) return 0;
96    if (ifst->Properties(fst::kMutable, false)) {
97      return static_cast<MutableFstClass *>(ifst);
98    } else {
99      MutableFstClass *ofst = new VectorFstClass(*ifst);
100      delete ifst;
101      return ofst;
102    }
103  }
104}
105
106//
107// VECTOR FST CLASS METHODS
108//
109
110IORegistration<VectorFstClass>::Entry GetVFSTRegisterEntry(
111    const string &arc_type) {
112  IORegistration<VectorFstClass>::Register *reg =
113      IORegistration<VectorFstClass>::Register::GetRegister();
114  const IORegistration<VectorFstClass>::Entry &entry = reg->GetEntry(arc_type);
115
116  if (entry.converter == 0) {
117    LOG(ERROR) << "Unknown arc type " << arc_type;
118    return entry;
119  }
120
121  return entry;
122}
123
124VectorFstClass::VectorFstClass(const FstClass &other)
125    : MutableFstClass(GetVFSTRegisterEntry(other.ArcType()).converter(other)) {
126}
127
128VectorFstClass::VectorFstClass(const string &arc_type)
129    : MutableFstClass(GetVFSTRegisterEntry(arc_type).creator()) { }
130
131VectorFstClass *VectorFstClass::Read(const string &fname) {
132  if (!fname.empty()) {
133    ifstream in(fname.c_str(), ifstream::in | ifstream::binary);
134    return ReadFst<VectorFstClass>(in, fname);
135  } else {
136    return ReadFst<VectorFstClass>(std::cin, "standard input");
137  }
138}
139
140}  // namespace script
141}  // namespace fst
142