simplify multiple reads

This commit is contained in:
Kelvin Sherlock 2012-04-08 15:13:46 -04:00
parent 1c6cfe8874
commit ac6eadd9c0

View File

@ -2,19 +2,70 @@
#include <tcpipx.h> #include <tcpipx.h>
static void HandleAppend(Handle h1, Handle h2) static LongWord find_crlf(const char *cp, LongWord length)
{ {
LongWord size1, size2; LongWord rv;
HUnlock(h1);
size1 = GetHandleSize(h1); rv = 0;
size2 = GetHandleSize(h2);
SetHandleSize(size1 + size2, h1);
if (_toolErr) return;
HandToPtr(h2, *h1 + size1, size2); asm {
// scan all the full blocks.
ldy #0
ldx length+2
beq remainder
loop1:
lda [<cp],y
and #0xff
cmp #'\r'
beq match
cmp #'\n'
beq match
iny
bne loop1
// scanned a full bank, increment cp && rv
// decrement x
inc <cp+2
inc <rv+2
dex
bne loop1
// if x = 0, drop to remainder bytes.
remainder:
// scan non-full bank
// y = 0
// x is the counter var.
ldx <length
beq done
loop2:
lda [<cp],y
and #0xff
cmp #'\r'
beq match
cmp #'\n'
beq match
iny
dex
beq done
bra loop2
match:
sty <rv
bra exit
done:
lda #-1
sta <rv
sta <rv+2
exit:
} }
return rv;
}
/* /*
* read a line terminated by \r\n, \r, or \n * read a line terminated by \r\n, \r, or \n
* *
@ -28,7 +79,7 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
rrBuff rb; rrBuff rb;
const char *cp; char *cp;
Handle h; Handle h;
LongWord hsize; LongWord hsize;
LongWord size; LongWord size;
@ -50,7 +101,7 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
h = (Handle *)ur->uwTCPDataIn; h = (Handle *)ur->uwTCPDataIn;
if (!h) return 0; if (!h) return 0;
cp = *(const char **)h; cp = *(char **)h;
hsize = GetHandleSize(h); hsize = GetHandleSize(h);
size = find_crlf(cp, hsize); size = find_crlf(cp, hsize);
@ -79,44 +130,43 @@ Word ReadLine2(Word ipid, rlBuffer *buffer)
tlen = 1; tlen = 1;
} }
buffer->size = size; //buffer->size = size;
buffer->term = term; //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,
// so read it in and then delete it afterwards. // so read it in and then shrink it afterwards.
// //
size += tlen;
h = NULL;
while (size) // 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.
Handle h2;
rv = TCPIPReadTCP(ipid, 2, 0, size, &rb);
h2 = rb.rrBuffHandle; hsize = size + tlen;
size -= rb.rrBuffCount; h = NewHandle(hsize, ur->uwUserID, attrNoSpec | attrLocked, 0);
if (_toolErr) return -1;
if (h) buffer->size = size;
buffer->handle = h;
buffer->term = term;
cp = *(char **)h;
while (hsize)
{ {
// append. rv = TCPIPReadTCP(ipid, 0, cp, hsize, &rb);
HandleAppend(h, h2); // break on tcp error?
DisposeHandle(h2);
} hsize -= rb.rrBuffCount;
else cp += rb.rrBuffCount
{
buffer->handle = h = h2;
}
} }
if (tlen) if (tlen)
{ {
// remove the delimiter // remove the delimiter
h = buffer->handle;
size = buffer->size;
// if line length is 0, dispose the handle entirely. // if line length is 0, dispose the handle entirely.
// term will be set to indicate it's a blank line.
if (!size) if (!size)
{ {
DisposeHandle(h); DisposeHandle(h);