00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <errno.h>
00014
00015 #include "assa/CharInBuffer.h"
00016 #include "assa/MemDump.h"
00017 #include "assa/Logger.h"
00018
00019 using namespace ASSA;
00020
00021
00022
00023
00024 CharInBuffer::
00025 CharInBuffer (size_t size_, const string& delimiter_)
00026 : m_state (start), m_max_size (size_), m_delimiter (delimiter_)
00027 {
00028 trace_with_mask ("CharInBuffer::CharInBuffer", CHARINBUF);
00029
00030 if (m_max_size == 0 || m_delimiter.length () == 0) {
00031 state (error);
00032 }
00033 state (waiting);
00034 }
00035
00036 const char*
00037 CharInBuffer::
00038 state_name (state_t state_)
00039 {
00040 static const char* vmsg[] =
00041 { "start", "waiting", "complete", "error", "unknown state" };
00042
00043 if (state_ < CharInBuffer::start || state_ > CharInBuffer::error) {
00044 return vmsg [sizeof (vmsg)-1];
00045 }
00046 return vmsg [state_];
00047 }
00048
00049 void
00050 CharInBuffer::
00051 dump () const
00052 {
00053 DL((CHARINBUF,"== CharInBuffer state ==\n"));
00054 DL((CHARINBUF,"m_state = %s\n", state_name (m_state)));
00055 DL((CHARINBUF,"m_max_size = %d\n", m_max_size));
00056
00057 MemDump::dump_to_log (TRACE, "m_delimiter:\n",
00058 m_delimiter.c_str (), m_delimiter.length ());
00059
00060 MemDump::dump_to_log (TRACE, "m_buffer:\n",
00061 m_buffer.c_str (), m_buffer.length ());
00062
00063 DL((CHARINBUF,"========================\n"));
00064 }
00065
00066 namespace ASSA {
00067
00079 Socket&
00080 operator>> (Socket& s_, CharInBuffer& b_)
00081 {
00082 trace_with_mask ("Socket >> CharInBuffer", CHARINBUF);
00083 register char c;
00084
00085 if (b_.state () != CharInBuffer::waiting) {
00086 DL((CHARINBUF,"Wrong state %s\n", b_.state_name (b_.state ())));
00087 return s_;
00088 }
00089
00090 while (s_.read (&c, 1) == 1)
00091 {
00092 b_.m_buffer += c;
00093
00094 if (b_.m_buffer.size() < b_.m_delimiter.size()) {
00095 continue;
00096 }
00097
00098 if (b_.m_buffer.substr (
00099 b_.m_buffer.size ()-b_.m_delimiter.size ()) == b_.m_delimiter)
00100 {
00101 b_.chop ();
00102 b_.m_state = CharInBuffer::complete;
00103 return s_;
00104 }
00105
00106 if (b_.m_buffer.length () >= b_.m_max_size) {
00107 b_.m_state = CharInBuffer::error;
00108 break;
00109 }
00110 }
00111
00112 if (!s_) {
00113 b_.state (CharInBuffer::error);
00114 }
00115
00116 return s_;
00117 }
00118 }