00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <sstream>
00040
00041 #include "consmgr.h"
00042 #include "history.h"
00043 #include "guard.h"
00044
00048 History::History(const int size) : lines(size), start_a_new_line(true)
00049 {
00050
00051 Guard::initialize_mutex(buf_mutex);
00052 return;
00053 }
00054
00055 History::~History()
00056 {
00057 disconnect();
00058 Guard::destroy_mutex(buf_mutex);
00059 }
00060
00061 #if 0
00062 void
00063 History::notify_on_disconnect(const Messageable *owner)
00064 {
00065 add_recipient(owner);
00066 }
00067 #endif
00068
00070 std::string
00071 History::get_id(void) const
00072 {
00073 std::ostringstream id_str;
00074
00075 id_str << "History(" << lines.size() << "/" << lines.max_size() << ")";
00076
00077 return(id_str.str());
00078 }
00079
00080 Data *
00081 History::read()
00082 {
00083 throw(fireball(28, "History::read() not implemented [yet]!"));
00084 }
00085
00086 ssize_t
00087 History::write(const Data &d)
00088 {
00089 const u_char *dptr = d.data(), *end = (dptr + d.len());
00090 int ret;
00091
00092 clog << "History::write()" << endl;
00093
00094
00095 ret = pthread_mutex_lock(&buf_mutex);
00096 PTHREAD_CHECK_AND_THROW(ret, "mutex_lock(buf_mutex)");
00097
00098
00099
00100
00101 string last_line;
00102
00103 if (start_a_new_line || lines.empty())
00104 last_line = "";
00105 else {
00106
00107
00108 last_line = lines.back();
00109 lines.pop_back();
00110 }
00111
00112
00113
00114 u_char *sol = NULL;
00115
00116 for ( u_char *eol = const_cast<u_char*>(dptr) ; eol <= end ; eol++ ) {
00117 if (sol == NULL)
00118 sol = eol;
00119 if (*eol == '\n') {
00120
00121
00122
00123 while ((eol > sol) && (*(eol-1) == '\r'))
00124 eol--;
00125
00126
00127 if (last_line.length() > 0) {
00128
00129 lines.push_back(last_line +
00130 string(reinterpret_cast<const char*>(sol),
00131 (eol-sol)));
00132 last_line = "";
00133 } else
00134 lines.push_back(string(reinterpret_cast<const char*>(sol),
00135 (eol-sol)));
00136
00137 while (*eol == '\r')
00138 eol++;
00139 sol = NULL;
00140 }
00141 }
00142
00143
00144
00145 if (sol == NULL)
00146 start_a_new_line = true;
00147 else {
00148 lines.push_back(last_line +
00149 string(reinterpret_cast<const char*>(sol), (end-sol)));
00150 start_a_new_line = false;
00151 }
00152
00153
00154 ret = pthread_mutex_unlock(&buf_mutex);
00155 PTHREAD_CHECK_AND_THROW(ret, "mutex_unlock(buf_mutex)");
00156
00157
00158 clog << "Now " << lines.size() << " lines in " << this->get_id()
00159 << ": [[[" << endl;
00160 for (std::vector<string>::iterator vi = lines.begin() ; vi < lines.end() ;
00161 vi++)
00162 clog << " |" << *vi << "|" << endl;
00163 clog << "]]]" << endl;
00164
00165 return d.len();
00166 }
00167
00172 void
00173 History::disconnect(void)
00174 {
00175 Guard locker(&buf_mutex);
00176
00177 lines.clear();
00178
00179 return;
00180 }