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
28 namespace fst {
29 namespace script {
30
31 //
32 // REGISTRATION
33 //
34
35 REGISTER_FST_CLASSES(StdArc);
36 REGISTER_FST_CLASSES(LogArc);
37 REGISTER_FST_CLASSES(Log64Arc);
38
39 //
40 // FST CLASS METHODS
41 //
42
43 template<class FstT>
ReadFst(istream & in,const string & fname)44 FstT *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
Read(const string & fname)72 FstClass *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
Read(istream & istr,const string & source)81 FstClass *FstClass::Read(istream &istr, const string &source) {
82 return ReadFst<FstClass>(istr, source);
83 }
84
85 //
86 // MUTABLE FST CLASS METHODS
87 //
88
Read(const string & fname,bool convert)89 MutableFstClass *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
GetVFSTRegisterEntry(const string & arc_type)114 IORegistration<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
VectorFstClass(const FstClass & other)128 VectorFstClass::VectorFstClass(const FstClass &other)
129 : MutableFstClass(GetVFSTRegisterEntry(other.ArcType()).converter(other)) {
130 }
131
VectorFstClass(const string & arc_type)132 VectorFstClass::VectorFstClass(const string &arc_type)
133 : MutableFstClass(GetVFSTRegisterEntry(arc_type).creator()) { }
134
Read(const string & fname)135 VectorFstClass *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