// Socket.C -*- C++ -*-
+// Copyright (C) 2002 Clinton Ebadi
// Copyright (c) 1997, 1998 Etienne BERNARD
// This program is free software; you can redistribute it and/or modify
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "Socket.H"
+#include "Bot.H"
+#include <string>
#include <sys/types.h>
#include <sys/socket.h>
addr.sin_addr.s_addr = htonl(remoteAddress);
addr.sin_port = htons(remotePort);
if (::connect(fd->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
- return false;
+ {
+ // Bot::logLine (String("Socket Error: ")
+ // + strerror (errno) + String("\n"));
+ return false;
+ }
return true;
}
String
Socket::readLine()
{
- static char buf[512];
- int pos = 0, nb;
- char r;
+ // fixme: this could probably be sped up (use some faster way of
+ // reading from the socket than reading a char at a time)
+
+ // We allocate the buffer statically to keep from having to overhead
+ // of reallocating a new buffer every time we call this (which is
+ // every time anything happens on IRC so the overhead of
+ // re-allocating a buffer every time is potentially too large).
+ //
+ // Since it is static, and the length of lines will differ for each
+ // read, an embedded \0 is inserted after the last character of the
+ // line and then a copy of the the c_str is returned as a String so
+ // that only the line that was just read is returned.
+ static std::string buf (512, ' ');
+
+ std::string::size_type pos = 0; // pos in buffer
+ int nb; // number of bytes read by ::read
+ char r; // temp var for storing output of read into
+ std::string::size_type length = buf.length ();
- do {
- nb = ::read(fd->fd, &r, 1);
- switch (nb) {
- case 0:
- return String("");
- case -1:
- if (errno != EINTR && errno != EAGAIN)
- return String("");
- sleep(1);
- }
-
- if (nb != -1)
- buf[pos++] = r;
- } while (r != '\n');
+ do
+ {
+ nb = ::read(fd->fd, &r, 1);
+ switch (nb) {
+ case 0:
+ return String("");
+ case -1:
+ if (errno != EINTR && errno != EAGAIN)
+ return String("");
+ sleep(1);
+ }
+
+ if (nb != -1)
+ if (pos < length)
+ buf[pos++] = r;
+ else
+ {
+ buf.resize (length * 2);
+ length = buf.length ();
+ buf[pos++] = r;
+ }
+ } while (r != '\n');
if (pos > 1 && buf[pos-2] == '\r')
buf[pos-2] = '\0';
else
buf[pos-1] = '\0';
-
- return String(buf);
+
+ // c_str () is used because the String constructor for std::string
+ // will copy the entire std::string into it when we only want it to
+ // copy up to the first null.
+ return String (buf.c_str ());
}
String