readline improvements

This commit is contained in:
Kelvin Sherlock 2012-04-08 21:29:03 -04:00
parent ac6eadd9c0
commit d388292da6
2 changed files with 74 additions and 39 deletions

View File

@ -75,64 +75,87 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
{ {
userRecordHandle urh; userRecordHandle urh;
userRecordPtr ur; userRecordPtr ur;
rrBuff rb;
char *cp; char *cp;
Handle h; Handle h;
LongWord hsize; LongWord hsize;
LongWord size; LongWord size;
Word term; Word term;
Word tlen; Word tlen;
Word rv; Word state;
if (!buffer) return -1;
buffer->handle = NULL; if (!buffer) return 0; // ?
buffer->size = 0;
buffer->bufferhandle = NULL;
buffer->bufferSize = 0;
buffer->terminator = 0; buffer->terminator = 0;
buffer->moreFlag = 0;
urh = TCPIPGetUserRecord(ipid); urh = TCPIPGetUserRecord(ipid);
if (_toolErr || !urh) return -1; if (_toolErr || !urh) return 0;
ur = *urh; ur = *urh;
h = (Handle *)ur->uwTCPDataIn;
if (!h) return 0; state = ur->uwTCP_State;
// TCPREAD returns these errors.
if (state == TCPSCLOSED) return tcperrBadConnection;
if (state < TCPSESTABLISHED) return tcperrNoResources;
h = (Handle *)ur->uwTCPDataIn;
// should never happen....
if (!h) return tcperrNoResources;
cp = *(char **)h; cp = *(char **)h;
hsize = GetHandleSize(h); hsize = GetHandleSize(h);
size = find_crlf(cp, hsize);
if (size & 0x8000000) if (!hsize)
{ {
// not found. if (state > TCPSCLOSEWAIT) return tcperrConClosing;
// if closing, return data as-is w/o terminator?
return 0; return 0;
} }
size = find_crlf(cp, hsize);
hsize -= size; // -1 = not found.
cp += size; if (size == 0xffffffff)
// check for \r\n
term = *(Word *)cp;
if (term == 0x0a0d && hsize >= 2)
{ {
tlen = 2;
// if state >= CLOSEWAIT, assume no more data incoming
// and return as-is w/o terminator.
// if state < TCPSCLOSEWAIT, the terminator has not yet been
// received, so don't return anything.
// tcpread does an implied push if state == tcpsCLOSEWAIT
if (state < TCPSCLOSEWAIT)
{
buffer->moreFlag = 1;
return 0;
}
term = 0;
tlen = 0;
} }
else else
{ {
term &= 0x00ff; hsize -= size;
tlen = 1; cp += size;
// check for \r\n
term = *(Word *)cp;
if (term == 0x0a0d && hsize >= 2)
{
tlen = 2;
}
else
{
term &= 0x00ff;
tlen = 1;
}
} }
//buffer->size = size;
//buffer->term = term;
// read the data. // read the data.
// read will stop reading if there was a push. // read will stop reading if there was a push.
// if using \r\n, there could be something stupid like a push in the middle, // if using \r\n, there could be something stupid like a push in the middle,
@ -142,23 +165,33 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
// 99% of the time, it should just be one read, but generating the handle now // 99% of the time, it should just be one read, but generating the handle now
// and reading into a pointer keeps it simpler for the case where that is not the case. // and reading into a pointer keeps it simpler for the case where that is not the case.
// size = data to return
// hsize = data to read.
hsize = size + tlen; hsize = size + tlen;
h = NewHandle(hsize, ur->uwUserID, attrNoSpec | attrLocked, 0); h = NewHandle(hsize, ur->uwUserID, attrNoSpec | attrLocked, 0);
if (_toolErr) return -1; if (_toolErr) return tcperrNoResources;
buffer->size = size; buffer->bufferSize = size;
buffer->handle = h; buffer->bufferHandle = h;
buffer->term = term; buffer->term = term;
cp = *(char **)h; cp = *(char **)h;
while (hsize) while (hsize)
{ {
Word rv;
rrBuff rb;
rv = TCPIPReadTCP(ipid, 0, cp, hsize, &rb); rv = TCPIPReadTCP(ipid, 0, cp, hsize, &rb);
// break on tcp error? // tcperrConClosing is the only possible error
// (others were handled above via the state).
hsize -= rb.rrBuffCount; hsize -= rb.rrBuffCount;
cp += rb.rrBuffCount cp += rb.rrBuffCount;
buffer->moreFlag = rb.rrMoreFlag;
// should never hang in an infinite loop.
} }
if (tlen) if (tlen)
@ -170,7 +203,7 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
if (!size) if (!size)
{ {
DisposeHandle(h); DisposeHandle(h);
buffer->handle = 0; buffer->bufferHandle = 0;
} }
else else
{ {
@ -178,5 +211,6 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
} }
} }
return 1; // will be conclosing or 0.
return ur->uwTCP_ErrCode;
} }

View File

@ -12,9 +12,10 @@ enum {
}; };
typedef struct rlBuffer { typedef struct rlBuffer {
Handle handle; Handle bufferHandle;
LongWord size; LongWord bufferSize;
Word terminator; Word terminator;
Word moreFlag;
} rlBuffer; } rlBuffer;
Word ReadLine2(Word ipid, rlBuffer *buffer); Word ReadLine2(Word ipid, rlBuffer *buffer);