io-funcs.cc
Go to the documentation of this file.
1 // base/io-funcs.cc
2 
3 // Copyright 2009-2011 Microsoft Corporation; Saarland University
4 
5 // See ../../COPYING for clarification regarding multiple authors
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 
11 // http://www.apache.org/licenses/LICENSE-2.0
12 
13 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 // MERCHANTABLITY OR NON-INFRINGEMENT.
17 // See the Apache 2 License for the specific language governing permissions and
18 // limitations under the License.
19 
20 #include "base/io-funcs.h"
21 #include "base/kaldi-math.h"
22 
23 namespace kaldi {
24 
25 template<>
26 void WriteBasicType<bool>(std::ostream &os, bool binary, bool b) {
27  os << (b ? "T":"F");
28  if (!binary) os << " ";
29  if (os.fail())
30  KALDI_ERR << "Write failure in WriteBasicType<bool>";
31 }
32 
33 template<>
34 void ReadBasicType<bool>(std::istream &is, bool binary, bool *b) {
35  KALDI_PARANOID_ASSERT(b != NULL);
36  if (!binary) is >> std::ws; // eat up whitespace.
37  char c = is.peek();
38  if (c == 'T') {
39  *b = true;
40  is.get();
41  } else if (c == 'F') {
42  *b = false;
43  is.get();
44  } else {
45  KALDI_ERR << "Read failure in ReadBasicType<bool>, file position is "
46  << is.tellg() << ", next char is " << CharToString(c);
47  }
48 }
49 
50 template<>
51 void WriteBasicType<float>(std::ostream &os, bool binary, float f) {
52  if (binary) {
53  char c = sizeof(f);
54  os.put(c);
55  os.write(reinterpret_cast<const char *>(&f), sizeof(f));
56  } else {
57  os << f << " ";
58  }
59 }
60 
61 template<>
62 void WriteBasicType<double>(std::ostream &os, bool binary, double f) {
63  if (binary) {
64  char c = sizeof(f);
65  os.put(c);
66  os.write(reinterpret_cast<const char *>(&f), sizeof(f));
67  } else {
68  os << f << " ";
69  }
70 }
71 
72 template<>
73 void ReadBasicType<float>(std::istream &is, bool binary, float *f) {
74  KALDI_PARANOID_ASSERT(f != NULL);
75  if (binary) {
76  double d;
77  int c = is.peek();
78  if (c == sizeof(*f)) {
79  is.get();
80  is.read(reinterpret_cast<char*>(f), sizeof(*f));
81  } else if (c == sizeof(d)) {
82  ReadBasicType(is, binary, &d);
83  *f = d;
84  } else {
85  KALDI_ERR << "ReadBasicType: expected float, saw " << is.peek()
86  << ", at file position " << is.tellg();
87  }
88  } else {
89  is >> *f;
90  }
91  if (is.fail()) {
92  KALDI_ERR << "ReadBasicType: failed to read, at file position "
93  << is.tellg();
94  }
95 }
96 
97 template<>
98 void ReadBasicType<double>(std::istream &is, bool binary, double *d) {
99  KALDI_PARANOID_ASSERT(d != NULL);
100  if (binary) {
101  float f;
102  int c = is.peek();
103  if (c == sizeof(*d)) {
104  is.get();
105  is.read(reinterpret_cast<char*>(d), sizeof(*d));
106  } else if (c == sizeof(f)) {
107  ReadBasicType(is, binary, &f);
108  *d = f;
109  } else {
110  KALDI_ERR << "ReadBasicType: expected float, saw " << is.peek()
111  << ", at file position " << is.tellg();
112  }
113  } else {
114  is >> *d;
115  }
116  if (is.fail()) {
117  KALDI_ERR << "ReadBasicType: failed to read, at file position "
118  << is.tellg();
119  }
120 }
121 
122 void CheckToken(const char *token) {
123  if (*token == '\0')
124  KALDI_ERR << "Token is empty (not a valid token)";
125  const char *orig_token = token;
126  while (*token != '\0') {
127  if (::isspace(*token))
128  KALDI_ERR << "Token is not a valid token (contains space): '"
129  << orig_token << "'";
130  token++;
131  }
132 }
133 
134 void WriteToken(std::ostream &os, bool binary, const char *token) {
135  // binary mode is ignored;
136  // we use space as termination character in either case.
137  KALDI_ASSERT(token != NULL);
138  CheckToken(token); // make sure it's valid (can be read back)
139  os << token << " ";
140  if (os.fail()) {
141  KALDI_ERR << "Write failure in WriteToken.";
142  }
143 }
144 
145 int Peek(std::istream &is, bool binary) {
146  if (!binary) is >> std::ws; // eat up whitespace.
147  return is.peek();
148 }
149 
150 void WriteToken(std::ostream &os, bool binary, const std::string & token) {
151  WriteToken(os, binary, token.c_str());
152 }
153 
154 void ReadToken(std::istream &is, bool binary, std::string *str) {
155  KALDI_ASSERT(str != NULL);
156  if (!binary) is >> std::ws; // consume whitespace.
157  is >> *str;
158  if (is.fail()) {
159  KALDI_ERR << "ReadToken, failed to read token at file position "
160  << is.tellg();
161  }
162  if (!isspace(is.peek())) {
163  KALDI_ERR << "ReadToken, expected space after token, saw instead "
164  << CharToString(static_cast<char>(is.peek()))
165  << ", at file position " << is.tellg();
166  }
167  is.get(); // consume the space.
168 }
169 
170 int PeekToken(std::istream &is, bool binary) {
171  if (!binary) is >> std::ws; // consume whitespace.
172  bool read_bracket;
173  if (static_cast<char>(is.peek()) == '<') {
174  read_bracket = true;
175  is.get();
176  } else {
177  read_bracket = false;
178  }
179  int ans = is.peek();
180  if (read_bracket) {
181  if (!is.unget()) {
182  // Clear the bad bit. This code can be (and is in fact) reached, since the
183  // C++ standard does not guarantee that a call to unget() must succeed.
184  is.clear();
185  }
186  }
187  return ans;
188 }
189 
190 
191 void ExpectToken(std::istream &is, bool binary, const char *token) {
192  int pos_at_start = is.tellg();
193  KALDI_ASSERT(token != NULL);
194  CheckToken(token); // make sure it's valid (can be read back)
195  if (!binary) is >> std::ws; // consume whitespace.
196  std::string str;
197  is >> str;
198  is.get(); // consume the space.
199  if (is.fail()) {
200  KALDI_ERR << "Failed to read token [started at file position "
201  << pos_at_start << "], expected " << token;
202  }
203  // The second half of the '&&' expression below is so that if we're expecting
204  // "<Foo>", we will accept "Foo>" instead. This is so that the model-reading
205  // code will tolerate errors in PeekToken where is.unget() failed; search for
206  // is.clear() in PeekToken() for an explanation.
207  if (strcmp(str.c_str(), token) != 0 &&
208  !(token[0] == '<' && strcmp(str.c_str(), token + 1) == 0)) {
209  KALDI_ERR << "Expected token \"" << token << "\", got instead \""
210  << str <<"\".";
211  }
212 }
213 
214 void ExpectToken(std::istream &is, bool binary, const std::string &token) {
215  ExpectToken(is, binary, token.c_str());
216 }
217 
218 } // end namespace kaldi
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
void WriteBasicType< float >(std::ostream &os, bool binary, float f)
Definition: io-funcs.cc:51
void CheckToken(const char *token)
Definition: io-funcs.cc:122
void ReadBasicType(std::istream &is, bool binary, T *t)
ReadBasicType is the name of the read function for bool, integer types, and floating-point types...
Definition: io-funcs-inl.h:55
void WriteBasicType< bool >(std::ostream &os, bool binary, bool b)
Definition: io-funcs.cc:26
void ReadToken(std::istream &is, bool binary, std::string *str)
ReadToken gets the next token and puts it in str (exception on failure).
Definition: io-funcs.cc:154
int Peek(std::istream &is, bool binary)
Peek consumes whitespace (if binary == false) and then returns the peek() value of the stream...
Definition: io-funcs.cc:145
void WriteBasicType< double >(std::ostream &os, bool binary, double f)
Definition: io-funcs.cc:62
void ExpectToken(std::istream &is, bool binary, const char *token)
ExpectToken tries to read in the given token, and throws an exception on failure. ...
Definition: io-funcs.cc:191
#define KALDI_ERR
Definition: kaldi-error.h:147
#define KALDI_PARANOID_ASSERT(cond)
Definition: kaldi-error.h:206
void WriteToken(std::ostream &os, bool binary, const char *token)
The WriteToken functions are for writing nonempty sequences of non-space characters.
Definition: io-funcs.cc:134
int PeekToken(std::istream &is, bool binary)
PeekToken will return the first character of the next token, or -1 if end of file.
Definition: io-funcs.cc:170
std::string CharToString(const char &c)
Definition: kaldi-utils.cc:36
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
void ReadBasicType< bool >(std::istream &is, bool binary, bool *b)
Definition: io-funcs.cc:34
void ReadBasicType< double >(std::istream &is, bool binary, double *d)
Definition: io-funcs.cc:98
void ReadBasicType< float >(std::istream &is, bool binary, float *f)
Definition: io-funcs.cc:73