| State | Description |
|---|---|
| 1. | NotinPCL |
| 2. | Seen an Escape |
| 3. | Loaded a 2 char command |
| 4. | Loaded last term of commnd |
| 5. | Loaded last term with binary data |
| 6. | Loaded a term, another term waiting |
| 7. | Loaded a term with binary data, another term waiting |
| State | First | Second | Value | Parm | Command | Left in Buffer | |
|---|---|---|---|---|---|---|---|
| 3 | X | <esc>X | |||||
| 4 | x | X | # | X | <esc>x#X | ||
| 4 | x | X | X | <esc>xX | |||
| 4 | x | y | # | Z | <esc>xy#Z | ||
| 6 | x | y | # | z | <esc>xy#z#Z | #Z | |
Delphi code:
function Buffer.PCLGet: boolean;
var
Len: Word;
begin
{ Commented out?
if PCLState > 2 then begin
if PCLChrOne=PCLOldOne and PCLChrTwo=PCLOldTwo then begin
Buffer.InsertP(Lower(PCLOldParm)
Buffer.InsertS(ParmVal);
PCLOldParm := PCLChrParm;
end;
else begin
Buffer.InsertP(UpCase(PCLOldParm));
Buffer.InsertP('#27'+PCLChrOne+PCLChrTwo
PCLOldOne := PCLChrOne;
PCLOldTwo := PCLChrTwo;
Buffer.InsertS(ParmVal);
PCLOldParm := PCLChrParm;
end;
);
if PCLState in [1,3,4,5] and Data[0]=#27 then PCLState := 2;
if PCLState in [2,6,7] then begin
ParmVal:='';
if PCLState=2 then begin {starting a command, seen escape)
PCLChrOne := Buffer.GetChar;
if IsCharUpper(PCLChrOne) then
PCLState := 3; (EOC on first character = 2 Char command)
else begin
PCLState := 6; {first term or 3 char command waiting}
PCLChrOne := UpCase(PCLChrOne);
ParmVal := Buffer.GetNum; {only sees a number on 3 char command)
PCLChrTwo := Buffer.GetChar;
if IsCharUpper(PCLChrTwo) then begin
PCLChrParm := PCLChrTwo;
PCLState := 4
if Length(ParmVal)>O then begin
PCLChrParm := UpCase(PCLChrTwo);
end;
end;
end;
if PCLState in [6,7] and Length(ParmVal) = O then begin (term waiting)
ParmVal := Buffer.GetNum;
PCLChrParm := Buffer.GetChar;
if IsCharUpper(PCLChrParm) then
PCLState := PCLState-2; {last term. 6 becomes 4, 7 becomes 5)
else
PCLChrParm := UpCase(PCLChrParm);
end;
if PCLState in [4,6,7] and PCLChrParm='W' then begin
Len := ValS(ParmVal);
Len := MinP(Len,EndPtr-BufPtr);
Move(Binary, BufPtr[O], Len); Ilotta room for crashing here!)
BufPtr := BufPtr+Len;
PCLState := Min(PCLState +1,7); 14 becomes 5, 6 becomes 7~
end;
Buffer.Delete;
PCLGet := True;
end;
else begin
{We have ended a previous command and are being ask to load a PCL
command but the escape character is not at the begining of the buffer
indicating that something is wrong}
PCLGet := False;
end;
end;
| State | Description |
| 1 | Not in PCL |
| 2 | Stored an Escape |
| 3 | Stored a 2 char command |
| 4 | Stored last term of command |
| 5 | Stored last term with binary data |
| 6 | Stored a term, waiting for another term |
| 7 | Stored a term with binary data, waiting for another term |
procedure Buffer.PCLPut;
var
Ptr: PChar;
begin
Ptr := BufPtr;
case PCLState of
1..3: begin
{
Previously:
1 Not in PCL
or 2 Seen an Escape
or 3 Loaded a 2 char command
With any of these, this is the first term of the new command
}
if PCLState o 2 then Buffer.InsertS(#27); {not already passed the escape}
Buffer.InsertS(PCLChrOne));
if IsCharLower(PCLChrOne) then begin
Buffer.InsertS(LowerCase(PCLChrTwo));
Buffer.InsertS(ParmVal);
Buffer.StuffS(UpCase(PCLChrParm));
end;
end;
4..5: begin
{
or 4 Loaded last term of command
or 5 Loaded last term with binary data
}
end;
6..7: begin
{
Previously:
6 Loaded a term, another term waiting
or 7 Loaded a term with binary data, another term waiting
}
end;
end;
true = -1
false = 0
DataBinary = 0
DataText = 1
DataPCL = 2
DataUnknown = 3
DataMode = DataText
PCLStart = 0
PCLCmd = 1
PCLGrp = 2
PCLVal = 3
PCLPrm = 4
PCLUnknown = 5
PCLState = PCLUnknown
TYPE TextFile
Chars AS STRING * 1
DIM MyFile AS TextFile
OPEN $ FOR RANDOM AS #1 LEN = LEN(MyFile)
inlen = LOF(1)
WHILE incount <= inlen
incount = incount + 1
GET #1, incount, MyFile
in = ASC(MyFile.Chars)
IF DataMode = DataPCL THEN
PRINT #2, "CHAR '"; CHR$(in); "'";
IF PCLState = PCLVal THEN
SELECT CASE in
CASE 43 'positive
PCLSign = 1
PRINT #2, "+"
CASE 45 'negative
PCLSign = -1
PRINT #2, "-"
CASE 46 'decimal
PCLFrac = true
PRINT #2, "."
CASE 48 TO 57 'digit
IF PCLFrac THEN
PCLValueFrac = PCLValueFrac * 10
PRINT #2, PCLValueFrac
END IF
PCLValue = PCLValue * 10 + (in - 48)
PRINT #2, PCLValue
CASE ELSE
PCLPrms = PCLPrms + 1
PCLValue(PCLPrms) = PCLValue * PCLSign
PCLValueFrac(PCLPrms) = PCLValueFrac
PCLValue = 0
PCLSign = 1
PCLFrac = false
PCLValueFrac = 1
PCLParm(PCLPrms) = ASC(UCASE$(MyFile.Chars)) - 64
PRINT #2, " parm #"; PCLPrms
END SELECT
END IF
IF PCLState = PCLGrp THEN
PCLGroup = INSTR("abcdflprstuv", MyFile.Chars)
PCLGr$ = MyFile.Chars
PRINT #2, " group"
PCLState = PCLVal
END IF
IF PCLState = PCLCmd THEN
i = INSTR("=9EYZ", MyFile.Chars)
IF i > 0 THEN
PCLCommand = ASC(MID$(",-./+", i, 1)) - 32
PRINT #2, " two-char"
DataMode = DataUnknown
PCLState = PCLUnknown
ELSE
PCLCommand = in - 32
PCLState = PCLGrp
PRINT #2, " parm-command"
END IF
END IF
IF in > 64 AND in < 96 THEN 'Termination Character
IF in = 87 THEN '=W so it is binary data
DataMode = DataBinary
BinaryLength = PCLValue(1)
PCLState = PCLUnknown
ELSE
DataMode = DataUnknown 'we dont know what is next so mode is undefined
PCLState = PCLUnknown
END IF
END IF
GOTO nextchar
END IF
IF in = 27 AND DataMode <> DataBinary THEN
DataMode = DataPCL
PCLState = PCLCmd
PCLPrms = 0
PRINT #2, "pcl "
' bitcount = bitcount + 4
GOTO nextchar
END IF
See:
Questions: