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 Socket&
00068 operator>> (Socket& s_, CharInBuffer& b_)
00069 {
00070 trace_with_mask ("Socket >> CharInBuffer", CHARINBUF);
00071 register char c;
00072
00073 if (b_.state () != CharInBuffer::waiting) {
00074 DL((CHARINBUF,"Wrong state %s\n", b_.state_name (b_.state ())));
00075 return s_;
00076 }
00088 while (s_.read (&c, 1) == 1) {
00089 b_.m_buffer += c;
00090
00091 if (b_.m_buffer.size() < b_.m_delimiter.size()) {
00092 continue;
00093 }
00094
00095 if (b_.m_buffer.substr (
00096 b_.m_buffer.size ()-b_.m_delimiter.size ()) == b_.m_delimiter)
00097 {
00098 b_.chop ();
00099 b_.m_state = CharInBuffer::complete;
00100 return s_;
00101 }
00102
00103 if (b_.m_buffer.length () >= b_.m_max_size) {
00104 b_.m_state = CharInBuffer::error;
00105 break;
00106 }
00107 }
00108
00109 if (!s_) {
00110 b_.state (CharInBuffer::error);
00111 }
00112
00113 return s_;
00114 }
00115 }