141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// This file is part of TagSoup and is Copyright 2002-2008 by John Cowan.
241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//
341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// TagSoup is licensed under the Apache License,
441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// Version 2.0.  You may obtain a copy of this license at
541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// http://www.apache.org/licenses/LICENSE-2.0 .  You may also have
641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// additional legal rights not granted by this license.
741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//
841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// TagSoup is distributed in the hope that it will be useful, but
941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// unless required by applicable law or agreed to in writing, TagSoup
1041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
1141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// OF ANY KIND, either express or implied; not even the implied warranty
1241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//
1441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//
1541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectpackage org.ccil.cowan.tagsoup;
1641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport java.io.*;
1741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport org.xml.sax.SAXException;
1841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport org.xml.sax.Locator;
1941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
2041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project/**
2141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source ProjectThis class implements a table-driven scanner for HTML, allowing for lots of
2241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectdefects.  It implements the Scanner interface, which accepts a Reader
2341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectobject to fetch characters from and a ScanHandler object to report lexical
2441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectevents to.
2541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project*/
2641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
2741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectpublic class HTMLScanner implements Scanner, Locator {
2841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
2941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Start of state table
3041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		private static final int S_ANAME = 1;
3141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_APOS = 2;
3241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_AVAL = 3;
3341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_BB = 4;
3441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_BBC = 5;
3541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_BBCD = 6;
3641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_BBCDA = 7;
3741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_BBCDAT = 8;
3841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_BBCDATA = 9;
3941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_CDATA = 10;
4041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_CDATA2 = 11;
4141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_CDSECT = 12;
4241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_CDSECT1 = 13;
4341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_CDSECT2 = 14;
4441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_COM = 15;
4541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_COM2 = 16;
4641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_COM3 = 17;
4741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_COM4 = 18;
4841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_DECL = 19;
4941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_DECL2 = 20;
5041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_DONE = 21;
5141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_EMPTYTAG = 22;
5241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_ENT = 23;
5341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_EQ = 24;
5441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_ETAG = 25;
5541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_GI = 26;
5641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_NCR = 27;
5741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_PCDATA = 28;
5841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_PI = 29;
5941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_PITARGET = 30;
6041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_QUOT = 31;
6141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_STAGC = 32;
6241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_TAG = 33;
6341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_TAGWS = 34;
6441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int S_XNCR = 35;
6541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ADUP = 1;
6641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ADUP_SAVE = 2;
6741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ADUP_STAGC = 3;
6841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ANAME = 4;
6941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ANAME_ADUP = 5;
7041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ANAME_ADUP_STAGC = 6;
7141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_AVAL = 7;
7241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_AVAL_STAGC = 8;
7341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_CDATA = 9;
7441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_CMNT = 10;
7541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_DECL = 11;
7641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_EMPTYTAG = 12;
7741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ENTITY = 13;
7841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ENTITY_START = 14;
7941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_ETAG = 15;
8041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_GI = 16;
8141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_GI_STAGC = 17;
8241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_LT = 18;
8341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_LT_PCDATA = 19;
8441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_MINUS = 20;
8541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_MINUS2 = 21;
8641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_MINUS3 = 22;
8741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_PCDATA = 23;
8841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_PI = 24;
8941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_PITARGET = 25;
9041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_PITARGET_PI = 26;
9141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_SAVE = 27;
9241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_SKIP = 28;
9341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_SP = 29;
9441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_STAGC = 30;
9541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_UNGET = 31;
9641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final int A_UNSAVE_PCDATA = 32;
9741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static int[] statetable = {
9841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ANAME, '/', A_ANAME_ADUP, S_EMPTYTAG,
9941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ANAME, '=', A_ANAME, S_AVAL,
10041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ANAME, '>', A_ANAME_ADUP_STAGC, S_PCDATA,
10141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ANAME, 0, A_SAVE, S_ANAME,
10241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ANAME, -1, A_ANAME_ADUP_STAGC, S_DONE,
10341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ANAME, ' ', A_ANAME, S_EQ,
10441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ANAME, '\n', A_ANAME, S_EQ,
10541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ANAME, '\t', A_ANAME, S_EQ,
10641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_APOS, '\'', A_AVAL, S_TAGWS,
10741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_APOS, 0, A_SAVE, S_APOS,
10841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_APOS, -1, A_AVAL_STAGC, S_DONE,
10941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_APOS, ' ', A_SP, S_APOS,
11041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_APOS, '\n', A_SP, S_APOS,
11141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_APOS, '\t', A_SP, S_APOS,
11241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_AVAL, '"', A_SKIP, S_QUOT,
11370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		S_AVAL, '\'', A_SKIP, S_APOS,
11441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_AVAL, '>', A_AVAL_STAGC, S_PCDATA,
11541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_AVAL, 0, A_SAVE, S_STAGC,
11641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_AVAL, -1, A_AVAL_STAGC, S_DONE,
11741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_AVAL, ' ', A_SKIP, S_AVAL,
11841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_AVAL, '\n', A_SKIP, S_AVAL,
11941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_AVAL, '\t', A_SKIP, S_AVAL,
12041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BB, 'C', A_SKIP, S_BBC,
12141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BB, 0, A_SKIP, S_DECL,
12241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BB, -1, A_SKIP, S_DONE,
12341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBC, 'D', A_SKIP, S_BBCD,
12441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBC, 0, A_SKIP, S_DECL,
12541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBC, -1, A_SKIP, S_DONE,
12641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCD, 'A', A_SKIP, S_BBCDA,
12741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCD, 0, A_SKIP, S_DECL,
12841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCD, -1, A_SKIP, S_DONE,
12941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDA, 'T', A_SKIP, S_BBCDAT,
13041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDA, 0, A_SKIP, S_DECL,
13141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDA, -1, A_SKIP, S_DONE,
13241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDAT, 'A', A_SKIP, S_BBCDATA,
13341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDAT, 0, A_SKIP, S_DECL,
13441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDAT, -1, A_SKIP, S_DONE,
13541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDATA, '[', A_SKIP, S_CDSECT,
13641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDATA, 0, A_SKIP, S_DECL,
13741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_BBCDATA, -1, A_SKIP, S_DONE,
13841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDATA, '<', A_SAVE, S_CDATA2,
13941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDATA, 0, A_SAVE, S_CDATA,
14041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDATA, -1, A_PCDATA, S_DONE,
14141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDATA2, '/', A_UNSAVE_PCDATA, S_ETAG,
14241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDATA2, 0, A_SAVE, S_CDATA,
14341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDATA2, -1, A_UNSAVE_PCDATA, S_DONE,
14441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT, ']', A_SAVE, S_CDSECT1,
14541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT, 0, A_SAVE, S_CDSECT,
14641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT, -1, A_SKIP, S_DONE,
14741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT1, ']', A_SAVE, S_CDSECT2,
14841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT1, 0, A_SAVE, S_CDSECT,
14941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT1, -1, A_SKIP, S_DONE,
15041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT2, '>', A_CDATA, S_PCDATA,
15141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT2, 0, A_SAVE, S_CDSECT,
15241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_CDSECT2, -1, A_SKIP, S_DONE,
15341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM, '-', A_SKIP, S_COM2,
15441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM, 0, A_SAVE, S_COM2,
15541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM, -1, A_CMNT, S_DONE,
15641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM2, '-', A_SKIP, S_COM3,
15741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM2, 0, A_SAVE, S_COM2,
15841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM2, -1, A_CMNT, S_DONE,
15941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM3, '-', A_SKIP, S_COM4,
16041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM3, 0, A_MINUS, S_COM2,
16141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM3, -1, A_CMNT, S_DONE,
16241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM4, '-', A_MINUS3, S_COM4,
16341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM4, '>', A_CMNT, S_PCDATA,
16441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM4, 0, A_MINUS2, S_COM2,
16541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_COM4, -1, A_CMNT, S_DONE,
16641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_DECL, '-', A_SKIP, S_COM,
16741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_DECL, '>', A_SKIP, S_PCDATA,
16870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		S_DECL, '[', A_SKIP, S_BB,
16941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_DECL, 0, A_SAVE, S_DECL2,
17041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_DECL, -1, A_SKIP, S_DONE,
17141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_DECL2, '>', A_DECL, S_PCDATA,
17241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_DECL2, 0, A_SAVE, S_DECL2,
17341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_DECL2, -1, A_SKIP, S_DONE,
17441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EMPTYTAG, '>', A_EMPTYTAG, S_PCDATA,
17541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EMPTYTAG, 0, A_SAVE, S_ANAME,
17641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EMPTYTAG, ' ', A_SKIP, S_TAGWS,
17741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EMPTYTAG, '\n', A_SKIP, S_TAGWS,
17841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EMPTYTAG, '\t', A_SKIP, S_TAGWS,
17941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ENT, 0, A_ENTITY, S_ENT,
18041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ENT, -1, A_ENTITY, S_DONE,
18141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EQ, '=', A_SKIP, S_AVAL,
18241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EQ, '>', A_ADUP_STAGC, S_PCDATA,
18341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EQ, 0, A_ADUP_SAVE, S_ANAME,
18441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EQ, -1, A_ADUP_STAGC, S_DONE,
18541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EQ, ' ', A_SKIP, S_EQ,
18641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EQ, '\n', A_SKIP, S_EQ,
18741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_EQ, '\t', A_SKIP, S_EQ,
18841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ETAG, '>', A_ETAG, S_PCDATA,
18941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ETAG, 0, A_SAVE, S_ETAG,
19041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ETAG, -1, A_ETAG, S_DONE,
19141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ETAG, ' ', A_SKIP, S_ETAG,
19241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ETAG, '\n', A_SKIP, S_ETAG,
19341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_ETAG, '\t', A_SKIP, S_ETAG,
19441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_GI, '/', A_SKIP, S_EMPTYTAG,
19541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_GI, '>', A_GI_STAGC, S_PCDATA,
19641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_GI, 0, A_SAVE, S_GI,
19741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_GI, -1, A_SKIP, S_DONE,
19841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_GI, ' ', A_GI, S_TAGWS,
19941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_GI, '\n', A_GI, S_TAGWS,
20041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_GI, '\t', A_GI, S_TAGWS,
20141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_NCR, 0, A_ENTITY, S_NCR,
20241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_NCR, -1, A_ENTITY, S_DONE,
20341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PCDATA, '&', A_ENTITY_START, S_ENT,
20441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PCDATA, '<', A_PCDATA, S_TAG,
20541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PCDATA, 0, A_SAVE, S_PCDATA,
20641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PCDATA, -1, A_PCDATA, S_DONE,
20741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PI, '>', A_PI, S_PCDATA,
20841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PI, 0, A_SAVE, S_PI,
20941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PI, -1, A_PI, S_DONE,
21041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PITARGET, '>', A_PITARGET_PI, S_PCDATA,
21141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PITARGET, 0, A_SAVE, S_PITARGET,
21241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PITARGET, -1, A_PITARGET_PI, S_DONE,
21341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PITARGET, ' ', A_PITARGET, S_PI,
21441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PITARGET, '\n', A_PITARGET, S_PI,
21541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_PITARGET, '\t', A_PITARGET, S_PI,
21641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_QUOT, '"', A_AVAL, S_TAGWS,
21741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_QUOT, 0, A_SAVE, S_QUOT,
21841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_QUOT, -1, A_AVAL_STAGC, S_DONE,
21941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_QUOT, ' ', A_SP, S_QUOT,
22041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_QUOT, '\n', A_SP, S_QUOT,
22141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_QUOT, '\t', A_SP, S_QUOT,
22241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_STAGC, '>', A_AVAL_STAGC, S_PCDATA,
22341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_STAGC, 0, A_SAVE, S_STAGC,
22441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_STAGC, -1, A_AVAL_STAGC, S_DONE,
22541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_STAGC, ' ', A_AVAL, S_TAGWS,
22641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_STAGC, '\n', A_AVAL, S_TAGWS,
22741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_STAGC, '\t', A_AVAL, S_TAGWS,
22841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAG, '!', A_SKIP, S_DECL,
22941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAG, '/', A_SKIP, S_ETAG,
23041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAG, '<', A_SAVE, S_TAG,
23170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		S_TAG, '?', A_SKIP, S_PITARGET,
23241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAG, 0, A_SAVE, S_GI,
23341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAG, -1, A_LT_PCDATA, S_DONE,
23441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAG, ' ', A_LT, S_PCDATA,
23541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAG, '\n', A_LT, S_PCDATA,
23641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAG, '\t', A_LT, S_PCDATA,
23741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAGWS, '/', A_SKIP, S_EMPTYTAG,
23841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAGWS, '>', A_STAGC, S_PCDATA,
23941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAGWS, 0, A_SAVE, S_ANAME,
24041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAGWS, -1, A_STAGC, S_DONE,
24141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAGWS, ' ', A_SKIP, S_TAGWS,
24241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAGWS, '\n', A_SKIP, S_TAGWS,
24341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_TAGWS, '\t', A_SKIP, S_TAGWS,
24441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_XNCR, 0, A_ENTITY, S_XNCR,
24541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		S_XNCR, -1, A_ENTITY, S_DONE,
24641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
24741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	};
24841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final String[] debug_actionnames = { "", "A_ADUP", "A_ADUP_SAVE", "A_ADUP_STAGC", "A_ANAME", "A_ANAME_ADUP", "A_ANAME_ADUP_STAGC", "A_AVAL", "A_AVAL_STAGC", "A_CDATA", "A_CMNT", "A_DECL", "A_EMPTYTAG", "A_ENTITY", "A_ENTITY_START", "A_ETAG", "A_GI", "A_GI_STAGC", "A_LT", "A_LT_PCDATA", "A_MINUS", "A_MINUS2", "A_MINUS3", "A_PCDATA", "A_PI", "A_PITARGET", "A_PITARGET_PI", "A_SAVE", "A_SKIP", "A_SP", "A_STAGC", "A_UNGET", "A_UNSAVE_PCDATA"};
24941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static final String[] debug_statenames = { "", "S_ANAME", "S_APOS", "S_AVAL", "S_BB", "S_BBC", "S_BBCD", "S_BBCDA", "S_BBCDAT", "S_BBCDATA", "S_CDATA", "S_CDATA2", "S_CDSECT", "S_CDSECT1", "S_CDSECT2", "S_COM", "S_COM2", "S_COM3", "S_COM4", "S_DECL", "S_DECL2", "S_DONE", "S_EMPTYTAG", "S_ENT", "S_EQ", "S_ETAG", "S_GI", "S_NCR", "S_PCDATA", "S_PI", "S_PITARGET", "S_QUOT", "S_STAGC", "S_TAG", "S_TAGWS", "S_XNCR"};
25041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
25141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
25241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// End of state table
25341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
25441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String thePublicid;			// Locator state
25541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String theSystemid;
25641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private int theLastLine;
25741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private int theLastColumn;
25841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private int theCurrentLine;
25941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private int theCurrentColumn;
26041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
26141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	int theState;					// Current state
26241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	int theNextState;				// Next state
26341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	char[] theOutputBuffer = new char[200];	// Output buffer
26441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	int theSize;					// Current buffer size
26541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	int[] theWinMap = {				// Windows chars map
26641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
26741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD,
26841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
26941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178};
27041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
27170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	/**
27270dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * Index into the state table for [state][input character - 2].
27370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * The state table consists of 4-entry runs on the form
27470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * { current state, input character, action, next state }.
27570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * We precompute the index into the state table for all possible
27670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * { current state, input character } and store the result in
27770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * the statetableIndex array. Since only some input characters
27870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * are present in the state table, we only do the computation for
27970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * characters 0 to the highest character value in the state table.
28070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * An input character of -2 is used to cover all other characters
28170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * as -2 is guaranteed not to match any input character entry
28270dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * in the state table.
28370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 *
28470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * <p>When doing lookups, the input character should first be tested
28570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * to be in the range [-1 (inclusive), statetableIndexMaxChar (exclusive)].
28670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * if it isn't use -2 as the input character.
28770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 *
28870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * <p>Finally, add 2 to the input character to cover for the fact that
28970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * Java doesn't support negative array indexes. Then look up
29070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * the value in the statetableIndex. If the value is -1, then
29170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * no action or next state was found for the { state, input } that
29270dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * you had. If it isn't -1, then action = statetable[value + 2] and
29370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * next state = statetable[value + 3]. That is, the value points
29470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * to the start of the answer 4-tuple in the statetable.
29570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 */
29670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	static short[][] statetableIndex;
29770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	/**
29870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * The highest character value seen in the statetable.
29970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * See the doc comment for statetableIndex to see how this
30070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 * is used.
30170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	 */
30270dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	static int statetableIndexMaxChar;
30370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath	static {
30470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		int maxState = -1;
30570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		int maxChar = -1;
30670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		for (int i = 0; i < statetable.length; i += 4) {
30770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			if (statetable[i] > maxState) {
30870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				maxState = statetable[i];
30970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				}
31070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			if (statetable[i + 1] > maxChar) {
31170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				maxChar = statetable[i + 1];
31270dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				}
31370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			}
31470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		statetableIndexMaxChar = maxChar + 1;
31570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath
31670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		statetableIndex = new short[maxState + 1][maxChar + 3];
31770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		for (int theState = 0; theState <= maxState; ++theState) {
31870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			for (int ch = -2; ch <= maxChar; ++ch) {
31970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				int hit = -1;
32070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				int action = 0;
32170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				for (int i = 0; i < statetable.length; i += 4) {
32270dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath					if (theState != statetable[i]) {
32370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						if (action != 0) break;
32470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						continue;
32570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						}
32670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath					if (statetable[i+1] == 0) {
32770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						hit = i;
32870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						action = statetable[i+2];
32970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						}
33070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath					else if (statetable[i+1] == ch) {
33170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						hit = i;
33270dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						action = statetable[i+2];
33370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						break;
33470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath						}
33570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath					}
33670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				statetableIndex[theState][ch + 2] = (short) hit;
33770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				}
33870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			}
33970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		}
34070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath
34141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Compensate for bug in PushbackReader that allows
34241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// pushing back EOF.
34341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void unread(PushbackReader r, int c) throws IOException {
34441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (c != -1) r.unread(c);
34541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
34641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
34741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Locator implementation
34841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
34941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public int getLineNumber() {
35041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return theLastLine;
35141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
35241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public int getColumnNumber() {
35341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return theLastColumn;
35441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
35541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public String getPublicId() {
35641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return thePublicid;
35741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
35841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public String getSystemId() {
35941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return theSystemid;
36041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
36141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
36241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
36341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Scanner implementation
36441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
36541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
36641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Reset document locator, supplying systemid and publicid.
36741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	@param systemid System id
36841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	@param publicid Public id
36941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	*/
37041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
37141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void resetDocumentLocator(String publicid, String systemid) {
37241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		thePublicid = publicid;
37341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theSystemid = systemid;
37441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theLastLine = theLastColumn = theCurrentLine = theCurrentColumn = 0;
37541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
37641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
37741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
37841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Scan HTML source, reporting lexical events.
37941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	@param r0 Reader that provides characters
38041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	@param h ScanHandler that accepts lexical events.
38141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	*/
38241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
38341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void scan(Reader r0, ScanHandler h) throws IOException, SAXException {
38441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theState = S_PCDATA;
38541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		PushbackReader r;
38670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		if (r0 instanceof BufferedReader) {
38770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			r = new PushbackReader(r0, 5);
38841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
38941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else {
39070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			r = new PushbackReader(new BufferedReader(r0), 5);
39141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
39241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
39341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int firstChar = r.read();	// Remove any leading BOM
39441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (firstChar != '\uFEFF') unread(r, firstChar);
39541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
39641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		while (theState != S_DONE) {
39741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			int ch = r.read();
39841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
39941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			// Process control characters
40041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (ch >= 0x80 && ch <= 0x9F) ch = theWinMap[ch-0x80];
40141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
40241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (ch == '\r') {
40341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				ch = r.read();		// expect LF next
40441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (ch != '\n') {
40541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					unread(r, ch);	// nope
40641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					ch = '\n';
40741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
40841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
40941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
41041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (ch == '\n') {
41141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theCurrentLine++;
41241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theCurrentColumn = 0;
41341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
41441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
41541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theCurrentColumn++;
41641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
41741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
41841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (!(ch >= 0x20 || ch == '\n' || ch == '\t' || ch == -1)) continue;
41941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
42041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			// Search state table
42170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			int adjCh = (ch >= -1 && ch < statetableIndexMaxChar) ? ch : -2;
42270dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			int statetableRow = statetableIndex[theState][adjCh + 2];
42341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			int action = 0;
42470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			if (statetableRow != -1) {
42570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				action = statetable[statetableRow + 2];
42670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				theNextState = statetable[statetableRow + 3];
42741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
42870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath
42941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//			System.err.println("In " + debug_statenames[theState] + " got " + nicechar(ch) + " doing " + debug_actionnames[action] + " then " + debug_statenames[theNextState]);
43041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			switch (action) {
43141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case 0:
43241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				throw new Error(
43370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath					"HTMLScanner can't cope with " + Integer.toString(ch) + " in state " +
43470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath					Integer.toString(theState));
43570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_ADUP:
43641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.adup(theOutputBuffer, 0, theSize);
43741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
43841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
43970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_ADUP_SAVE:
44041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.adup(theOutputBuffer, 0, theSize);
44141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
44241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save(ch, h);
44341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
44470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_ADUP_STAGC:
44541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.adup(theOutputBuffer, 0, theSize);
44641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
44741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.stagc(theOutputBuffer, 0, theSize);
44841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
44970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_ANAME:
45041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.aname(theOutputBuffer, 0, theSize);
45141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
45241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
45370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_ANAME_ADUP:
45441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.aname(theOutputBuffer, 0, theSize);
45541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
45641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.adup(theOutputBuffer, 0, theSize);
45741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
45870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_ANAME_ADUP_STAGC:
45941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.aname(theOutputBuffer, 0, theSize);
46041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
46141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.adup(theOutputBuffer, 0, theSize);
46241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.stagc(theOutputBuffer, 0, theSize);
46341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
46470dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_AVAL:
46541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.aval(theOutputBuffer, 0, theSize);
46641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
46741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
46870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_AVAL_STAGC:
46941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.aval(theOutputBuffer, 0, theSize);
47041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
47141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.stagc(theOutputBuffer, 0, theSize);
47241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
47341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_CDATA:
47441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				mark();
47541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// suppress the final "]]" in the buffer
47641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (theSize > 1) theSize -= 2;
47741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pcdata(theOutputBuffer, 0, theSize);
47841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
47941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
48041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_ENTITY_START:
48141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pcdata(theOutputBuffer, 0, theSize);
48241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
48341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save(ch, h);
48441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
48541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_ENTITY:
48641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				mark();
48741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				char ch1 = (char)ch;
48841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.out.println("Got " + ch1 + " in state " + ((theState == S_ENT) ? "S_ENT" : ((theState == S_NCR) ? "S_NCR" : "UNK")));
48941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (theState == S_ENT && ch1 == '#') {
49041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					theNextState = S_NCR;
49141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					save(ch, h);
49241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					break;
49341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
49441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				else if (theState == S_NCR && (ch1 == 'x' || ch1 == 'X')) {
49541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					theNextState = S_XNCR;
49641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					save(ch, h);
49741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					break;
49841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
49941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				else if (theState == S_ENT && Character.isLetterOrDigit(ch1)) {
50041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					save(ch, h);
50141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					break;
50241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
50341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				else if (theState == S_NCR && Character.isDigit(ch1)) {
50441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					save(ch, h);
50541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					break;
50641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
50741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				else if (theState == S_XNCR && (Character.isDigit(ch1) || "abcdefABCDEF".indexOf(ch1) != -1)) {
50841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					save(ch, h);
50941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					break;
51041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
51141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
51241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// The whole entity reference has been collected
51341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println("%%" + new String(theOutputBuffer, 0, theSize));
51441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.entity(theOutputBuffer, 1, theSize - 1);
51541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				int ent = h.getEntity();
51641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println("%% value = " + ent);
51741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (ent != 0) {
51841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					theSize = 0;
51941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					if (ent >= 0x80 && ent <= 0x9F) {
52041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						ent = theWinMap[ent-0x80];
52141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						}
52241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					if (ent < 0x20) {
52341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						// Control becomes space
52441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						ent = 0x20;
52541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						}
52641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					else if (ent >= 0xD800 && ent <= 0xDFFF) {
52741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						// Surrogates get dropped
52841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						ent = 0;
52941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						}
53041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					else if (ent <= 0xFFFF) {
53141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						// BMP character
53241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						save(ent, h);
53341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						}
53441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					else {
53541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						// Astral converted to two surrogates
53641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						ent -= 0x10000;
53741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						save((ent>>10) + 0xD800, h);
53841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						save((ent&0x3FF) + 0xDC00, h);
53941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						}
54041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					if (ch != ';') {
54141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						unread(r, ch);
54241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						theCurrentColumn--;
54341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						}
54441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
54541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				else {
54641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					unread(r, ch);
54741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					theCurrentColumn--;
54841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
54941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theNextState = S_PCDATA;
55041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
55170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_ETAG:
55241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.etag(theOutputBuffer, 0, theSize);
55341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
55441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
55570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_DECL:
55641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.decl(theOutputBuffer, 0, theSize);
55741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
55841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
55970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_GI:
56041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.gi(theOutputBuffer, 0, theSize);
56141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
56241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
56341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_GI_STAGC:
56441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.gi(theOutputBuffer, 0, theSize);
56541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
56641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.stagc(theOutputBuffer, 0, theSize);
56741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
56870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_LT:
56941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				mark();
57041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save('<', h);
57141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save(ch, h);
57241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
57341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_LT_PCDATA:
57441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				mark();
57541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save('<', h);
57641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pcdata(theOutputBuffer, 0, theSize);
57741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
57841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
57970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_PCDATA:
58041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				mark();
58141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pcdata(theOutputBuffer, 0, theSize);
58241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
58341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
58441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_CMNT:
58541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				mark();
58641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.cmnt(theOutputBuffer, 0, theSize);
58741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
58841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
58941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_MINUS3:
59041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save('-', h);
59141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save(' ', h);
59241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
59341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_MINUS2:
59441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save('-', h);
59541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save(' ', h);
59641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// fall through into A_MINUS
59741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_MINUS:
59841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save('-', h);
59941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save(ch, h);
60041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
60170dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_PI:
60241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				mark();
60341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pi(theOutputBuffer, 0, theSize);
60441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
60541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
60670dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_PITARGET:
60741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pitarget(theOutputBuffer, 0, theSize);
60841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
60941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
61070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_PITARGET_PI:
61141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pitarget(theOutputBuffer, 0, theSize);
61241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
61341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pi(theOutputBuffer, 0, theSize);
61441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
61570dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_SAVE:
61641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save(ch, h);
61741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
61870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_SKIP:
61941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
62070dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_SP:
62141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				save(' ', h);
62241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
62370dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_STAGC:
62441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.stagc(theOutputBuffer, 0, theSize);
62541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
62641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
62741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_EMPTYTAG:
62841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				mark();
62941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println("%%% Empty tag seen");
63041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (theSize > 0) h.gi(theOutputBuffer, 0, theSize);
63141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
63241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.stage(theOutputBuffer, 0, theSize);
63341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
63441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			case A_UNGET:
63541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				unread(r, ch);
63641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theCurrentColumn--;
63741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
63870dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath			case A_UNSAVE_PCDATA:
63941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (theSize > 0) theSize--;
64041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pcdata(theOutputBuffer, 0, theSize);
64141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
64241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				break;
64341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			default:
64441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				throw new Error("Can't process state " + action);
64541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
64641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theState = theNextState;
64741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
64841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		h.eof(theOutputBuffer, 0, 0);
64941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
65041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
65141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
65241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	* Mark the current scan position as a "point of interest" - start of a tag,
65341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	* cdata, processing instruction etc.
65441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	*/
65541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
65641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void mark() {
65741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theLastColumn = theCurrentColumn;
65841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theLastLine = theCurrentLine;
65941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
66041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
66141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
66241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A callback for the ScanHandler that allows it to force
66341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	the lexer state to CDATA content (no markup is recognized except
66441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	the end of element.
66541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	*/
66641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
66741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void startCDATA() { theNextState = S_CDATA; }
66841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
66941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void save(int ch, ScanHandler h) throws IOException, SAXException {
67041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theSize >= theOutputBuffer.length - 20) {
67141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (theState == S_PCDATA || theState == S_CDATA) {
67241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// Return a buffer-sized chunk of PCDATA
67341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				h.pcdata(theOutputBuffer, 0, theSize);
67441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSize = 0;
67541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
67641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
67741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// Grow the buffer size
67841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				char[] newOutputBuffer = new char[theOutputBuffer.length * 2];
67970dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath				System.arraycopy(theOutputBuffer, 0, newOutputBuffer, 0, theSize+1);
68041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theOutputBuffer = newOutputBuffer;
68141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
68241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
68341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theOutputBuffer[theSize++] = (char)ch;
68441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
68541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
68641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
68741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Test procedure.  Reads HTML from the standard input and writes
68841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	PYX to the standard output.
68941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	*/
69041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
69141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public static void main(String[] argv) throws IOException, SAXException {
69241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Scanner s = new HTMLScanner();
69341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Reader r = new InputStreamReader(System.in, "UTF-8");
69441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Writer w = new OutputStreamWriter(System.out, "UTF-8");
69541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		PYXWriter pw = new PYXWriter(w);
69641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		s.scan(r, pw);
69741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		w.close();
69841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
69941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
70041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
70141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static String nicechar(int in) {
70241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (in == '\n') return "\\n";
70341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (in < 32) return "0x"+Integer.toHexString(in);
70441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return "'"+((char)in)+"'";
70541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
70641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
70741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	}
708