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 (at) 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> 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 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>(std::cin, "standard input"); 78 } 79 } 80 81 // 82 // MUTABLE FST CLASS METHODS 83 // 84 85 MutableFstClass *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 110 IORegistration<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 124 VectorFstClass::VectorFstClass(const FstClass &other) 125 : MutableFstClass(GetVFSTRegisterEntry(other.ArcType()).converter(other)) { 126 } 127 128 VectorFstClass::VectorFstClass(const string &arc_type) 129 : MutableFstClass(GetVFSTRegisterEntry(arc_type).creator()) { } 130 131 VectorFstClass *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