Exemplo n.º 1
0
        /// <summary>
        /// FS(0x1C) started variable bytes printer command sequence tokenize routine
        /// </summary>
        private void TokenizeFS()
        {
            if (s_PrtFSType.ContainsKey(ctlByte1))
            {
                ctlType     = s_PrtFSType[ctlByte1].seqtype;
                blockLength = s_PrtFSType[ctlByte1].length;
            }
            else
            {
                blockLength = 2;
                switch (ctlByte1)
                {
                case 0x28:     // FS (
                    blockLength = 3;
                    switch (ctlByte2)
                    {
                    case 0x41:         // FS ( A
                    case 0x43:         // FS ( C
                    case 0x45:         // FS ( E
                    case 0x4C:         // FS ( L
                    case 0x65:         // FS ( e
                    case 0x66:         // FS ( f
                    case 0x67:         // FS ( g
                        ctlType = EscPosCmdType.None;
                        break;

                    default:         // FS ( ??
                        ctlType = EscPosCmdType.FsUnknown;
                        break;
                    }
                    if (ctlType != EscPosCmdType.FsUnknown)
                    {
                        byte ctlByte5 = (byte)(((curIndex + 5) < dataLength) ? baData[curIndex + 5] : 0xFF);
                        // byte ctlByte6 = (byte)(((curIndex + 6) < dataLength) ? baData[curIndex + 6] : 0xFF);
                        blockLength = 5 + ctlByte4 * 0x100 + ctlByte3;
                        switch (ctlByte2)
                        {
                        case 0x41:         // FS ( A 02 00 '0' xx
                            if (blockLength == 7)
                            {
                                if (KanjiFontList.ContainsKey(baData[curIndex + 6]))
                                {
                                    KanjiFontSizeInfo info = KanjiFontList[(baData[curIndex + 6])];
                                    ctlType = EscPosCmdType.FsSelectKanjiCharacterFont;
                                    CurrentKanjiFontInfo = info;
                                }
                                else
                                {
                                    ctlType = EscPosCmdType.FsUnknown;
                                }
                            }
                            else
                            {
                                ctlType = EscPosCmdType.FsUnknown;
                            }
                            break;

                        case 0x43:         // FS ( C
                            ctlType = ctlByte5 switch
                            {
                                // FS ( C 02 00 '0' xx
                                0x30 => (blockLength == 7) ? EscPosCmdType.FsSelectCharacterEncodeSystem : EscPosCmdType.FsUnknown,
                                // FS ( C 03 00 '<' xx xx
                                0x3C => (blockLength == 8) ? EscPosCmdType.FsSetFontPriority : EscPosCmdType.FsUnknown,
                                _ => EscPosCmdType.FsUnknown,
                            };
                            break;

                        case 0x45:         // FS ( E
                            if (remainLength >= blockLength)
                            {
                                if (s_PrtFSEType.ContainsKey(ctlByte5))
                                {
                                    ctlType = s_PrtFSEType[ctlByte5];
                                }
                                else         // FS ( E dL dH ??
                                {
                                    ctlType = EscPosCmdType.FsUnknown;
                                }
                            }
                            break;

                        case 0x4C:         // FS ( L
                            if (remainLength >= blockLength)
                            {
                                if (s_PrtFSLType.ContainsKey(ctlByte5))
                                {
                                    ctlType = s_PrtFSLType[ctlByte5];
                                }
                                else         // FS ( L dL dH ??
                                {
                                    ctlType = EscPosCmdType.FsUnknown;
                                }
                            }
                            break;

                        case 0x65:         // FS ( e
                            ctlType = (blockLength == 7) ? EscPosCmdType.FsEnableDisableAutomaticStatusBackOptional : EscPosCmdType.FsUnknown;
                            break;

                        case 0x66:         // FS ( f
                            ctlType = EscPosCmdType.FsSelectMICRDataHandling;
                            break;

                        case 0x67:         // FS ( g
                            if (remainLength >= blockLength)
                            {
                                if (s_PrtFSgType.ContainsKey(ctlByte5))
                                {
                                    ctlType = s_PrtFSgType[ctlByte5];
                                }
                                else         // FS ( g dL dH ??
                                {
                                    ctlType = EscPosCmdType.FsUnknown;
                                }
                            }
                            break;

                        default:         // FS ( ??
                            ctlType = EscPosCmdType.FsUnknown;
                            break;
                        }
                    }
                    break;

                case 0x32:     // FS 2 --depends on KanjiFontType 72(FontA)/60(FontB)/32(FontC)
                    ctlType     = CurrentKanjiFontInfo.seqtype;
                    blockLength = 4 + (CurrentKanjiFontInfo.xbytes * CurrentKanjiFontInfo.ybytes);
                    break;

                case 0x61:     // FS a
                    ctlType = ctlByte2 switch
                    {
                        // FS a 0
                        0x30 => EscPosCmdType.FsObsoleteReadCheckPaper,
                        // FS a 1
                        0x31 => EscPosCmdType.FsObsoleteLoadCheckPaperToPrintStartingPosition,
                        // FS a 2
                        0x32 => EscPosCmdType.FsObsoleteEjectCheckPaper,
                        // FS ( ??
                        _ => EscPosCmdType.FsUnknown,
                    };
                    blockLength = ctlType == EscPosCmdType.FsObsoleteReadCheckPaper ? 4 : 3;
                    break;

                case 0x67:     // FS g
                    if ((ctlByte2 == 0x31) && (ctlByte3 == 0x00))
                    {
                        if (remainLength < 10)
                        {
                            blockLength = 10;
                            break;
                        }
                        ctlType     = EscPosCmdType.FsObsoleteWriteNVUserMemory;
                        blockLength = 10 + BitConverter.ToUInt16(baData, (int)(curIndex + 8));
                    }
                    else if ((ctlByte2 == 0x32) && (ctlByte3 == 0x00))
                    {
                        ctlType     = EscPosCmdType.FsObsoleteReadNVUserMemory;
                        blockLength = 10;
                    }
                    else     // FS g ?? ??
                    {
                        ctlType     = EscPosCmdType.FsUnknown;
                        blockLength = 4;
                    }
                    break;

                case 0x71:     // FS q
                    if ((ctlByte2 > 0) && (remainLength >= 15))
                    {
                        ctlType = EscPosCmdType.None;
                        long imageCount = ctlByte2;
                        long count;
                        long workIndex = curIndex + 3;
                        for (count = 0; (count < imageCount) && (workIndex < dataLength); count++)
                        {
                            long Xbytes = BitConverter.ToUInt16(baData, (int)workIndex);
                            long Ybytes = BitConverter.ToUInt16(baData, (int)(workIndex + 2));
                            workIndex += 4 + (Xbytes * Ybytes * 8);
                            if (workIndex > dataLength)
                            {
                                ctlType     = EscPosCmdType.NotEnough;
                                blockLength = remainLength;
                                break;
                            }
                        }
                        if (ctlType == EscPosCmdType.None)
                        {
                            if (count >= imageCount)
                            {
                                ctlType     = EscPosCmdType.FsObsoleteDefineNVBitimage;
                                blockLength = workIndex - curIndex;
                            }
                            else
                            {
                                ctlType     = EscPosCmdType.NotEnough;
                                blockLength = remainLength;
                            }
                        }
                    }
                    else     // FS 00 or NotEnough
                    {
                        ctlType     = EscPosCmdType.FsUnknown;
                        blockLength = 3;
                    }
                    break;

                default:     // FS ??
                    ctlType = EscPosCmdType.FsUnknown;
                    break;
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// entry point method of EscPosTokenizerr object
        /// </summary>
        /// <param name="data">byte array data</param>
        /// <param name="initialDevice">indicate initial device type</param>
        /// <returns></returns>
        public List <EscPosCmd> Scan(byte[] data, long initialDevice = EscPosPrinter, int SbcsFontPattern = 1, int KanjiFontPattern = 1, int LineDisplayFontPattern = 1)
        {
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            List <EscPosCmd> result = new List <EscPosCmd> {
            };
            long targetDevice       = initialDevice;
            long prtHead            = -1;
            long ctlHead            = -1;

            dataLength = data.Length;
            baData     = data;
            ctlType    = EscPosCmdType.None;

            SbcsFontList = SbcsFontPattern switch
            {
                1 => s_SbcsFontType01,
                2 => s_SbcsFontType02,
                3 => s_SbcsFontType03,
                4 => s_SbcsFontType04,
                5 => s_SbcsFontType05,
                6 => s_SbcsFontType06,
                7 => s_SbcsFontType07,
                8 => s_SbcsFontType08,
                9 => s_SbcsFontType09,
                _ => s_SbcsFontType01,
            };
            CurrentSbcsFontInfo = SbcsFontList[0];

            KanjiFontList = KanjiFontPattern switch
            {
                1 => s_KanjiFontType01,
                2 => s_KanjiFontType02,
                3 => s_KanjiFontType03,
                4 => s_KanjiFontType04,
                5 => s_KanjiFontType05,
                _ => s_KanjiFontType01,
            };
            CurrentKanjiFontInfo = KanjiFontList[0];

            CurrentVfdFontInfo = LineDisplayFontPattern switch
            {
                1 => s_VfdFontType01,
                2 => s_VfdFontType02,
                _ => s_VfdFontType01,
            };

            for (curIndex = 0; curIndex < dataLength; curIndex += blockLength)
            {
                blockLength  = 0;
                ctlByte0     = baData[curIndex];
                remainLength = dataLength - curIndex;

                // special handling for select perihperal device sequence to update process target device type
                if ((ctlByte0 == 0x1B) && ((((curIndex + 1) < dataLength) ? baData[curIndex + 1] : 0xFF) == 0x3D))
                {
                    AddPrintablesAndControls(result, ref ctlHead, ref prtHead);
                    if ((curIndex + 2) < dataLength)
                    {
                        targetDevice = baData[curIndex + 2];
                    }
                }
                // special handling for realtime commands
                else if (ctlByte0 == 0x10)
                {
                    AddPrintablesAndControls(result, ref ctlHead, ref prtHead);
                    prtHead = -1;
                    ctlHead = -1;
                    if (remainLength < 2)
                    {
                        ctlType     = EscPosCmdType.NotEnough;
                        blockLength = 1;
                    }
                    else
                    {
                        ctlByte1 = (byte)(((curIndex + 1) < dataLength) ? baData[curIndex + 1] : 0xFF);
                        ctlByte2 = (byte)(((curIndex + 2) < dataLength) ? baData[curIndex + 2] : 0xFF);
                        ctlByte3 = (byte)(((curIndex + 3) < dataLength) ? baData[curIndex + 3] : 0xFF);
                        ctlByte4 = (byte)(((curIndex + 4) < dataLength) ? baData[curIndex + 4] : 0xFF);
                        TokenizeDLE();
                        result.Add(new EscPosCmd(ctlType, ref baData, curIndex, blockLength));
                        ctlType = EscPosCmdType.None;
                        prtHead = -1;
                        ctlHead = -1;
                    }
                }
                // for Printer
                if ((targetDevice & EscPosPrinter) == EscPosPrinter)
                {
                    switch (ctlByte0)
                    {
                    // single byte control code
                    case 0x09:     // HT
                    case 0x0C:     // FF
                    case 0x18:     // CAN
                        AddPrintablesAndControls(result, ref ctlHead, ref prtHead);
                        blockLength = 1;
                        ctlType     = s_Prt1ByteType[ctlByte0];
                        result.Add(new EscPosCmd(ctlType, ref baData, curIndex, blockLength));
                        ctlType = EscPosCmdType.None;
                        prtHead = -1;
                        ctlHead = -1;
                        break;

                    case 0x0A:     // LF
                    case 0x0D:     // CR
                        AddPrintablesAndControls(result, ref ctlHead, ref prtHead);
                        blockLength = 1;
                        // Consecutive carriage returns and line feeds and vice versa are processed in combination
                        // so that they do not appear redundant.
                        ctlType  = s_Prt1ByteType[ctlByte0];
                        ctlByte1 = (byte)(((curIndex + 1) < dataLength) ? baData[curIndex + 1] : 0);
                        if ((ctlByte0 == 0x0D) && (ctlByte1 == 0x0A))
                        {
                            blockLength = 2;
                            ctlType     = EscPosCmdType.PrintAndCarriageReturnLineFeed;
                        }
                        else if ((ctlByte0 == 0x0A) && (ctlByte1 == 0x0D))
                        {
                            blockLength = 2;
                            ctlType     = EscPosCmdType.PrintAndLineFeedCarriageReturn;
                        }
                        result.Add(new EscPosCmd(ctlType, ref baData, curIndex, blockLength));
                        ctlType = EscPosCmdType.None;
                        prtHead = -1;
                        ctlHead = -1;
                        break;

                    case 0x10:     // DLE
                        break;     // Since it is already specially processed as a realtime command, it will not be processed.

                    // muntiple bytes control data sequence
                    case 0x1B:     // ESC
                    case 0x1C:     // FS
                    case 0x1D:     // GS
                        AddPrintablesAndControls(result, ref ctlHead, ref prtHead);
                        if (remainLength < 2)
                        {
                            ctlType     = EscPosCmdType.NotEnough;
                            blockLength = 1;
                        }
                        else
                        {
                            ctlByte1 = (byte)(((curIndex + 1) < dataLength) ? baData[curIndex + 1] : 0xFF);
                            ctlByte2 = (byte)(((curIndex + 2) < dataLength) ? baData[curIndex + 2] : 0xFF);
                            ctlByte3 = (byte)(((curIndex + 3) < dataLength) ? baData[curIndex + 3] : 0xFF);
                            ctlByte4 = (byte)(((curIndex + 4) < dataLength) ? baData[curIndex + 4] : 0xFF);
                            switch (ctlByte0)
                            {
                            case 0x1B:
                                TokenizeESCprt();
                                break;

                            case 0x1C:
                                TokenizeFS();
                                break;

                            case 0x1D:
                                TokenizeGS();
                                break;
                            }
                        }
                        if (remainLength < blockLength)
                        {
                            ctlType     = EscPosCmdType.NotEnough;
                            blockLength = remainLength;
                        }
                        result.Add(new EscPosCmd(ctlType, ref baData, curIndex, blockLength));
                        ctlType = EscPosCmdType.None;
                        prtHead = -1;
                        ctlHead = -1;
                        break;

                    default:
                        // printable data
                        if (ctlByte0 >= 0x20)
                        {
                            if (ctlHead >= 0)
                            {
                                result.Add(new EscPosCmd(ctlType, ref baData, ctlHead, (curIndex - ctlHead)));
                                ctlHead = -1;
                            }
                            if (prtHead < 0)
                            {
                                prtHead = curIndex;
                                ctlType = EscPosCmdType.PrtPrintables;
                            }
                        }
                        // unused control code
                        else
                        {
                            if (prtHead >= 0)
                            {
                                result.Add(new EscPosCmd(ctlType, ref baData, prtHead, (curIndex - prtHead)));
                                prtHead = -1;
                            }
                            if (ctlHead < 0)
                            {
                                ctlHead = curIndex;
                                ctlType = EscPosCmdType.Controls;
                            }
                        }
                        blockLength = 1;
                        break;
                    }
                }
                // for LineDisplay
                else if ((targetDevice & EscPosLineDisplay) == EscPosLineDisplay)
                {
                    switch (ctlByte0)
                    {
                    // single byte control code
                    case 0x08:     // BS
                    case 0x09:     // HT
                    case 0x0A:     // LF
                    case 0x0B:     // HOM
                    case 0x0C:     // CLR
                    case 0x0D:     // CR
                    case 0x18:     // CAN
                        AddPrintablesAndControls(result, ref ctlHead, ref prtHead);
                        blockLength = 1;
                        ctlType     = s_Vfd1ByteType[ctlByte0];
                        result.Add(new EscPosCmd(ctlType, ref baData, curIndex, blockLength));
                        ctlType = EscPosCmdType.None;
                        prtHead = -1;
                        ctlHead = -1;
                        break;

                    case 0x10:     // DLE
                        break;     // guard for printer already specially processed as a realtime command, it will not be processed.

                    // muntiple bytes control data sequence
                    case 0x1B:     // ESC
                    case 0x1F:     // US
                        AddPrintablesAndControls(result, ref ctlHead, ref prtHead);
                        if (remainLength < 2)
                        {
                            ctlType     = EscPosCmdType.NotEnough;
                            blockLength = 1;
                        }
                        else
                        {
                            ctlByte1 = (byte)(((curIndex + 1) < dataLength) ? baData[curIndex + 1] : 0xFF);
                            ctlByte2 = (byte)(((curIndex + 2) < dataLength) ? baData[curIndex + 2] : 0xFF);
                            ctlByte3 = (byte)(((curIndex + 3) < dataLength) ? baData[curIndex + 3] : 0xFF);
                            ctlByte4 = (byte)(((curIndex + 4) < dataLength) ? baData[curIndex + 4] : 0xFF);
                            switch (ctlByte0)
                            {
                            case 0x1B:
                                TokenizeESCvfd();
                                break;

                            case 0x1F:
                                TokenizeUS();
                                break;
                            }
                        }
                        if (remainLength < blockLength)
                        {
                            ctlType     = EscPosCmdType.NotEnough;
                            blockLength = remainLength;
                        }
                        result.Add(new EscPosCmd(ctlType, ref baData, curIndex, blockLength));
                        ctlType = EscPosCmdType.None;
                        prtHead = -1;
                        ctlHead = -1;
                        break;

                    default:
                        // printable data
                        if (ctlByte0 >= 0x20)
                        {
                            if (ctlHead >= 0)
                            {
                                result.Add(new EscPosCmd(ctlType, ref baData, ctlHead, (curIndex - ctlHead)));
                                ctlHead = -1;
                            }
                            if (prtHead < 0)
                            {
                                prtHead = curIndex;
                                ctlType = EscPosCmdType.VfdDisplayables;
                            }
                        }
                        // unused control code
                        else
                        {
                            if (prtHead >= 0)
                            {
                                result.Add(new EscPosCmd(ctlType, ref baData, prtHead, (curIndex - prtHead)));
                                prtHead = -1;
                            }
                            if (ctlHead < 0)
                            {
                                ctlHead = curIndex;
                                ctlType = EscPosCmdType.Controls;
                            }
                        }
                        blockLength = 1;
                        break;
                    }
                }
                else
                {
                    blockLength = 1;
                }
            }
            AddPrintablesAndControls(result, ref ctlHead, ref prtHead);
            baData = null;
            return(result);
        }