2012-05-09 21:21:41 +04:00
|
|
|
/*
|
|
|
|
* This class creates c++ like stream from file descriptor
|
2013-11-15 15:56:00 +04:00
|
|
|
* It uses gcc-specific functions, therefore is not portable
|
|
|
|
*
|
|
|
|
* Jeroen Vermeulen reckons that it can be replaced with Boost's io::stream_buffer
|
|
|
|
*
|
2012-05-09 21:21:41 +04:00
|
|
|
*/
|
|
|
|
|
2013-11-15 15:56:00 +04:00
|
|
|
|
2012-05-09 21:21:41 +04:00
|
|
|
#ifndef _FDSTREAM_
|
|
|
|
#define _FDSTREAM_
|
|
|
|
|
|
|
|
#include <iostream>
|
2012-05-10 01:57:44 +04:00
|
|
|
#include <string>
|
|
|
|
|
2012-05-09 21:21:41 +04:00
|
|
|
#if defined(__GLIBCXX__) || defined(__GLIBCPP__)
|
|
|
|
#include <ext/stdio_filebuf.h>
|
|
|
|
|
2015-05-20 07:40:11 +03:00
|
|
|
#include "util/file.hh"
|
|
|
|
|
2012-05-10 02:08:54 +04:00
|
|
|
#define BUFFER_SIZE (32768)
|
2012-05-09 21:21:41 +04:00
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
namespace MosesTuning
|
2012-06-30 23:23:45 +04:00
|
|
|
{
|
|
|
|
|
2012-05-09 21:21:41 +04:00
|
|
|
class _fdstream
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
_fdstream() :
|
2015-05-20 07:40:11 +03:00
|
|
|
_file_descriptor(), _filebuf(NULL) {
|
2013-06-10 21:11:55 +04:00
|
|
|
}
|
2012-05-09 21:21:41 +04:00
|
|
|
|
2012-05-10 01:57:44 +04:00
|
|
|
_fdstream(int file_descriptor, std::ios_base::openmode openmode) :
|
2015-05-20 07:40:11 +03:00
|
|
|
_file_descriptor(-1), _openmode(openmode) {
|
2012-05-09 21:21:41 +04:00
|
|
|
_filebuf = NULL;
|
|
|
|
open(file_descriptor, openmode);
|
2015-05-20 07:40:11 +03:00
|
|
|
_file_descriptor.reset(file_descriptor);
|
2012-05-09 21:21:41 +04:00
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
std::ios_base::openmode openmode() const {
|
|
|
|
return _openmode;
|
|
|
|
}
|
2012-05-09 21:21:41 +04:00
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
void open(int file_descriptor, std::ios_base::openmode openmode) {
|
2015-05-20 07:40:11 +03:00
|
|
|
// TODO: How does file_descriptor relate to the one we already have?
|
|
|
|
// Should we reset our own _file_descriptor to match it?
|
|
|
|
if (!_filebuf) {
|
2012-05-09 21:21:41 +04:00
|
|
|
// We create a C++ stream from a file descriptor
|
|
|
|
// stdio_filebuf is not synced with stdio.
|
|
|
|
// From GCC 3.4.0 on exists in addition stdio_sync_filebuf
|
|
|
|
// You can also create the filebuf from a FILE* with
|
|
|
|
// FILE* f = fdopen(file_descriptor, mode);
|
|
|
|
_filebuf = new __gnu_cxx::stdio_filebuf<char> (file_descriptor,
|
2013-05-29 21:16:15 +04:00
|
|
|
openmode);
|
2015-05-20 07:40:11 +03:00
|
|
|
}
|
2012-05-09 21:21:41 +04:00
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
virtual ~_fdstream() {
|
2012-05-09 21:21:41 +04:00
|
|
|
delete _filebuf;
|
|
|
|
_filebuf = NULL;
|
|
|
|
}
|
|
|
|
|
2015-05-20 07:40:11 +03:00
|
|
|
private:
|
|
|
|
util::scoped_fd _file_descriptor;
|
2012-05-09 21:21:41 +04:00
|
|
|
__gnu_cxx::stdio_filebuf<char>* _filebuf;
|
2012-05-10 01:57:44 +04:00
|
|
|
std::ios_base::openmode _openmode;
|
2015-05-20 07:40:11 +03:00
|
|
|
|
|
|
|
protected:
|
|
|
|
/// For child classes only: retrieve filebuf.
|
2015-06-04 15:41:46 +03:00
|
|
|
__gnu_cxx::stdio_filebuf<char> *get_filebuf() {
|
|
|
|
return _filebuf;
|
|
|
|
}
|
2012-05-09 21:21:41 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
class ifdstream : public _fdstream
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ifdstream() :
|
2013-06-10 21:11:55 +04:00
|
|
|
_fdstream(), _stream(NULL) {
|
|
|
|
}
|
2012-05-09 21:21:41 +04:00
|
|
|
|
|
|
|
ifdstream(int file_descriptor) :
|
2013-05-29 21:16:15 +04:00
|
|
|
_fdstream(file_descriptor, std::ios_base::in) {
|
2015-05-20 07:40:11 +03:00
|
|
|
_stream = new std::istream(get_filebuf());
|
2012-05-09 21:21:41 +04:00
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
void open(int file_descriptor) {
|
|
|
|
if (!_stream) {
|
|
|
|
_fdstream::open(file_descriptor, std::ios_base::in);
|
2015-05-20 07:40:11 +03:00
|
|
|
_stream = new std::istream(get_filebuf());
|
2013-05-29 21:16:15 +04:00
|
|
|
}
|
2012-05-09 21:21:41 +04:00
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
ifdstream& operator>> (std::string& str) {
|
2012-05-09 21:21:41 +04:00
|
|
|
(*_stream) >> str;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
std::size_t getline(std::string& str) {
|
2012-05-09 21:21:41 +04:00
|
|
|
char tmp[BUFFER_SIZE];
|
2012-05-10 01:57:44 +04:00
|
|
|
std::size_t ret = getline(tmp, BUFFER_SIZE);
|
2012-05-09 21:21:41 +04:00
|
|
|
str = tmp;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
std::size_t getline(char* s, std::streamsize n) {
|
2012-05-09 21:21:41 +04:00
|
|
|
return (getline(s, n, '\n'));
|
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
std::size_t getline(char* s, std::streamsize n, char delim) {
|
2012-05-09 21:21:41 +04:00
|
|
|
int i = 0;
|
2013-05-29 21:16:15 +04:00
|
|
|
do {
|
2012-05-09 21:21:41 +04:00
|
|
|
s[i] = _stream->get();
|
|
|
|
i++;
|
2013-05-29 21:16:15 +04:00
|
|
|
} while(i < n-1 && s[i-1] != delim && s[i-1] != '\0');
|
2012-05-09 21:21:41 +04:00
|
|
|
|
|
|
|
s[i-1] = '\0'; // overwrite the delimiter given with string end
|
|
|
|
|
|
|
|
return i-1;
|
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
~ifdstream() {
|
2012-05-09 21:21:41 +04:00
|
|
|
//this->~_fdstream();
|
|
|
|
delete _stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2012-05-10 01:57:44 +04:00
|
|
|
std::istream* _stream;
|
2012-05-09 21:21:41 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
class ofdstream : public _fdstream
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ofdstream() :
|
2013-06-10 21:11:55 +04:00
|
|
|
_fdstream(), _stream(NULL) {
|
|
|
|
}
|
2012-05-09 21:21:41 +04:00
|
|
|
|
|
|
|
ofdstream(int file_descriptor) :
|
2013-05-29 21:16:15 +04:00
|
|
|
_fdstream(file_descriptor, std::ios_base::out) {
|
2015-05-20 07:40:11 +03:00
|
|
|
_stream = new std::ostream(get_filebuf());
|
2012-05-09 21:21:41 +04:00
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
void open(int file_descriptor) {
|
|
|
|
if (!_stream) {
|
2012-05-10 01:57:44 +04:00
|
|
|
_fdstream::open(file_descriptor, std::ios_base::out);
|
2015-05-20 07:40:11 +03:00
|
|
|
_stream = new std::ostream(get_filebuf());
|
2012-05-10 01:57:44 +04:00
|
|
|
}
|
2012-05-09 21:21:41 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
ofdstream& operator<< (const std::string& str) {
|
2012-05-09 21:21:41 +04:00
|
|
|
if (_stream->good())
|
|
|
|
(*_stream) << str;
|
|
|
|
|
|
|
|
_stream->flush();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2013-05-29 21:16:15 +04:00
|
|
|
~ofdstream() {
|
2012-05-09 21:21:41 +04:00
|
|
|
//this->~_fdstream();
|
|
|
|
delete _stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2012-05-10 01:57:44 +04:00
|
|
|
std::ostream* _stream;
|
2012-05-09 21:21:41 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#else
|
|
|
|
#error "Not supported"
|
|
|
|
#endif
|
|
|
|
|
2012-06-30 23:23:45 +04:00
|
|
|
}
|
|
|
|
|
2012-05-09 21:21:41 +04:00
|
|
|
#endif // _FDSTREAM_
|