FST  openfst-1.8.3
OpenFst Library
fst-class.cc
Go to the documentation of this file.
1 // Copyright 2005-2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the 'License');
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an 'AS IS' BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // See www.openfst.org for extensive documentation on this weighted
16 // finite-state transducer library.
17 //
18 // These classes are only recommended for use in high-level scripting
19 // applications. Most users should use the lower-level templated versions
20 // corresponding to these classes.
21 
22 #include <fst/script/fst-class.h>
23 
24 #include <ios>
25 #include <iostream>
26 #include <istream>
27 #include <memory>
28 #include <string>
29 
30 #include <fst/log.h>
31 #include <fst/arc.h>
32 #include <fstream>
33 #include <fst/fst.h>
34 #include <fst/properties.h>
35 #include <fst/util.h>
37 #include <string_view>
38 
39 namespace fst {
40 namespace script {
41 namespace {
42 
43 // Helper functions.
44 
45 template <class F>
46 std::unique_ptr<F> ReadFstClass(std::istream &istrm,
47  const std::string &source) {
48  if (!istrm) {
49  LOG(ERROR) << "ReadFstClass: Can't open file: " << source;
50  return nullptr;
51  }
52  FstHeader hdr;
53  if (!hdr.Read(istrm, source)) return nullptr;
54  const FstReadOptions read_options(source, &hdr);
55  const auto &arc_type = hdr.ArcType();
56  static const auto *reg = FstClassIORegistration<F>::Register::GetRegister();
57  const auto reader = reg->GetReader(arc_type);
58  if (!reader) {
59  LOG(ERROR) << "ReadFstClass: Unknown arc type: " << arc_type;
60  return nullptr;
61  }
62  return reader(istrm, read_options);
63 }
64 
65 template <class F>
66 std::unique_ptr<FstClassImplBase> CreateFstClass(
67  std::string_view arc_type) {
68  static const auto *reg = FstClassIORegistration<F>::Register::GetRegister();
69  auto creator = reg->GetCreator(arc_type);
70  if (!creator) {
71  FSTERROR() << "CreateFstClass: Unknown arc type: " << arc_type;
72  return nullptr;
73  }
74  return creator();
75 }
76 
77 template <class F>
78 std::unique_ptr<FstClassImplBase> ConvertFstClass(
79  const FstClass &other) {
80  static const auto *reg = FstClassIORegistration<F>::Register::GetRegister();
81  auto converter = reg->GetConverter(other.ArcType());
82  if (!converter) {
83  FSTERROR() << "ConvertFstClass: Unknown arc type: " << other.ArcType();
84  return nullptr;
85  }
86  return converter(other);
87 }
88 
89 } // namespace
90 
91 // FstClass methods.
92 
93 std::unique_ptr<FstClass> FstClass::Read(
94  const std::string &source) {
95  if (!source.empty()) {
96  std::ifstream istrm(source, std::ios_base::in | std::ios_base::binary);
97  return ReadFstClass<FstClass>(istrm, source);
98  } else {
99  return ReadFstClass<FstClass>(std::cin, "standard input");
100  }
101 }
102 
103 std::unique_ptr<FstClass> FstClass::Read(
104  std::istream &istrm, const std::string &source) {
105  return ReadFstClass<FstClass>(istrm, source);
106 }
107 
109  std::string_view op_name) const {
110  if (WeightType() != weight.Type()) {
111  FSTERROR() << op_name << ": FST and weight with non-matching weight types: "
112  << WeightType() << " and " << weight.Type();
113  return false;
114  }
115  return true;
116 }
117 
118 // MutableFstClass methods.
119 
120 std::unique_ptr<MutableFstClass> MutableFstClass::Read(
121  const std::string &source, bool convert) {
122  if (convert == false) {
123  if (!source.empty()) {
124  std::ifstream in(source, std::ios_base::in | std::ios_base::binary);
125  return ReadFstClass<MutableFstClass>(in, source);
126  } else {
127  return ReadFstClass<MutableFstClass>(std::cin, "standard input");
128  }
129  } else { // Converts to VectorFstClass if not mutable.
130  std::unique_ptr<FstClass> ifst(FstClass::Read(source));
131  if (!ifst) return nullptr;
132  if (ifst->Properties(kMutable, false) == kMutable) {
133  return fst::WrapUnique(down_cast<MutableFstClass *>(ifst.release()));
134  } else {
135  return std::make_unique<VectorFstClass>(*ifst.release());
136  }
137  }
138 }
139 
140 // VectorFstClass methods.
141 
142 std::unique_ptr<VectorFstClass> VectorFstClass::Read(
143  const std::string &source) {
144  if (!source.empty()) {
145  std::ifstream in(source, std::ios_base::in | std::ios_base::binary);
146  return ReadFstClass<VectorFstClass>(in, source);
147  } else {
148  return ReadFstClass<VectorFstClass>(std::cin, "standard input");
149  }
150 }
151 
152 VectorFstClass::VectorFstClass(std::string_view arc_type)
153  : MutableFstClass(CreateFstClass<VectorFstClass>(arc_type)) {}
154 
156  : MutableFstClass(ConvertFstClass<VectorFstClass>(other)) {}
157 
158 // Registration.
159 
163 
164 } // namespace script
165 } // namespace fst
static std::unique_ptr< FstClass > Read(const std::string &source)
Definition: fst-class.cc:93
constexpr uint64_t kMutable
Definition: properties.h:49
static std::unique_ptr< VectorFstClass > Read(const std::string &source)
Definition: fst-class.cc:142
const std::string & Type() const
Definition: weight-class.h:155
#define LOG(type)
Definition: log.h:53
std::unique_ptr< T > WrapUnique(T *ptr)
Definition: compat.h:132
VectorFstClass(std::unique_ptr< FstClassImplBase > impl)
Definition: fst-class.h:554
const std::string & WeightType() const final
Definition: fst-class.h:367
#define FSTERROR()
Definition: util.h:56
bool WeightTypesMatch(const WeightClass &weight, std::string_view op_name) const
Definition: fst-class.cc:108
REGISTER_FST_CLASSES(StdArc)
static std::unique_ptr< MutableFstClass > Read(const std::string &source, bool convert=false)
Definition: fst-class.cc:120