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;
}