diff --git a/readline2.c b/readline2.c index 999110b..da406af 100644 --- a/readline2.c +++ b/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; } \ No newline at end of file diff --git a/readline2.h b/readline2.h index 6b364ca..bdff4ec 100644 --- a/readline2.h +++ b/readline2.h @@ -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);