Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

executable file 195 lines (158 sloc) 3.698 kb
#ifndef com_sleepless_linesocket_h
#define com_sleepless_linesocket_h
// Copyright 2004 Sleepless Software Inc. All Rights Reserved
#include <stdarg.h>
#include "socket.cpp"
#include "str.cpp"
struct LineSocket
{
Socket *sock;
int bufsize;
int mark;
char *rbuf;
char *msg;
char *wbuf;
// The 'bs' argument is the buffer size to
// allocate for the internal read and write buffers and should be
// the maximum length of any expected string to be read or written.
LineSocket(int bs)
{
sock = 0;
bufsize = bs;
mark = 0;
rbuf = new char[bufsize + 1];
memset(rbuf, 0, bufsize + 1);
msg = new char[bufsize + 1];
memset(msg, 0, bufsize + 1);
wbuf = new char[bufsize + 1];
memset(wbuf, 0, bufsize + 1);
}
// Attempt a connection to 'host':'port'
// returns true if connected successfully
int connect(const char *host, int port)
{
disconnect();
sock = new Socket(host, port);
return isConnected();
}
// This is useful for creating the server side endpoint.
int connect(Socket *s)
{
disconnect();
sock = s;
return isConnected();
}
// Disconnects, if connected.
void disconnect()
{
if(sock)
{
delete sock;
sock = 0;
}
}
// Deletes this object and disconnects the socket from the remote host.
~LineSocket()
{
disconnect();
}
// Returns true if this object is connected and ready to send/recv.
int isConnected()
{
return (sock && rbuf && msg && wbuf) ? sock->isConnected() : 0;
}
// Returns the next line of input from the socket or NULL if a full
// line hasn't yet arrived.
// The line will have the terminating "\r\n", as well as any leading
// and/or trailing white space stripped off and the
// string will be 0-terminated.
// This returns a pointer to an internal buffer that will be over-
// written on the next call.
const char *readLine()
{
if(isConnected())
{
int a = sock->available(); // get # of bytes avail to read
if(a > 0)
{
if((mark + a) > (int)bufsize)
a = bufsize - mark;
int r = sock->read(rbuf + mark, a);
if(r == a)
{
mark += a;
if(mark == bufsize)
{
rbuf[bufsize - 1] = '\n';
}
}
else
{
// read error
delete sock;
sock = 0;
}
}
if(mark > 0)
{
msg[0] = 0;
for(int j = 0; j < mark; j++)
{
if(rbuf[j] == 0x0d) // change CR's to spaces
rbuf[j] = ' ';
if(rbuf[j] == 0x0a) // change LF's to 0's
rbuf[j] = 0;
if(rbuf[j] == 0) // If char is 0, end of str
{
strcpy(msg, rbuf);
j++;
memcpy(rbuf, rbuf + j, mark - j);
mark -= j;
Str::trim(msg);
break;
}
}
if(msg[0])
{
return msg; // got a msg.
}
}
}
return NULL;
}
// Returns 0 if the timeout of tosecs expires.
// Returns -1 if an error occured.
// Otherwise, returns # of bytes available to read on the socket.
// To wait forever, pass a 0 for tosecs.
int waitForData(int tosecs)
{
return sock->waitForData(tosecs);
}
/* Writes a formatted line of text to the socket.
A "\r\n" line terminator is automatically appended so caller
doesn't have to do that.
It is the caller's responbility to be careful that the formatted
string, plus the terminating "\r\n" does not overflow the
buffer size given in the constructor.
*/
int writeLine(const char *fmt, ...)
{
if(isConnected())
{
va_list marker;
va_start(marker, fmt);
vsprintf(wbuf, fmt, marker);
strcat(wbuf, "\n");
int l = strlen(wbuf);
int r = sock->write(wbuf, l);
va_end(marker);
if(r != l)
{
delete sock;
sock = 0;
}
}
return isConnected();
}
};
#endif // com_sleepless_linesocket_h
Jump to Line
Something went wrong with that request. Please try again.