basic-filebuf.h
Go to the documentation of this file.
1 // This is a modified version of the std::basic_filebuf from libc++
3 // (http://libcxx.llvm.org/).
4 // It allows one to create basic_filebuf from an existing FILE* handle or file
5 // descriptor.
6 //
7 // This file is dual licensed under the MIT and the University of Illinois Open
8 // Source License licenses. See LICENSE.TXT for details (included at the
9 // bottom).
11 #ifndef KALDI_UTIL_BASIC_FILEBUF_H_
12 #define KALDI_UTIL_BASIC_FILEBUF_H_
13 
15 #include <fstream>
16 #include <cstdio>
17 #include <cstring>
18 #include <string>
19 #include <algorithm>
20 
22 namespace kaldi {
24 template <typename CharT, typename Traits = std::char_traits<CharT> >
25 class basic_filebuf : public std::basic_streambuf<CharT, Traits> {
26  public:
27  typedef CharT char_type;
28  typedef Traits traits_type;
29  typedef typename traits_type::int_type int_type;
30  typedef typename traits_type::pos_type pos_type;
31  typedef typename traits_type::off_type off_type;
32  typedef typename traits_type::state_type state_type;
33 
34  basic_filebuf();
36  virtual ~basic_filebuf();
37 
39  void swap(basic_filebuf& rhs);
40 
41  bool is_open() const;
42  basic_filebuf* open(const char* s, std::ios_base::openmode mode);
43  basic_filebuf* open(const std::string& s, std::ios_base::openmode mode);
44  basic_filebuf* open(int fd, std::ios_base::openmode mode);
45  basic_filebuf* open(FILE* f, std::ios_base::openmode mode);
47 
48  FILE* file() { return this->_M_file; }
49  int fd() { return fileno(this->_M_file); }
50 
51  protected:
52  int_type underflow() override;
53  int_type pbackfail(int_type c = traits_type::eof()) override;
54  int_type overflow(int_type c = traits_type::eof()) override;
55  std::basic_streambuf<char_type, traits_type>*
56  setbuf(char_type* s, std::streamsize n) override;
57  pos_type seekoff(off_type off, std::ios_base::seekdir way,
58  std::ios_base::openmode wch =
59  std::ios_base::in | std::ios_base::out) override;
60  pos_type seekpos(pos_type sp,
61  std::ios_base::openmode wch =
62  std::ios_base::in | std::ios_base::out) override;
63  int sync() override;
64  void imbue(const std::locale& loc) override;
65 
66  protected:
67  char* _M_extbuf;
68  const char* _M_extbufnext;
69  const char* _M_extbufend;
70  char _M_extbuf_min[8];
71  size_t _M_ebs;
72  char_type* _M_intbuf;
73  size_t _M_ibs;
74  FILE* _M_file;
75  const std::codecvt<char_type, char, state_type>* _M_cv;
76  state_type _M_st;
77  state_type _M_st_last;
78  std::ios_base::openmode _M_om;
79  std::ios_base::openmode _M_cm;
80  bool _M_owns_eb;
81  bool _M_owns_ib;
83 
84  const char* _M_get_mode(std::ios_base::openmode mode);
85  bool _M_read_mode();
86  void _M_write_mode();
87 };
88 
90 template <class CharT, class Traits>
92  : _M_extbuf(nullptr),
93  _M_extbufnext(nullptr),
94  _M_extbufend(nullptr),
95  _M_ebs(0),
96  _M_intbuf(nullptr),
97  _M_ibs(0),
98  _M_file(nullptr),
99  _M_cv(nullptr),
100  _M_st(),
101  _M_st_last(),
102  _M_om(std::ios_base::openmode(0)),
103  _M_cm(std::ios_base::openmode(0)),
104  _M_owns_eb(false),
105  _M_owns_ib(false),
106  _M_always_noconv(false) {
107  if (std::has_facet<std::codecvt<char_type, char, state_type> >
108  (this->getloc())) {
109  _M_cv = &std::use_facet<std::codecvt<char_type, char, state_type> >
110  (this->getloc());
111  _M_always_noconv = _M_cv->always_noconv();
112  }
113  setbuf(0, 4096);
114 }
115 
117 template <class CharT, class Traits>
119  : std::basic_streambuf<CharT, Traits>(rhs) {
120  if (rhs._M_extbuf == rhs._M_extbuf_min) {
122  _M_extbufnext = _M_extbuf + (rhs._M_extbufnext - rhs._M_extbuf);
123  _M_extbufend = _M_extbuf + (rhs._M_extbufend - rhs._M_extbuf);
124  } else {
125  _M_extbuf = rhs._M_extbuf;
126  _M_extbufnext = rhs._M_extbufnext;
127  _M_extbufend = rhs._M_extbufend;
128  }
129  _M_ebs = rhs._M_ebs;
130  _M_intbuf = rhs._M_intbuf;
131  _M_ibs = rhs._M_ibs;
132  _M_file = rhs._M_file;
133  _M_cv = rhs._M_cv;
134  _M_st = rhs._M_st;
135  _M_st_last = rhs._M_st_last;
136  _M_om = rhs._M_om;
137  _M_cm = rhs._M_cm;
138  _M_owns_eb = rhs._M_owns_eb;
139  _M_owns_ib = rhs._M_owns_ib;
140  _M_always_noconv = rhs._M_always_noconv;
141  if (rhs.pbase()) {
142  if (rhs.pbase() == rhs._M_intbuf)
143  this->setp(_M_intbuf, _M_intbuf + (rhs. epptr() - rhs.pbase()));
144  else
145  this->setp(reinterpret_cast<char_type*>(_M_extbuf),
146  reinterpret_cast<char_type*>(_M_extbuf)
147  + (rhs. epptr() - rhs.pbase()));
148  this->pbump(rhs. pptr() - rhs.pbase());
149  } else if (rhs.eback()) {
150  if (rhs.eback() == rhs._M_intbuf)
151  this->setg(_M_intbuf, _M_intbuf + (rhs.gptr() - rhs.eback()),
152  _M_intbuf + (rhs.egptr() - rhs.eback()));
153  else
154  this->setg(reinterpret_cast<char_type*>(_M_extbuf),
155  reinterpret_cast<char_type*>(_M_extbuf) +
156  (rhs.gptr() - rhs.eback()),
157  reinterpret_cast<char_type*>(_M_extbuf) +
158  (rhs.egptr() - rhs.eback()));
159  }
160  rhs._M_extbuf = nullptr;
161  rhs._M_extbufnext = nullptr;
162  rhs._M_extbufend = nullptr;
163  rhs._M_ebs = 0;
164  rhs._M_intbuf = nullptr;
165  rhs._M_ibs = 0;
166  rhs._M_file = nullptr;
167  rhs._M_st = state_type();
168  rhs._M_st_last = state_type();
169  rhs._M_om = std::ios_base::openmode(0);
170  rhs._M_cm = std::ios_base::openmode(0);
171  rhs._M_owns_eb = false;
172  rhs._M_owns_ib = false;
173  rhs.setg(0, 0, 0);
174  rhs.setp(0, 0);
175 }
176 
178 template <class CharT, class Traits>
179 inline
182  close();
183  swap(rhs);
184  return *this;
185 }
186 
188 template <class CharT, class Traits>
190  // try
191  // {
192  // close();
193  // }
194  // catch (...)
195  // {
196  // }
197  if (_M_owns_eb)
198  delete [] _M_extbuf;
199  if (_M_owns_ib)
200  delete [] _M_intbuf;
201 }
202 
204 template <class CharT, class Traits>
205 void
208  if (_M_extbuf != _M_extbuf_min && rhs._M_extbuf != rhs._M_extbuf_min) {
212  } else {
213  ptrdiff_t ln = _M_extbufnext - _M_extbuf;
214  ptrdiff_t le = _M_extbufend - _M_extbuf;
215  ptrdiff_t rn = rhs._M_extbufnext - rhs._M_extbuf;
216  ptrdiff_t re = rhs._M_extbufend - rhs._M_extbuf;
217  if (_M_extbuf == _M_extbuf_min && rhs._M_extbuf != rhs._M_extbuf_min) {
218  _M_extbuf = rhs._M_extbuf;
219  rhs._M_extbuf = rhs._M_extbuf_min;
220  } else if (_M_extbuf != _M_extbuf_min &&
221  rhs._M_extbuf == rhs._M_extbuf_min) {
222  rhs._M_extbuf = _M_extbuf;
223  _M_extbuf = _M_extbuf_min;
224  }
225  _M_extbufnext = _M_extbuf + rn;
226  _M_extbufend = _M_extbuf + re;
227  rhs._M_extbufnext = rhs._M_extbuf + ln;
228  rhs._M_extbufend = rhs._M_extbuf + le;
229  }
230  std::swap(_M_ebs, rhs._M_ebs);
232  std::swap(_M_ibs, rhs._M_ibs);
233  std::swap(_M_file, rhs._M_file);
234  std::swap(_M_cv, rhs._M_cv);
235  std::swap(_M_st, rhs._M_st);
237  std::swap(_M_om, rhs._M_om);
238  std::swap(_M_cm, rhs._M_cm);
242  if (this->eback() == reinterpret_cast<char_type*>(rhs._M_extbuf_min)) {
243  ptrdiff_t n = this->gptr() - this->eback();
244  ptrdiff_t e = this->egptr() - this->eback();
245  this->setg(reinterpret_cast<char_type*>(_M_extbuf_min),
246  reinterpret_cast<char_type*>(_M_extbuf_min) + n,
247  reinterpret_cast<char_type*>(_M_extbuf_min) + e);
248  } else if (this->pbase() ==
249  reinterpret_cast<char_type*>(rhs._M_extbuf_min)) {
250  ptrdiff_t n = this->pptr() - this->pbase();
251  ptrdiff_t e = this->epptr() - this->pbase();
252  this->setp(reinterpret_cast<char_type*>(_M_extbuf_min),
253  reinterpret_cast<char_type*>(_M_extbuf_min) + e);
254  this->pbump(n);
255  }
256  if (rhs.eback() == reinterpret_cast<char_type*>(_M_extbuf_min)) {
257  ptrdiff_t n = rhs.gptr() - rhs.eback();
258  ptrdiff_t e = rhs.egptr() - rhs.eback();
259  rhs.setg(reinterpret_cast<char_type*>(rhs._M_extbuf_min),
260  reinterpret_cast<char_type*>(rhs._M_extbuf_min) + n,
261  reinterpret_cast<char_type*>(rhs._M_extbuf_min) + e);
262  } else if (rhs.pbase() == reinterpret_cast<char_type*>(_M_extbuf_min)) {
263  ptrdiff_t n = rhs.pptr() - rhs.pbase();
264  ptrdiff_t e = rhs.epptr() - rhs.pbase();
265  rhs.setp(reinterpret_cast<char_type*>(rhs._M_extbuf_min),
266  reinterpret_cast<char_type*>(rhs._M_extbuf_min) + e);
267  rhs.pbump(n);
268  }
269 }
270 
272 template <class CharT, class Traits>
273 inline
274 void
276  x.swap(y);
277 }
278 
280 template <class CharT, class Traits>
281 inline
282 bool
284  return _M_file != nullptr;
285 }
286 
288 template <class CharT, class Traits>
290 _M_get_mode(std::ios_base::openmode mode) {
291  switch ((mode & ~std::ios_base::ate) | 0) {
292  case std::ios_base::out:
293  case std::ios_base::out | std::ios_base::trunc:
294  return "w";
295  case std::ios_base::out | std::ios_base::app:
296  case std::ios_base::app:
297  return "a";
298  break;
299  case std::ios_base::in:
300  return "r";
301  case std::ios_base::in | std::ios_base::out:
302  return "r+";
303  case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
304  return "w+";
305  case std::ios_base::in | std::ios_base::out | std::ios_base::app:
306  case std::ios_base::in | std::ios_base::app:
307  return "a+";
308  case std::ios_base::out | std::ios_base::binary:
309  case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
310  return "wb";
311  case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
312  case std::ios_base::app | std::ios_base::binary:
313  return "ab";
314  case std::ios_base::in | std::ios_base::binary:
315  return "rb";
316  case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
317  return "r+b";
318  case std::ios_base::in | std::ios_base::out | std::ios_base::trunc |
319  std::ios_base::binary:
320  return "w+b";
321  case std::ios_base::in | std::ios_base::out | std::ios_base::app |
322  std::ios_base::binary:
323  case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
324  return "a+b";
325  default:
326  return nullptr;
327  }
328 }
329 
331 template <class CharT, class Traits>
334 open(const char* s, std::ios_base::openmode mode) {
335  basic_filebuf<CharT, Traits>* rt = nullptr;
336  if (_M_file == nullptr) {
337  const char* md= _M_get_mode(mode);
338  if (md) {
339  _M_file = fopen(s, md);
340  if (_M_file) {
341  rt = this;
342  _M_om = mode;
343  if (mode & std::ios_base::ate) {
344  if (fseek(_M_file, 0, SEEK_END)) {
345  fclose(_M_file);
346  _M_file = nullptr;
347  rt = nullptr;
348  }
349  }
350  }
351  }
352  }
353  return rt;
354 }
355 
357 template <class CharT, class Traits>
358 inline
361  std::ios_base::openmode mode) {
362  return open(s.c_str(), mode);
363 }
364 
366 template <class CharT, class Traits>
368 basic_filebuf<CharT, Traits>::open(int fd, std::ios_base::openmode mode) {
369  const char* md= this->_M_get_mode(mode);
370  if (md) {
371  this->_M_file= fdopen(fd, md);
372  this->_M_om = mode;
373  return this;
374  } else {
375  return nullptr;
376  }
377 }
378 
380 template <class CharT, class Traits>
382 basic_filebuf<CharT, Traits>::open(FILE* f, std::ios_base::openmode mode) {
383  this->_M_file = f;
384  this->_M_om = mode;
385  return this;
386 }
387 
389 template <class CharT, class Traits>
392  basic_filebuf<CharT, Traits>* rt = nullptr;
393  if (_M_file) {
394  rt = this;
395  std::unique_ptr<FILE, int(*)(FILE*)> h(_M_file, fclose);
396  if (sync())
397  rt = nullptr;
398  if (fclose(h.release()) == 0)
399  _M_file = nullptr;
400  else
401  rt = nullptr;
402  }
403  return rt;
404 }
405 
407 template <class CharT, class Traits>
410  if (_M_file == nullptr)
411  return traits_type::eof();
412  bool initial = _M_read_mode();
413  char_type buf;
414  if (this->gptr() == nullptr)
415  this->setg(&buf, &buf+1, &buf+1);
416  const size_t unget_sz = initial ? 0 : std::
417  min<size_t>((this->egptr() - this->eback()) / 2, 4);
418  int_type c = traits_type::eof();
419  if (this->gptr() == this->egptr()) {
420  memmove(this->eback(), this->egptr() - unget_sz,
421  unget_sz * sizeof(char_type));
422  if (_M_always_noconv) {
423  size_t nmemb = static_cast<size_t>
424  (this->egptr() - this->eback() - unget_sz);
425  nmemb = fread(this->eback() + unget_sz, 1, nmemb, _M_file);
426  if (nmemb != 0) {
427  this->setg(this->eback(),
428  this->eback() + unget_sz,
429  this->eback() + unget_sz + nmemb);
430  c = traits_type::to_int_type(*this->gptr());
431  }
432  } else {
436  (_M_extbuf == _M_extbuf_min ? sizeof(_M_extbuf_min) : _M_ebs);
437  size_t nmemb = std::min(static_cast<size_t>(_M_ibs - unget_sz),
438  static_cast<size_t>
439  (_M_extbufend - _M_extbufnext));
440  std::codecvt_base::result r;
441  _M_st_last = _M_st;
442  size_t nr = fread(
443  reinterpret_cast<void*>(const_cast<char_type*>(_M_extbufnext)),
444  1, nmemb, _M_file);
445  if (nr != 0) {
446  if (!_M_cv)
447  throw std::bad_cast();
448  _M_extbufend = _M_extbufnext + nr;
449  char_type* inext;
450  r = _M_cv->in(_M_st, _M_extbuf, _M_extbufend, _M_extbufnext,
451  this->eback() + unget_sz,
452  this->eback() + _M_ibs, inext);
453  if (r == std::codecvt_base::noconv) {
454  this->setg(reinterpret_cast<char_type*>(_M_extbuf),
455  reinterpret_cast<char_type*>(_M_extbuf),
456  const_cast<char_type*>(_M_extbufend));
457  c = traits_type::to_int_type(*this->gptr());
458  } else if (inext != this->eback() + unget_sz) {
459  this->setg(this->eback(), this->eback() + unget_sz, inext);
460  c = traits_type::to_int_type(*this->gptr());
461  }
462  }
463  }
464  } else {
465  c = traits_type::to_int_type(*this->gptr());
466  }
467  if (this->eback() == &buf)
468  this->setg(0, 0, 0);
469  return c;
470 }
471 
473 template <class CharT, class Traits>
476  if (_M_file && this->eback() < this->gptr()) {
477  if (traits_type::eq_int_type(c, traits_type::eof())) {
478  this->gbump(-1);
479  return traits_type::not_eof(c);
480  }
481  if ((_M_om & std::ios_base::out) ||
482  traits_type::eq(traits_type::to_char_type(c), this->gptr()[-1])) {
483  this->gbump(-1);
484  *this->gptr() = traits_type::to_char_type(c);
485  return c;
486  }
487  }
488  return traits_type::eof();
489 }
490 
492 template <class CharT, class Traits>
495  if (_M_file == nullptr)
496  return traits_type::eof();
497  _M_write_mode();
498  char_type buf;
499  char_type* pb_save = this->pbase();
500  char_type* epb_save = this->epptr();
501  if (!traits_type::eq_int_type(c, traits_type::eof())) {
502  if (this->pptr() == nullptr)
503  this->setp(&buf, &buf+1);
504  *this->pptr() = traits_type::to_char_type(c);
505  this->pbump(1);
506  }
507  if (this->pptr() != this->pbase()) {
508  if (_M_always_noconv) {
509  size_t nmemb = static_cast<size_t>(this->pptr() - this->pbase());
510  if (fwrite(this->pbase(), sizeof(char_type),
511  nmemb, _M_file) != nmemb)
512  return traits_type::eof();
513  } else {
514  char* extbe = _M_extbuf;
515  std::codecvt_base::result r;
516  do {
517  if (!_M_cv)
518  throw std::bad_cast();
519  const char_type* e;
520  r = _M_cv->out(_M_st, this->pbase(), this->pptr(), e,
521  _M_extbuf, _M_extbuf + _M_ebs, extbe);
522  if (e == this->pbase())
523  return traits_type::eof();
524  if (r == std::codecvt_base::noconv) {
525  size_t nmemb = static_cast<size_t>
526  (this->pptr() - this->pbase());
527  if (fwrite(this->pbase(), 1, nmemb, _M_file) != nmemb)
528  return traits_type::eof();
529  } else if (r == std::codecvt_base::ok ||
530  r == std::codecvt_base::partial) {
531  size_t nmemb = static_cast<size_t>(extbe - _M_extbuf);
532  if (fwrite(_M_extbuf, 1, nmemb, _M_file) != nmemb)
533  return traits_type::eof();
534  if (r == std::codecvt_base::partial) {
535  this->setp(const_cast<char_type*>(e),
536  this->pptr());
537  this->pbump(this->epptr() - this->pbase());
538  }
539  } else {
540  return traits_type::eof();
541  }
542  } while (r == std::codecvt_base::partial);
543  }
544  this->setp(pb_save, epb_save);
545  }
546  return traits_type::not_eof(c);
547 }
548 
550 template <class CharT, class Traits>
551 std::basic_streambuf<CharT, Traits>*
553  this->setg(0, 0, 0);
554  this->setp(0, 0);
555  if (_M_owns_eb)
556  delete [] _M_extbuf;
557  if (_M_owns_ib)
558  delete [] _M_intbuf;
559  _M_ebs = n;
560  if (_M_ebs > sizeof(_M_extbuf_min)) {
561  if (_M_always_noconv && s) {
562  _M_extbuf = reinterpret_cast<char*>(s);
563  _M_owns_eb = false;
564  } else {
565  _M_extbuf = new char[_M_ebs];
566  _M_owns_eb = true;
567  }
568  } else {
570  _M_ebs = sizeof(_M_extbuf_min);
571  _M_owns_eb = false;
572  }
573  if (!_M_always_noconv) {
574  _M_ibs = std::max<std::streamsize>(n, sizeof(_M_extbuf_min));
575  if (s && _M_ibs >= sizeof(_M_extbuf_min)) {
576  _M_intbuf = s;
577  _M_owns_ib = false;
578  } else {
579  _M_intbuf = new char_type[_M_ibs];
580  _M_owns_ib = true;
581  }
582  } else {
583  _M_ibs = 0;
584  _M_intbuf = 0;
585  _M_owns_ib = false;
586  }
587  return this;
588 }
589 
591 template <class CharT, class Traits>
593 basic_filebuf<CharT, Traits>::seekoff(off_type off, std::ios_base::seekdir way,
594  std::ios_base::openmode) {
595  if (!_M_cv)
596  throw std::bad_cast();
597  int width = _M_cv->encoding();
598  if (_M_file == nullptr || (width <= 0 && off != 0) || sync())
599  return pos_type(off_type(-1));
600  // width > 0 || off == 0
601  int whence;
602  switch (way) {
603  case std::ios_base::beg:
604  whence = SEEK_SET;
605  break;
606  case std::ios_base::cur:
607  whence = SEEK_CUR;
608  break;
609  case std::ios_base::end:
610  whence = SEEK_END;
611  break;
612  default:
613  return pos_type(off_type(-1));
614  }
615 #if _WIN32
616  if (fseek(_M_file, width > 0 ? width * off : 0, whence))
617  return pos_type(off_type(-1));
618  pos_type r = ftell(_M_file);
619 #else
620  if (fseeko(_M_file, width > 0 ? width * off : 0, whence))
621  return pos_type(off_type(-1));
622  pos_type r = ftello(_M_file);
623 #endif
624  r.state(_M_st);
625  return r;
626 }
627 
629 template <class CharT, class Traits>
631 basic_filebuf<CharT, Traits>::seekpos(pos_type sp, std::ios_base::openmode) {
632  if (_M_file == nullptr || sync())
633  return pos_type(off_type(-1));
634 #if _WIN32
635  if (fseek(_M_file, sp, SEEK_SET))
636  return pos_type(off_type(-1));
637 #else
638  if (fseeko(_M_file, sp, SEEK_SET))
639  return pos_type(off_type(-1));
640 #endif
641  _M_st = sp.state();
642  return sp;
643 }
644 
646 template <class CharT, class Traits>
647 int
649  if (_M_file == nullptr)
650  return 0;
651  if (!_M_cv)
652  throw std::bad_cast();
653  if (_M_cm & std::ios_base::out) {
654  if (this->pptr() != this->pbase())
655  if (overflow() == traits_type::eof())
656  return -1;
657  std::codecvt_base::result r;
658  do {
659  char* extbe;
660  r = _M_cv->unshift(_M_st, _M_extbuf, _M_extbuf + _M_ebs, extbe);
661  size_t nmemb = static_cast<size_t>(extbe - _M_extbuf);
662  if (fwrite(_M_extbuf, 1, nmemb, _M_file) != nmemb)
663  return -1;
664  } while (r == std::codecvt_base::partial);
665  if (r == std::codecvt_base::error)
666  return -1;
667  if (fflush(_M_file))
668  return -1;
669  } else if (_M_cm & std::ios_base::in) {
670  off_type c;
671  state_type state = _M_st_last;
672  bool update_st = false;
673  if (_M_always_noconv) {
674  c = this->egptr() - this->gptr();
675  } else {
676  int width = _M_cv->encoding();
678  if (width > 0) {
679  c += width * (this->egptr() - this->gptr());
680  } else {
681  if (this->gptr() != this->egptr()) {
682  const int off = _M_cv->length(state, _M_extbuf,
683  _M_extbufnext,
684  this->gptr() - this->eback());
685  c += _M_extbufnext - _M_extbuf - off;
686  update_st = true;
687  }
688  }
689  }
690 #if _WIN32
691  if (fseek(_M_file_, -c, SEEK_CUR))
692  return -1;
693 #else
694  if (fseeko(_M_file, -c, SEEK_CUR))
695  return -1;
696 #endif
697  if (update_st)
698  _M_st = state;
700  this->setg(0, 0, 0);
701  _M_cm = std::ios_base::openmode(0);
702  }
703  return 0;
704 }
705 
707 template <class CharT, class Traits>
708 void
709 basic_filebuf<CharT, Traits>::imbue(const std::locale& loc) {
710  sync();
711  _M_cv = &std::use_facet<std::codecvt<char_type, char, state_type> >(loc);
712  bool old_anc = _M_always_noconv;
713  _M_always_noconv = _M_cv->always_noconv();
714  if (old_anc != _M_always_noconv) {
715  this->setg(0, 0, 0);
716  this->setp(0, 0);
717  // invariant, char_type is char, else we couldn't get here
718  // need to dump _M_intbuf
719  if (_M_always_noconv) {
720  if (_M_owns_eb)
721  delete [] _M_extbuf;
723  _M_ebs = _M_ibs;
724  _M_extbuf = reinterpret_cast<char*>(_M_intbuf);
725  _M_ibs = 0;
726  _M_intbuf = nullptr;
727  _M_owns_ib = false;
728  } else { // need to obtain an _M_intbuf.
729  // If _M_extbuf is user-supplied, use it, else new _M_intbuf
730  if (!_M_owns_eb && _M_extbuf != _M_extbuf_min) {
731  _M_ibs = _M_ebs;
732  _M_intbuf = reinterpret_cast<char_type*>(_M_extbuf);
733  _M_owns_ib = false;
734  _M_extbuf = new char[_M_ebs];
735  _M_owns_eb = true;
736  } else {
737  _M_ibs = _M_ebs;
738  _M_intbuf = new char_type[_M_ibs];
739  _M_owns_ib = true;
740  }
741  }
742  }
743 }
744 
746 template <class CharT, class Traits>
747 bool
749  if (!(_M_cm & std::ios_base::in)) {
750  this->setp(0, 0);
751  if (_M_always_noconv)
752  this->setg(reinterpret_cast<char_type*>(_M_extbuf),
753  reinterpret_cast<char_type*>(_M_extbuf) + _M_ebs,
754  reinterpret_cast<char_type*>(_M_extbuf) + _M_ebs);
755  else
756  this->setg(_M_intbuf, _M_intbuf + _M_ibs, _M_intbuf + _M_ibs);
757  _M_cm = std::ios_base::in;
758  return true;
759  }
760  return false;
761 }
762 
764 template <class CharT, class Traits>
765 void
767  if (!(_M_cm & std::ios_base::out)) {
768  this->setg(0, 0, 0);
769  if (_M_ebs > sizeof(_M_extbuf_min)) {
770  if (_M_always_noconv)
771  this->setp(reinterpret_cast<char_type*>(_M_extbuf),
772  reinterpret_cast<char_type*>(_M_extbuf) +
773  (_M_ebs - 1));
774  else
775  this->setp(_M_intbuf, _M_intbuf + (_M_ibs - 1));
776  } else {
777  this->setp(0, 0);
778  }
779  _M_cm = std::ios_base::out;
780  }
781 }
782 
784 }
785 
787 #endif // KALDI_UTIL_BASIC_FILEBUF_H_
788 
790 
791 /*
792  * ============================================================================
793  * libc++ License
794  * ============================================================================
795  *
796  * The libc++ library is dual licensed under both the University of Illinois
797  * "BSD-Like" license and the MIT license. As a user of this code you may
798  * choose to use it under either license. As a contributor, you agree to allow
799  * your code to be used under both.
800  *
801  * Full text of the relevant licenses is included below.
802  *
803  * ============================================================================
804  *
805  * University of Illinois/NCSA
806  * Open Source License
807  *
808  * Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT (included below)
809  *
810  * All rights reserved.
811  *
812  * Developed by:
813  *
814  * LLVM Team
815  *
816  * University of Illinois at Urbana-Champaign
817  *
818  * http://llvm.org
819  *
820  * Permission is hereby granted, free of charge, to any person obtaining a copy of
821  * this software and associated documentation files (the "Software"), to deal with
822  * the Software without restriction, including without limitation the rights to
823  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
824  * of the Software, and to permit persons to whom the Software is furnished to do
825  * so, subject to the following conditions:
826  *
827  * * Redistributions of source code must retain the above copyright notice,
828  * this list of conditions and the following disclaimers.
829  *
830  * * Redistributions in binary form must reproduce the above copyright notice,
831  * this list of conditions and the following disclaimers in the
832  * documentation and/or other materials provided with the distribution.
833  *
834  * * Neither the names of the LLVM Team, University of Illinois at
835  * Urbana-Champaign, nor the names of its contributors may be used to
836  * endorse or promote products derived from this Software without specific
837  * prior written permission.
838  *
839  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
840  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
841  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
842  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
843  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
844  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
845  * SOFTWARE.
846  *
847  * ==============================================================================
848  *
849  * Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT (included below)
850  *
851  * Permission is hereby granted, free of charge, to any person obtaining a copy
852  * of this software and associated documentation files (the "Software"), to deal
853  * in the Software without restriction, including without limitation the rights
854  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
855  * copies of the Software, and to permit persons to whom the Software is
856  * furnished to do so, subject to the following conditions:
857  *
858  * The above copyright notice and this permission notice shall be included in
859  * all copies or substantial portions of the Software.
860  *
861  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
862  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
863  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
864  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
865  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
866  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
867  * THE SOFTWARE.
868  *
869  * ==============================================================================
870  *
871  * This file is a partial list of people who have contributed to the LLVM/libc++
872  * project. If you have contributed a patch or made some other contribution to
873  * LLVM/libc++, please submit a patch to this file to add yourself, and it will be
874  * done!
875  *
876  * The list is sorted by surname and formatted to allow easy grepping and
877  * beautification by scripts. The fields are: name (N), email (E), web-address
878  * (W), PGP key ID and fingerprint (P), description (D), and snail-mail address
879  * (S).
880  *
881  * N: Saleem Abdulrasool
882  * E: compnerd@compnerd.org
883  * D: Minor patches and Linux fixes.
884  *
885  * N: Dimitry Andric
886  * E: dimitry@andric.com
887  * D: Visibility fixes, minor FreeBSD portability patches.
888  *
889  * N: Holger Arnold
890  * E: holgerar@gmail.com
891  * D: Minor fix.
892  *
893  * N: Ruben Van Boxem
894  * E: vanboxem dot ruben at gmail dot com
895  * D: Initial Windows patches.
896  *
897  * N: David Chisnall
898  * E: theraven at theravensnest dot org
899  * D: FreeBSD and Solaris ports, libcxxrt support, some atomics work.
900  *
901  * N: Marshall Clow
902  * E: mclow.lists@gmail.com
903  * E: marshall@idio.com
904  * D: C++14 support, patches and bug fixes.
905  *
906  * N: Bill Fisher
907  * E: william.w.fisher@gmail.com
908  * D: Regex bug fixes.
909  *
910  * N: Matthew Dempsky
911  * E: matthew@dempsky.org
912  * D: Minor patches and bug fixes.
913  *
914  * N: Google Inc.
915  * D: Copyright owner and contributor of the CityHash algorithm
916  *
917  * N: Howard Hinnant
918  * E: hhinnant@apple.com
919  * D: Architect and primary author of libc++
920  *
921  * N: Hyeon-bin Jeong
922  * E: tuhertz@gmail.com
923  * D: Minor patches and bug fixes.
924  *
925  * N: Argyrios Kyrtzidis
926  * E: kyrtzidis@apple.com
927  * D: Bug fixes.
928  *
929  * N: Bruce Mitchener, Jr.
930  * E: bruce.mitchener@gmail.com
931  * D: Emscripten-related changes.
932  *
933  * N: Michel Morin
934  * E: mimomorin@gmail.com
935  * D: Minor patches to is_convertible.
936  *
937  * N: Andrew Morrow
938  * E: andrew.c.morrow@gmail.com
939  * D: Minor patches and Linux fixes.
940  *
941  * N: Arvid Picciani
942  * E: aep at exys dot org
943  * D: Minor patches and musl port.
944  *
945  * N: Bjorn Reese
946  * E: breese@users.sourceforge.net
947  * D: Initial regex prototype
948  *
949  * N: Nico Rieck
950  * E: nico.rieck@gmail.com
951  * D: Windows fixes
952  *
953  * N: Jonathan Sauer
954  * D: Minor patches, mostly related to constexpr
955  *
956  * N: Craig Silverstein
957  * E: csilvers@google.com
958  * D: Implemented Cityhash as the string hash function on 64-bit machines
959  *
960  * N: Richard Smith
961  * D: Minor patches.
962  *
963  * N: Joerg Sonnenberger
964  * E: joerg@NetBSD.org
965  * D: NetBSD port.
966  *
967  * N: Stephan Tolksdorf
968  * E: st@quanttec.com
969  * D: Minor <atomic> fix
970  *
971  * N: Michael van der Westhuizen
972  * E: r1mikey at gmail dot com
973  *
974  * N: Klaas de Vries
975  * E: klaas at klaasgaaf dot nl
976  * D: Minor bug fix.
977  *
978  * N: Zhang Xiongpang
979  * E: zhangxiongpang@gmail.com
980  * D: Minor patches and bug fixes.
981  *
982  * N: Xing Xue
983  * E: xingxue@ca.ibm.com
984  * D: AIX port
985  *
986  * N: Zhihao Yuan
987  * E: lichray@gmail.com
988  * D: Standard compatibility fixes.
989  *
990  * N: Jeffrey Yasskin
991  * E: jyasskin@gmail.com
992  * E: jyasskin@google.com
993  * D: Linux fixes.
994  */
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
bool is_open() const
const std::codecvt< char_type, char, state_type > * _M_cv
Definition: basic-filebuf.h:75
char_type * _M_intbuf
Definition: basic-filebuf.h:72
int_type pbackfail(int_type c=traits_type::eof()) override
void swap(basic_filebuf< CharT, Traits > &x, basic_filebuf< CharT, Traits > &y)
std::basic_streambuf< char_type, traits_type > * setbuf(char_type *s, std::streamsize n) override
traits_type::int_type int_type
Definition: basic-filebuf.h:29
void imbue(const std::locale &loc) override
int sync() override
std::ios_base::openmode _M_cm
Definition: basic-filebuf.h:79
basic_filebuf * close()
struct rnnlm::@11::@12 n
basic_filebuf * open(const char *s, std::ios_base::openmode mode)
traits_type::pos_type pos_type
Definition: basic-filebuf.h:30
const char * _M_extbufnext
Definition: basic-filebuf.h:68
pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode wch=std::ios_base::in|std::ios_base::out) override
traits_type::off_type off_type
Definition: basic-filebuf.h:31
basic_filebuf & operator=(basic_filebuf &&rhs)
const char * _M_get_mode(std::ios_base::openmode mode)
void swap(basic_filebuf &rhs)
traits_type::state_type state_type
Definition: basic-filebuf.h:32
const char * _M_extbufend
Definition: basic-filebuf.h:69
int_type underflow() override
std::ios_base::openmode _M_om
Definition: basic-filebuf.h:78
int_type overflow(int_type c=traits_type::eof()) override
pos_type seekpos(pos_type sp, std::ios_base::openmode wch=std::ios_base::in|std::ios_base::out) override