libassa
3.5.0
|
00001 // -*- c++ -*- 00002 //------------------------------------------------------------------------------ 00003 // CharInBuffer.cpp 00004 //------------------------------------------------------------------------------ 00005 // Copyright (C) 2002 Vladislav Grinchenko 00006 // 00007 // This library is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Library General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 2 of the License, or (at your option) any later version. 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 Member functions 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()) { // Bug # 1252926 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_) { // EOF or error 00113 b_.state (CharInBuffer::error); 00114 } 00115 00116 return s_; 00117 } 00118 } // end namespace ASSA