view src/scanner.cpp @ 8:dbe18921f741

integration work on url scanner
author carl
date Thu, 22 Apr 2004 11:25:45 -0700
parents 93ff6d1ef647
children 8c65411cd7ab
line wrap: on
line source

static char* scanner_version="$Id$";

using namespace std;

enum state {// url  decoder states
            u_init,
            u_http,
            u_sla,
            u_url,

            // html entity decoder states
            e_init,
            e_amp,
            e_num,

            // mime decoder states
            m_init,
            m_eq,
            m_1,

            // base64 decoder states
            b_init,
            b_lf,
            b_lf2,
            b_64,

            // counter for number of columns in the table
            end_state,

            // temporary mime states
            u_reco,
            e_semi,
            m_2,
            m_cr,
            m_nl,
            b_cr,
           };

typedef state PARSE[end_state];

static PARSE parse_table[256] = {
  // u_init, u_http, u_sla , u_url,  e_init, e_amp,  e_num,  m_init, m_eq,   m_1,    b_init, b_lf,   b_lf2,  b_64

    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x00
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x01
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x02
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x03
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x04
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x05
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x06
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x07
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x08
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x09 <tab>
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_nl,   m_init, b_lf,   b_init, b_lf2,  b_init,  },  // 0x0a <lf>
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x0b
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x0c
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_cr,   m_init, b_init, b_init, b_init, b_cr,    },  // 0x0d <cr>
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x0e
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x0f
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x10
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x11 xon char
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x12
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x13 xoff char
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x14
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x15
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x16
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x17
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x18
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x19
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x1a
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x1b
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x1c
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x1d
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x1e
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x1f
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x20 space
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x21 !
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x22 ""
    {u_init, u_init, u_init, u_reco, e_init, e_num,  e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x23 #
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x24 $
    {u_init, u_init, u_init, u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x25 %
    {u_init, u_init, u_init, u_reco, e_amp,  e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x26 &
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x27 '
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x28 (
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x29 )
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x2A *
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x2B +
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x2C ,
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x2D -
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x2E .
    {u_init, u_sla,  u_sla,  u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x2F /
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x30 0
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x31 1
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x32 2
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x33 3
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x34 4
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x35 5
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x36 6
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x37 7
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x38 8
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_num,  m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x39 9
    {u_http, u_http, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x3A :
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_semi, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x3B ;
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x3C <
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_eq,   m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x3D =
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x3E >
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x3F ?
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x40 @
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x41 A
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x42 B
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x43 C
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x44 D
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x45 E
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x46 F
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x47 G
    {u_http, u_http, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x48 H
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x49 I
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x4A J
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x4B K
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x4C L
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x4D M
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x4E N
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x4F O
    {u_http, u_http, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x50 P
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x51 Q
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x52 R
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x53 S
    {u_http, u_http, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x54 T
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x55 U
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x56 V
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x57 W
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x58 X
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x59 Y
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x5A Z
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x5B [
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x5C brace
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x5D ]
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x5E ^
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x5F _
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x60 `
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x61 a
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x62 b
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x63 c
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x64 d
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x65 e
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_1,    m_2,    b_init, b_64,   b_64,   b_64,    },  // 0x66 f
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x67 g
    {u_http, u_http, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x68 h
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x69 i
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x6A j
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x6B k
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x6C l
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x6D m
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x6E n
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x6F o
    {u_http, u_http, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x70 p
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x71 q
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x72 r
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x73 s
    {u_http, u_http, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x74 t
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x75 u
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x76 v
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x77 w
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x78 x
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x79 y
    {u_init, u_init, u_url,  u_url,  e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_64,   b_64,   b_64,    },  // 0x7A z
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x7B {
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x7C |
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x7D }
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x7E ~
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x7f
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x80
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x81
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x82
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x83
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x84
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x85
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x86
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x87
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x88
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x89
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x8a
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x8b
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x8c
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x8d
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x8e
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x8f
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x90
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x91
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x92
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x93
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x94
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x95
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x96
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x97
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x98
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x99
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x9a
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x9b
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x9c
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x9d
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x9e
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0x9f
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa0
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa1
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa2
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa3
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa4
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa5
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa6
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa7
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa8
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xa9
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xaa
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xab
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xac
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xad
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xae
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xaf
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb0
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb1
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb2
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb3
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb4
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb5
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb6
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb7
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb8
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xb9
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xba
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xbb
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xbc
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xbd
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xbe
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xbf
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc0
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc1
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc2
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc3
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc4
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc5
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc6
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc7
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc8
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xc9
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xca
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xcb
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xcc
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xcd
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xce
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xcf
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd0
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd1
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd2
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd3
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd4
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd5
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd6
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd7
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd8
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xd9
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xda
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xdb
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xdc
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xdd
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xde
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xdf
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe0
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe1
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe2
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe3
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe4
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe5
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe6
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe7
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe8
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xe9
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xea
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xeb
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xec
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xed
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xee
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xef
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf0
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf1
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf2
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf3
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf4
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf5
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf6
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf7
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf8
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xf9
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xfa
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xfb
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xfc
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xfd
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xfe
    {u_init, u_init, u_init, u_reco, e_init, e_init, e_init, m_init, m_init, m_init, b_init, b_init, b_init, b_init,  },  // 0xff
};


u_char hex_decode[256] = {
    0,  // 0x00
    0,  // 0x01
    0,  // 0x02
    0,  // 0x03
    0,  // 0x04
    0,  // 0x05
    0,  // 0x06
    0,  // 0x07
    0,  // 0x08
    0,  // 0x09 <tab>
    0,  // 0x0a <lf>
    0,  // 0x0b
    0,  // 0x0c
    0,  // 0x0d <cr>
    0,  // 0x0e
    0,  // 0x0f
    0,  // 0x10
    0,  // 0x11 xon char
    0,  // 0x12
    0,  // 0x13 xoff char
    0,  // 0x14
    0,  // 0x15
    0,  // 0x16
    0,  // 0x17
    0,  // 0x18
    0,  // 0x19
    0,  // 0x1a
    0,  // 0x1b
    0,  // 0x1c
    0,  // 0x1d
    0,  // 0x1e
    0,  // 0x1f
    0,  // 0x20 space
    0,  // 0x21 !
    0,  // 0x22 ""
    0,  // 0x23 #
    0,  // 0x24 $
    0,  // 0x25 %
    0,  // 0x26 &
    0,  // 0x27 '
    0,  // 0x28 (
    0,  // 0x29 )
    0,  // 0x2A *
    0,  // 0x2B +
    0,  // 0x2C ,
    0,  // 0x2D -
    0,  // 0x2E .
    0,  // 0x2F /
    0,  // 0x30 0
    1,  // 0x31 1
    2,  // 0x32 2
    3,  // 0x33 3
    4,  // 0x34 4
    5,  // 0x35 5
    6,  // 0x36 6
    7,  // 0x37 7
    8,  // 0x38 8
    9,  // 0x39 9
    0,  // 0x3A :
    0,  // 0x3B ;
    0,  // 0x3C <
    0,  // 0x3D =
    0,  // 0x3E >
    0,  // 0x3F ?
    0,  // 0x40 @
    10, // 0x41 A
    11, // 0x42 B
    12, // 0x43 C
    13, // 0x44 D
    14, // 0x45 E
    15, // 0x46 F
    0,  // 0x47 G
    0,  // 0x48 H
    0,  // 0x49 I
    0,  // 0x4A J
    0,  // 0x4B K
    0,  // 0x4C L
    0,  // 0x4D M
    0,  // 0x4E N
    0,  // 0x4F O
    0,  // 0x50 P
    0,  // 0x51 Q
    0,  // 0x52 R
    0,  // 0x53 S
    0,  // 0x54 T
    0,  // 0x55 U
    0,  // 0x56 V
    0,  // 0x57 W
    0,  // 0x58 X
    0,  // 0x59 Y
    0,  // 0x5A Z
    0,  // 0x5B [
    0,  // 0x5C brace
    0,  // 0x5D ]
    0,  // 0x5E ^
    0,  // 0x5F _
    0,  // 0x60 `
    10, // 0x61 a
    11, // 0x62 b
    12, // 0x63 c
    13, // 0x64 d
    14, // 0x65 e
    15, // 0x66 f
    0,  // 0x67 g
    0,  // 0x68 h
    0,  // 0x69 i
    0,  // 0x6A j
    0,  // 0x6B k
    0,  // 0x6C l
    0,  // 0x6D m
    0,  // 0x6E n
    0,  // 0x6F o
    0,  // 0x70 p
    0,  // 0x71 q
    0,  // 0x72 r
    0,  // 0x73 s
    0,  // 0x74 t
    0,  // 0x75 u
    0,  // 0x76 v
    0,  // 0x77 w
    0,  // 0x78 x
    0,  // 0x79 y
    0,  // 0x7A z
    0,  // 0x7B {
    0,  // 0x7C |
    0,  // 0x7D }
    0,  // 0x7E ~
    0,  // 0x7f
    0,  // 0x80
    0,  // 0x81
    0,  // 0x82
    0,  // 0x83
    0,  // 0x84
    0,  // 0x85
    0,  // 0x86
    0,  // 0x87
    0,  // 0x88
    0,  // 0x89
    0,  // 0x8a
    0,  // 0x8b
    0,  // 0x8c
    0,  // 0x8d
    0,  // 0x8e
    0,  // 0x8f
    0,  // 0x90
    0,  // 0x91
    0,  // 0x92
    0,  // 0x93
    0,  // 0x94
    0,  // 0x95
    0,  // 0x96
    0,  // 0x97
    0,  // 0x98
    0,  // 0x99
    0,  // 0x9a
    0,  // 0x9b
    0,  // 0x9c
    0,  // 0x9d
    0,  // 0x9e
    0,  // 0x9f
    0,  // 0xa0
    0,  // 0xa1
    0,  // 0xa2
    0,  // 0xa3
    0,  // 0xa4
    0,  // 0xa5
    0,  // 0xa6
    0,  // 0xa7
    0,  // 0xa8
    0,  // 0xa9
    0,  // 0xaa
    0,  // 0xab
    0,  // 0xac
    0,  // 0xad
    0,  // 0xae
    0,  // 0xaf
    0,  // 0xb0
    0,  // 0xb1
    0,  // 0xb2
    0,  // 0xb3
    0,  // 0xb4
    0,  // 0xb5
    0,  // 0xb6
    0,  // 0xb7
    0,  // 0xb8
    0,  // 0xb9
    0,  // 0xba
    0,  // 0xbb
    0,  // 0xbc
    0,  // 0xbd
    0,  // 0xbe
    0,  // 0xbf
    0,  // 0xc0
    0,  // 0xc1
    0,  // 0xc2
    0,  // 0xc3
    0,  // 0xc4
    0,  // 0xc5
    0,  // 0xc6
    0,  // 0xc7
    0,  // 0xc8
    0,  // 0xc9
    0,  // 0xca
    0,  // 0xcb
    0,  // 0xcc
    0,  // 0xcd
    0,  // 0xce
    0,  // 0xcf
    0,  // 0xd0
    0,  // 0xd1
    0,  // 0xd2
    0,  // 0xd3
    0,  // 0xd4
    0,  // 0xd5
    0,  // 0xd6
    0,  // 0xd7
    0,  // 0xd8
    0,  // 0xd9
    0,  // 0xda
    0,  // 0xdb
    0,  // 0xdc
    0,  // 0xdd
    0,  // 0xde
    0,  // 0xdf
    0,  // 0xe0
    0,  // 0xe1
    0,  // 0xe2
    0,  // 0xe3
    0,  // 0xe4
    0,  // 0xe5
    0,  // 0xe6
    0,  // 0xe7
    0,  // 0xe8
    0,  // 0xe9
    0,  // 0xea
    0,  // 0xeb
    0,  // 0xec
    0,  // 0xed
    0,  // 0xee
    0,  // 0xef
    0,  // 0xf0
    0,  // 0xf1
    0,  // 0xf2
    0,  // 0xf3
    0,  // 0xf4
    0,  // 0xf5
    0,  // 0xf6
    0,  // 0xf7
    0,  // 0xf8
    0,  // 0xf9
    0,  // 0xfa
    0,  // 0xfb
    0,  // 0xfc
    0,  // 0xfd
    0,  // 0xfe
    0,  // 0xff
};

u_char b64_decode[256] = {
    0,  // 0x00
    0,  // 0x01
    0,  // 0x02
    0,  // 0x03
    0,  // 0x04
    0,  // 0x05
    0,  // 0x06
    0,  // 0x07
    0,  // 0x08
    0,  // 0x09 <tab>
    0,  // 0x0a <lf>
    0,  // 0x0b
    0,  // 0x0c
    0,  // 0x0d <cr>
    0,  // 0x0e
    0,  // 0x0f
    0,  // 0x10
    0,  // 0x11 xon char
    0,  // 0x12
    0,  // 0x13 xoff char
    0,  // 0x14
    0,  // 0x15
    0,  // 0x16
    0,  // 0x17
    0,  // 0x18
    0,  // 0x19
    0,  // 0x1a
    0,  // 0x1b
    0,  // 0x1c
    0,  // 0x1d
    0,  // 0x1e
    0,  // 0x1f
    0,  // 0x20 space
    0,  // 0x21 !
    0,  // 0x22 ""
    0,  // 0x23 #
    0,  // 0x24 $
    0,  // 0x25 %
    0,  // 0x26 &
    0,  // 0x27 '
    0,  // 0x28 (
    0,  // 0x29 )
    0,  // 0x2A *
    62, // 0x2B +
    0,  // 0x2C ,
    0,  // 0x2D -
    0,  // 0x2E .
    63, // 0x2F /
    52, // 0x30 0
    53, // 0x31 1
    54, // 0x32 2
    55, // 0x33 3
    56, // 0x34 4
    57, // 0x35 5
    58, // 0x36 6
    59, // 0x37 7
    60, // 0x38 8
    61, // 0x39 9
    0,  // 0x3A :
    0,  // 0x3B ;
    0,  // 0x3C <
    0,  // 0x3D =
    0,  // 0x3E >
    0,  // 0x3F ?
    0,  // 0x40 @
    0,  // 0x41 A
    1,  // 0x42 B
    2,  // 0x43 C
    3,  // 0x44 D
    4,  // 0x45 E
    5,  // 0x46 F
    6,  // 0x47 G
    7,  // 0x48 H
    8,  // 0x49 I
    9,  // 0x4A J
    10, // 0x4B K
    11, // 0x4C L
    12, // 0x4D M
    13, // 0x4E N
    14, // 0x4F O
    15, // 0x50 P
    16, // 0x51 Q
    17, // 0x52 R
    18, // 0x53 S
    19, // 0x54 T
    20, // 0x55 U
    21, // 0x56 V
    22, // 0x57 W
    23, // 0x58 X
    24, // 0x59 Y
    25, // 0x5A Z
    0,  // 0x5B [
    0,  // 0x5C brace
    0,  // 0x5D ]
    0,  // 0x5E ^
    0,  // 0x5F _
    0,  // 0x60 `
    26, // 0x61 a
    27, // 0x62 b
    28, // 0x63 c
    29, // 0x64 d
    30, // 0x65 e
    31, // 0x66 f
    32, // 0x67 g
    33, // 0x68 h
    34, // 0x69 i
    35, // 0x6A j
    36, // 0x6B k
    37, // 0x6C l
    38, // 0x6D m
    39, // 0x6E n
    40, // 0x6F o
    41, // 0x70 p
    42, // 0x71 q
    43, // 0x72 r
    44, // 0x73 s
    45, // 0x74 t
    46, // 0x75 u
    47, // 0x76 v
    48, // 0x77 w
    49, // 0x78 x
    50, // 0x79 y
    51, // 0x7A z
    0,  // 0x7B {
    0,  // 0x7C |
    0,  // 0x7D }
    0,  // 0x7E ~
    0,  // 0x7f
    0,  // 0x80
    0,  // 0x81
    0,  // 0x82
    0,  // 0x83
    0,  // 0x84
    0,  // 0x85
    0,  // 0x86
    0,  // 0x87
    0,  // 0x88
    0,  // 0x89
    0,  // 0x8a
    0,  // 0x8b
    0,  // 0x8c
    0,  // 0x8d
    0,  // 0x8e
    0,  // 0x8f
    0,  // 0x90
    0,  // 0x91
    0,  // 0x92
    0,  // 0x93
    0,  // 0x94
    0,  // 0x95
    0,  // 0x96
    0,  // 0x97
    0,  // 0x98
    0,  // 0x99
    0,  // 0x9a
    0,  // 0x9b
    0,  // 0x9c
    0,  // 0x9d
    0,  // 0x9e
    0,  // 0x9f
    0,  // 0xa0
    0,  // 0xa1
    0,  // 0xa2
    0,  // 0xa3
    0,  // 0xa4
    0,  // 0xa5
    0,  // 0xa6
    0,  // 0xa7
    0,  // 0xa8
    0,  // 0xa9
    0,  // 0xaa
    0,  // 0xab
    0,  // 0xac
    0,  // 0xad
    0,  // 0xae
    0,  // 0xaf
    0,  // 0xb0
    0,  // 0xb1
    0,  // 0xb2
    0,  // 0xb3
    0,  // 0xb4
    0,  // 0xb5
    0,  // 0xb6
    0,  // 0xb7
    0,  // 0xb8
    0,  // 0xb9
    0,  // 0xba
    0,  // 0xbb
    0,  // 0xbc
    0,  // 0xbd
    0,  // 0xbe
    0,  // 0xbf
    0,  // 0xc0
    0,  // 0xc1
    0,  // 0xc2
    0,  // 0xc3
    0,  // 0xc4
    0,  // 0xc5
    0,  // 0xc6
    0,  // 0xc7
    0,  // 0xc8
    0,  // 0xc9
    0,  // 0xca
    0,  // 0xcb
    0,  // 0xcc
    0,  // 0xcd
    0,  // 0xce
    0,  // 0xcf
    0,  // 0xd0
    0,  // 0xd1
    0,  // 0xd2
    0,  // 0xd3
    0,  // 0xd4
    0,  // 0xd5
    0,  // 0xd6
    0,  // 0xd7
    0,  // 0xd8
    0,  // 0xd9
    0,  // 0xda
    0,  // 0xdb
    0,  // 0xdc
    0,  // 0xdd
    0,  // 0xde
    0,  // 0xdf
    0,  // 0xe0
    0,  // 0xe1
    0,  // 0xe2
    0,  // 0xe3
    0,  // 0xe4
    0,  // 0xe5
    0,  // 0xe6
    0,  // 0xe7
    0,  // 0xe8
    0,  // 0xe9
    0,  // 0xea
    0,  // 0xeb
    0,  // 0xec
    0,  // 0xed
    0,  // 0xee
    0,  // 0xef
    0,  // 0xf0
    0,  // 0xf1
    0,  // 0xf2
    0,  // 0xf3
    0,  // 0xf4
    0,  // 0xf5
    0,  // 0xf6
    0,  // 0xf7
    0,  // 0xf8
    0,  // 0xf9
    0,  // 0xfa
    0,  // 0xfb
    0,  // 0xfc
    0,  // 0xfd
    0,  // 0xfe
    0,  // 0xff
};

#define PENDING_LIMIT 100
struct fsa {
    u_char  pending[PENDING_LIMIT];
    int     count;
    state   st;
    state   init;
    fsa*    next;
    string_set  *urls;

    fsa(state init, fsa* next_, string_set *urls_);
    void push(u_char *buf, int len);
};

fsa::fsa(state init_, fsa *next_, string_set *urls_) {
    count = 0;
    st    = init_;
    init  = init_;
    next  = next_;
    urls  = urls_;
}

void fsa::push(u_char *buf, int len) {
    for (int i=0; i<len; i++) {
        u_char c = buf[i];
        // guard against buffer overflow
        if (count == PENDING_LIMIT-1) {
            if (next) next->push(pending, count);
            count = 0;
            st    = init;
        }
        pending[count++] = c;
        st = parse_table[c][st];
        switch (st) {

            //////////////////////////////
            //  url recognizer
            case u_sla: {
                if ((count < 6) || (7 < count)) {
                    count = 0;
                    st    = u_init;
                }
                } break;

            case u_reco: {
                pending[count-1] = 0;
                if (strncasecmp((const char *)pending, "http://", 7) == 0) {
                    urls->insert(strdup((const char *)pending+7));
                }
                }   // fall thru

            case u_init: {
                count = 0;  // discard all characters
                } break;


            //////////////////////////////
            //  mime decoder
            case m_2: {
                pending[0] = hex_decode[pending[1]] * 16 + hex_decode[pending[2]];
                count = 1;
                st    = m_init;
                } // fall thru

            case m_init: {
                if (next) next->push(pending, count);
                count = 0;
                } break;

            case m_cr: {
                count = 1;
                st    = m_eq;
                } break;

            case m_nl: {
                count = 0;
                st    = m_init;
                } break;

            //////////////////////////////
            //  html entity decoder
            case e_semi: {
                pending[--count] = '\0';  // null terminate the digit string by overwriting the semicolon
                pending[0] = atoi((const char *)pending+2);
                count = 1;
                st    = e_init;
                } // fall thru

            case e_init: {
                if (next) next->push(pending, count);
                count = 0;
                } break;

            //////////////////////////////
            //  base64 decoder
            case b_lf2: {
                count--;
                } break;

            case b_cr: {
                int cnt = 0;
                if ((count % 4) == 1) {
                    count--;
                    // might have proper b64 data
                    for (int i=0; i<count; i+=4) {
                        unsigned long a1 = b64_decode[pending[i]];
                        unsigned long a2 = b64_decode[pending[i+1]];
                        unsigned long a3 = b64_decode[pending[i+2]];
                        unsigned long a4 = b64_decode[pending[i+3]];
                        unsigned long a = (a1 << 18) | (a2 << 12) | (a3 << 6) | a4;
                        pending[cnt++] = (a & 0x00ff0000) >> 16;
                        pending[cnt++] = (a & 0x0000ff00) >>  8;
                        pending[cnt++] = (a & 0x000000ff);
                        if ((char)pending[i+3] == '=') cnt--;
                        if ((char)pending[i+2] == '=') cnt--;
                    }
                    count = cnt;
                    st    = b_lf2;
                }
                else st = b_init;
                } // fall thru

            case b_lf:
            case b_init: {
                if (next) next->push(pending, count);
                count = 0;
                } break;

            //////////////////////////////
            //  states that just accumulate characters in the pending buffer
            case u_http:
            case u_url:
            case e_amp:
            case e_num:
            case b_64:
            case m_eq:
            case m_1:
            default: {
                } break;
        }
    }
}

struct url_scanner {
    fsa *urls_parser;
    fsa *html_parser;
    fsa *mime_parser;
    fsa *b64_parser;

    url_scanner(string_set *urls);
    ~url_scanner();
    void scan(u_char *buffer, size_t length);
};

url_scanner::url_scanner(string_set *urls) {
    urls_parser = new fsa(u_init, NULL,        urls);
    html_parser = new fsa(e_init, urls_parser, NULL);
    mime_parser = new fsa(m_init, html_parser, NULL);
    b64_parser  = new fsa(b_init, mime_parser, NULL);
}

url_scanner::~url_scanner() {
    delete urls_parser;
    delete html_parser;
    delete mime_parser;
    delete b64_parser;
}

void url_scanner::scan(u_char *buffer, size_t length) {
    b64_parser->push(buffer, length);
}