IBR-DTNSuite  0.8
ibrcommon/ibrcommon/appstreambuf.cpp
Go to the documentation of this file.
00001 /*
00002  * appstreambuf.cpp
00003  *
00004  *  Created on: 20.11.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "ibrcommon/config.h"
00009 #include "ibrcommon/appstreambuf.h"
00010 
00011 namespace ibrcommon
00012 {
00013         appstreambuf::appstreambuf(std::string command, appstreambuf::Mode mode)
00014          : m_buf( BUF_SIZE+1 )
00015         {
00016                 // execute the command
00017                 if (mode == MODE_READ)
00018                 {
00019                         setg(0, 0, 0);
00020                         _handle = popen(command.c_str(), "r");
00021                 }
00022                 else
00023                 {
00024                         setp( &m_buf[0], &m_buf[0] + (m_buf.size() - 1) );
00025                         _handle = popen(command.c_str(), "w");
00026                 }
00027         }
00028 
00029         appstreambuf::~appstreambuf()
00030         {
00031                 // close the handle
00032                 pclose(_handle);
00033         }
00034 
00035         std::char_traits<char>::int_type appstreambuf::underflow()
00036         {
00037                 // read the stdout of the process
00038                 size_t ret = 0;
00039 
00040                 if (feof(_handle))
00041                         return std::char_traits<char>::eof();
00042 
00043                 ret = fread(&m_buf[0], sizeof(char), m_buf.size(), _handle);
00044 
00045                 // Since the input buffer content is now valid (or is new)
00046                 // the get pointer should be initialized (or reset).
00047                 setg(&m_buf[0], &m_buf[0], &m_buf[0] + ret);
00048 
00049                 return std::char_traits<char>::not_eof((unsigned char) m_buf[0]);
00050         }
00051 
00052         int appstreambuf::sync()
00053         {
00054                 int ret = std::char_traits<char>::eq_int_type(this->overflow(std::char_traits<char>::eof()),
00055                                 std::char_traits<char>::eof()) ? -1 : 0;
00056 
00057                 return ret;
00058         }
00059 
00060         std::char_traits<char>::int_type appstreambuf::overflow( std::char_traits<char>::int_type m )
00061         {
00062                 char *ibegin = pbase();
00063                 char *iend = pptr();
00064 
00065                 // if there is nothing to send, just return
00066                 if ( iend <= ibegin ) return std::char_traits<char>::not_eof(m);
00067 
00068                 // mark the buffer as free
00069                 setp( &m_buf[0], &m_buf[0] + (m_buf.size() - 1) );
00070 
00071                 if(!std::char_traits<char>::eq_int_type(m, std::char_traits<char>::eof())) {
00072                         *iend++ = std::char_traits<char>::to_char_type(m);
00073                 }
00074 
00075                 // write the data
00076                 int ret = 0;
00077                 if ((ret = fwrite(pbase(), sizeof(char), (iend - ibegin), _handle)) != (iend - ibegin))
00078                 {
00079                         return std::char_traits<char>::eof();
00080                 }
00081 
00082                 return std::char_traits<char>::not_eof(m);
00083         }
00084 }