AmendHub

Download:

thecloud

/

SimpleSpooler

/

amendments

/

4

change FilterData to handle split sequences, detect reverse linefeed

- instead of trying to filter data as it comes in from the network,
filter it later when we write the spool file to the serial port
- rewrite the filter to handle sequences split across data buffers
- don't rewind file position or attempt retries if we can't write

thecloud made amendment 4 about 2 days ago
--- PAP.c Mon Mar 30 01:01:17 2026 +++ PAP.c Wed Jul 29 23:48:39 2026 @@ -42,7 +42,6 @@ int SendRequest(char connID, char funcID); int SendResponse(char connID, char funcID); int SetUpRequestData(char funcID, Ptr reqBuf); int SetUpResponseData(char funcID, Ptr respBuf); -void FilterData(long *count, void *data); void SendTickle(void); void StartTickling(void); void StopTickling(void); @@ -782,7 +781,6 @@ void HandleResponse_from_ATPRequest(void) eofByte = 0; /* clear so we ask for more data */ } else { - FilterData(&length,data); /* can modify length */ WriteDataToSpoolFile(length,data); gDataLen += length; if (++gDataSeq == 0) { @@ -1190,37 +1188,6 @@ int SetUpResponseData(char funcID, Ptr respBuf) } } return dataLen; -} - -void FilterData(long *count, void *data) -{ - /* The AppleTalk ImageWriter driver assumes it is formatting output - * for the ImageWriter II. Some of the printer control sequences - * it can emit are not understood by an ImageWriter I. We can filter - * these out so the unused parameters of the commands are not printed. - * Currently, we strip the following IW II-only sequences: - * 1B48xxxxxxxx (page size command, plus 4 bytes) - * 1B4Bxx (set color command, plus 1 byte) - */ - char *p; - long length, index; - if (!gIW1Mode) { return; } /* only filter in IW1 compatibility mode */ - - p = (char*)data; - length = *count; - for (index=0; index<length; index++) { - if (p[index] != 0x1B) { continue; } - if ((length>(index+6)) && (p[index+1] == 0x48)) { - BlockMove(&p[index+6],&p[index],(length-index)-6); - length -= 6; - index -= 1; - } else if ((length>(index+3)) && (p[index+1] == 0x4B)) { - BlockMove(&p[index+3],&p[index],(length-index)-3); - length -= 3; - index -= 1; - } - } - *count = length; } void SendTickle(void) --- PrintQueue.c Fri Feb 13 10:18:33 2026 +++ PrintQueue.c Thu Jul 30 00:10:57 2026 @@ -36,13 +36,69 @@ long int gCurIndex = 0L; char *gPrefixStr = 0L; char *gPortStr = 0L; Str63 gPrintFileName; -short gRetryAttempts = 0; short gPrintFileRefNum = 0; short gSerialRefNum = 0; long gBytesWritten = 0L; long gJobsPrinted = 0L; +Boolean gProcessingEscape = false; +short gBytesToRemove = 0; +void FilterData(long *count, void *data) +{ + /* The AppleTalk ImageWriter driver assumes it is formatting output + * for the ImageWriter II. Some of the printer control sequences + * it can emit are not understood by an ImageWriter I. We can filter + * these out so the unused parameters of the commands are not printed. + * Currently, we filter the following IW II-only sequences: + * 1B48xxxxxxxx (page size command, plus 4 parameter bytes) + * 1B4Bxx (set color command, plus 1 parameter byte) + * We can also optionally filter the command that backs up the paper: + * 1B72 (set reverse line feeding) + * Since control sequences can span data blocks, the 1B might have been + * sent out before we get the command code. Our filter changes the + * command code to FF which will be ignored, and removes the parameter + * bytes which follow, if any. + */ + char *p; + long length, index; + Boolean iw1Mode, noReverse; + GetPrinterOptions(NULL, NULL, &iw1Mode, &noReverse); + + p = (char*)data; + length = *count; + for (index=0; index<length; index++) { + if (p[index] == 0x1B) { + gProcessingEscape = true; + gBytesToRemove = 0; + continue; + } + if (gProcessingEscape) { + if (iw1Mode) { + if (p[index] == 0x48) { + p[index] = 0xFF; /* change command to no-op */ + gBytesToRemove = 4; /* remove 4 bytes after this */ + } else if (p[index] == 0x4B) { + p[index] = 0xFF; /* change command to no-op */ + gBytesToRemove = 1; /* remove 1 byte after this */ + } + } + if (noReverse && p[index] == 0x72) { + p[index] = 0xFF; /* change command to no-op */ + } + gProcessingEscape = false; + continue; + } + if (gBytesToRemove > 0 && length > (index+1)) { + /* remove one byte by shifting remaining bytes left */ + BlockMove(&p[index+1],&p[index],(length-index)-1); + length -= 1; + gBytesToRemove -= 1; + } + } + *count = length; +} + long JobsPrinted(void) { return gJobsPrinted; @@ -92,7 +148,8 @@ void PrintCurrentJob(void) StopPrintQueue(); return; } - gRetryAttempts = 0; + gProcessingEscape = false; + gBytesToRemove = 0; } /* keep reading more of the current file and sending * to serial port until done, then close the file. @@ -106,21 +163,12 @@ void PrintCurrentJob(void) readCount = count; if (err == eofErr) { readEOF = true; } if (err == noErr || (err == eofErr && readCount > 0)) { + /* filter unwanted commands before writing data out to printer */ + FilterData(&count,buf); /* can reduce count */ err = FSWrite(gSerialRefNum,&count,buf); if (err != noErr) { MessageWithIntValue(LOG_ERR_X,"\pUnable to send print data:",err); - /* go away and retry later if we couldn't write to the port */ - if (count > 0 && count < readCount) { - /* rewind read position, since we didn't write all bytes we read */ - long delta = readCount - count; - err = SetFPos(gPrintFileRefNum, fsFromMark, -delta); - if (err != noErr) { - MessageWithIntValue(LOG_ERR_X,"\pUnable to rewind spool file:",err); - } - } - if (++gRetryAttempts > 3) { - readEOF = true; /* cannot continue */ - } + readEOF = true; /* cannot continue */ } else if (count > 0) { gBytesWritten += count; }