Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "ibrcommon/data/iobuffer.h"
00009 #include "ibrcommon/thread/MutexLock.h"
00010 #include <string.h>
00011
00012 namespace ibrcommon
00013 {
00014 iobuffer::iobuffer(const size_t buffer)
00015 : _eof(false), _data_size(0), _buf_size(buffer), _input_buf(new char[buffer]), _interim_buf(new char[buffer]), _output_buf(new char[buffer])
00016 {
00017
00018 setg(0, 0, 0);
00019 setp(_input_buf, _input_buf + _buf_size - 1);
00020 }
00021
00022 iobuffer::~iobuffer()
00023 {
00024 delete[] _input_buf;
00025 delete[] _output_buf;
00026 delete[] _interim_buf;
00027 }
00028
00029 void iobuffer::finalize()
00030 {
00031 ibrcommon::MutexLock l(_data_cond);
00032 _eof = true;
00033 _data_cond.signal(true);
00034 }
00035
00036 int iobuffer::sync()
00037 {
00038 int ret = std::char_traits<char>::eq_int_type(this->overflow(
00039 std::char_traits<char>::eof()), std::char_traits<char>::eof()) ? -1
00040 : 0;
00041
00042 return ret;
00043 }
00044
00045 int iobuffer::overflow(int c)
00046 {
00047 char *ibegin = _input_buf;
00048 char *iend = pptr();
00049
00050
00051 setp(_input_buf, _input_buf + _buf_size - 1);
00052
00053 if (!std::char_traits<char>::eq_int_type(c, std::char_traits<char>::eof()))
00054 {
00055 *iend++ = std::char_traits<char>::to_char_type(c);
00056 }
00057
00058
00059 if ((iend - ibegin) == 0)
00060 {
00061 return std::char_traits<char>::not_eof(c);
00062 }
00063
00064 ibrcommon::MutexLock l(_data_cond);
00065
00066
00067 while (_data_size > 0) _data_cond.wait();
00068
00069
00070 _data_size = (iend - ibegin);
00071
00072
00073 ::memcpy(_interim_buf, _input_buf, _data_size);
00074
00075
00076 _data_cond.signal(true);
00077
00078 return std::char_traits<char>::not_eof(c);
00079 }
00080
00081 int iobuffer::underflow()
00082 {
00083 ibrcommon::MutexLock l(_data_cond);
00084
00085
00086 while (_data_size == 0)
00087 {
00088
00089 if (_eof) return std::char_traits<char>::eof();
00090
00091 _data_cond.wait();
00092 }
00093
00094
00095 ::memcpy(_output_buf, _interim_buf, _data_size);
00096
00097
00098
00099 setg(_output_buf, _output_buf, _output_buf + _data_size);
00100
00101
00102 _data_size = 0;
00103 _data_cond.signal(true);
00104
00105 return std::char_traits<char>::not_eof(_output_buf[0]);
00106 }
00107 }