mirror of
https://github.com/ksherlock/gopher.git
synced 2024-12-21 06:29:39 +00:00
readline improvements
This commit is contained in:
parent
ac6eadd9c0
commit
d388292da6
108
readline2.c
108
readline2.c
@ -75,64 +75,87 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
|
||||
{
|
||||
userRecordHandle urh;
|
||||
userRecordPtr ur;
|
||||
|
||||
rrBuff rb;
|
||||
|
||||
|
||||
|
||||
char *cp;
|
||||
Handle h;
|
||||
LongWord hsize;
|
||||
LongWord size;
|
||||
Word term;
|
||||
Word tlen;
|
||||
Word rv;
|
||||
Word tlen;
|
||||
Word state;
|
||||
|
||||
if (!buffer) return -1;
|
||||
|
||||
buffer->handle = NULL;
|
||||
buffer->size = 0;
|
||||
if (!buffer) return 0; // ?
|
||||
|
||||
buffer->bufferhandle = NULL;
|
||||
buffer->bufferSize = 0;
|
||||
buffer->terminator = 0;
|
||||
buffer->moreFlag = 0;
|
||||
|
||||
urh = TCPIPGetUserRecord(ipid);
|
||||
if (_toolErr || !urh) return -1;
|
||||
if (_toolErr || !urh) return 0;
|
||||
|
||||
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;
|
||||
|
||||
hsize = GetHandleSize(h);
|
||||
size = find_crlf(cp, hsize);
|
||||
|
||||
if (size & 0x8000000)
|
||||
if (!hsize)
|
||||
{
|
||||
// not found.
|
||||
// if closing, return data as-is w/o terminator?
|
||||
|
||||
if (state > TCPSCLOSEWAIT) return tcperrConClosing;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = find_crlf(cp, hsize);
|
||||
|
||||
hsize -= size;
|
||||
cp += size;
|
||||
|
||||
// check for \r\n
|
||||
term = *(Word *)cp;
|
||||
if (term == 0x0a0d && hsize >= 2)
|
||||
// -1 = not found.
|
||||
if (size == 0xffffffff)
|
||||
{
|
||||
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
|
||||
{
|
||||
term &= 0x00ff;
|
||||
tlen = 1;
|
||||
{
|
||||
hsize -= size;
|
||||
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 will stop reading if there was a push.
|
||||
// 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
|
||||
// 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;
|
||||
h = NewHandle(hsize, ur->uwUserID, attrNoSpec | attrLocked, 0);
|
||||
if (_toolErr) return -1;
|
||||
if (_toolErr) return tcperrNoResources;
|
||||
|
||||
buffer->size = size;
|
||||
buffer->handle = h;
|
||||
buffer->bufferSize = size;
|
||||
buffer->bufferHandle = h;
|
||||
buffer->term = term;
|
||||
|
||||
cp = *(char **)h;
|
||||
|
||||
while (hsize)
|
||||
{
|
||||
Word rv;
|
||||
rrBuff 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;
|
||||
cp += rb.rrBuffCount
|
||||
cp += rb.rrBuffCount;
|
||||
|
||||
buffer->moreFlag = rb.rrMoreFlag;
|
||||
// should never hang in an infinite loop.
|
||||
}
|
||||
|
||||
if (tlen)
|
||||
@ -170,7 +203,7 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
|
||||
if (!size)
|
||||
{
|
||||
DisposeHandle(h);
|
||||
buffer->handle = 0;
|
||||
buffer->bufferHandle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -178,5 +211,6 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
// will be conclosing or 0.
|
||||
return ur->uwTCP_ErrCode;
|
||||
}
|
@ -12,9 +12,10 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct rlBuffer {
|
||||
Handle handle;
|
||||
LongWord size;
|
||||
Handle bufferHandle;
|
||||
LongWord bufferSize;
|
||||
Word terminator;
|
||||
Word moreFlag;
|
||||
} rlBuffer;
|
||||
|
||||
Word ReadLine2(Word ipid, rlBuffer *buffer);
|
||||
|
Loading…
Reference in New Issue
Block a user