mirror of
https://github.com/ksherlock/gopher.git
synced 2024-12-21 21:29:19 +00:00
readline improvements
This commit is contained in:
parent
ac6eadd9c0
commit
d388292da6
84
readline2.c
84
readline2.c
@ -76,45 +76,70 @@ 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);
|
||||||
|
|
||||||
|
// -1 = not found.
|
||||||
|
if (size == 0xffffffff)
|
||||||
|
{
|
||||||
|
|
||||||
|
// 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
|
||||||
|
{
|
||||||
hsize -= size;
|
hsize -= size;
|
||||||
cp += size;
|
cp += size;
|
||||||
|
|
||||||
@ -129,9 +154,7 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
|
|||||||
term &= 0x00ff;
|
term &= 0x00ff;
|
||||||
tlen = 1;
|
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.
|
||||||
@ -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;
|
||||||
}
|
}
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user