001    /* Generated By:JavaCC: Do not edit this line. UCode_UCodeESC_CharStream.java Version 0.7pre6 */
002    /* The previous line keeps JavaCC quiet. In fact, the JavaCC generated file
003       has been edited to fix some bugs. */
004    package com.thaiopensource.relaxng.parse.compact;
005    
006    import com.thaiopensource.util.Utf16;
007    import com.thaiopensource.relaxng.parse.BuildException;
008    
009    import java.io.IOException;
010    
011    /**
012     * An implementation of interface CharStream, where the stream is assumed to
013     * contain 16-bit unicode characters.
014     */
015    public final class UCode_UCodeESC_CharStream {
016      public static final boolean staticFlag = false;
017    
018      static final int hexval(char c) {
019        switch (c) {
020        case '0':
021          return 0;
022        case '1':
023          return 1;
024        case '2':
025          return 2;
026        case '3':
027          return 3;
028        case '4':
029          return 4;
030        case '5':
031          return 5;
032        case '6':
033          return 6;
034        case '7':
035          return 7;
036        case '8':
037          return 8;
038        case '9':
039          return 9;
040    
041        case 'a':
042        case 'A':
043          return 10;
044        case 'b':
045        case 'B':
046          return 11;
047        case 'c':
048        case 'C':
049          return 12;
050        case 'd':
051        case 'D':
052          return 13;
053        case 'e':
054        case 'E':
055          return 14;
056        case 'f':
057        case 'F':
058          return 15;
059        }
060        return -1;
061      }
062    
063      public int bufpos = -1;
064      int bufsize;
065      int available;
066      int tokenBegin;
067      private int bufline[];
068      private int bufcolumn[];
069    
070      private int column = 0;
071      private int line = 1;
072    
073      private java.io.Reader inputStream;
074      private boolean closed = false;
075    
076      private boolean prevCharIsLF = false;
077    
078      private char[] nextCharBuf;
079      private char[] buffer;
080      private int maxNextCharInd = 0;
081      private int nextCharInd = -1;
082      private int inBuf = 0;
083    
084      private final void ExpandBuff(boolean wrapAround) {
085        char[] newbuffer = new char[bufsize + 2048];
086        int newbufline[] = new int[bufsize + 2048];
087        int newbufcolumn[] = new int[bufsize + 2048];
088    
089        if (wrapAround) {
090          System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
091          System.arraycopy(buffer, 0, newbuffer,
092                           bufsize - tokenBegin, bufpos);
093          buffer = newbuffer;
094    
095          System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
096          System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
097          bufline = newbufline;
098    
099          System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
100          System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
101          bufcolumn = newbufcolumn;
102    
103          bufpos += (bufsize - tokenBegin);
104        }
105        else {
106          System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
107          buffer = newbuffer;
108    
109          System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
110          bufline = newbufline;
111    
112          System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
113          bufcolumn = newbufcolumn;
114    
115          bufpos -= tokenBegin;
116        }
117    
118        available = (bufsize += 2048);
119        tokenBegin = 0;
120      }
121    
122      private final void FillBuff() throws EOFException {
123        int i;
124        if (maxNextCharInd == 4096)
125          maxNextCharInd = nextCharInd = 0;
126    
127        if (closed)
128          throw new EOFException();
129        try {
130          if ((i = inputStream.read(nextCharBuf, maxNextCharInd, 4096 - maxNextCharInd)) == -1) {
131            closed = true;
132            inputStream.close();
133            throw new EOFException();
134          }
135          else
136            maxNextCharInd += i;
137        }
138        catch (IOException e) {
139          throw new BuildException(e);
140        }
141      }
142    
143      private final char ReadChar() throws EOFException {
144        if (++nextCharInd >= maxNextCharInd)
145          FillBuff();
146    
147        return nextCharBuf[nextCharInd];
148      }
149    
150      private final char PeekChar() throws EOFException {
151        char c = ReadChar();
152        --nextCharInd;
153        return c;
154      }
155    
156      public final char BeginToken() throws EOFException {
157        if (inBuf > 0) {
158          --inBuf;
159          return buffer[tokenBegin = (bufpos == bufsize - 1) ? (bufpos = 0)
160                  : ++bufpos];
161        }
162    
163        tokenBegin = 0;
164        bufpos = -1;
165    
166        return readChar();
167      }
168    
169      private final void AdjustBuffSize() {
170        if (available == bufsize) {
171          if (tokenBegin > 2048) {
172            bufpos = 0;
173            available = tokenBegin;
174          }
175          else
176            ExpandBuff(false);
177        }
178        else if (available > tokenBegin)
179          available = bufsize;
180        else if ((tokenBegin - available) < 2048)
181          ExpandBuff(true);
182        else
183          available = tokenBegin;
184      }
185    
186      private final void UpdateLineColumn(char c) {
187        column++;
188    
189        if (prevCharIsLF) {
190          prevCharIsLF = false;
191          line += (column = 1);
192        }
193    
194        switch (c) {
195        case NEWLINE_MARKER:
196          prevCharIsLF = true;
197          break;
198        case '\t':
199          column--;
200          column += (8 - (column & 07));
201          break;
202        default :
203          break;
204        }
205    
206        bufline[bufpos] = line;
207        bufcolumn[bufpos] = column;
208      }
209    
210      private final char NEWLINE_MARKER = '\u0000';
211    
212      public final char readChar() throws EOFException {
213        if (inBuf > 0) {
214          --inBuf;
215          return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
216        }
217    
218        char c;
219        try {
220          c = ReadChar();
221          switch (c) {
222          case '\r':
223            c = NEWLINE_MARKER;
224            try {
225              if (PeekChar() == '\n')
226                ReadChar();
227            }
228            catch (EOFException e) {
229            }
230            break;
231          case '\n':
232            c = NEWLINE_MARKER;
233            break;
234          case '\t':
235            break;
236          default:
237            if (c >= 0x20) {
238              if (Utf16.isSurrogate(c)) {
239                if (Utf16.isSurrogate2(c))
240                  throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 1);
241                if (++bufpos == available)
242                  AdjustBuffSize();
243                buffer[bufpos] = c;
244                // UpdateLineColumn(c);
245                try {
246                  c = ReadChar();
247                }
248                catch (EOFException e) {
249                  throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 1);
250                }
251                if (!Utf16.isSurrogate2(c))
252                  throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 2);
253              }
254              break;
255            }
256            // fall through
257          case '\uFFFE':
258          case '\uFFFF':
259            throw new EscapeSyntaxException("illegal_char_code", line, column + 1);
260          }
261        }
262        catch (EOFException e) {
263          if (bufpos == -1) {
264            if (++bufpos == available)
265              AdjustBuffSize();
266            bufline[bufpos] = line;
267            bufcolumn[bufpos] = column;
268          }
269          throw e;
270        }
271        if (++bufpos == available)
272          AdjustBuffSize();
273        buffer[bufpos] = c;
274        UpdateLineColumn(c);
275        try {
276          if (c != '\\' || PeekChar() != 'x')
277            return c;
278        }
279        catch (EOFException e) {
280          return c;
281        }
282    
283        int xCnt = 1;
284        for (;;) {
285          ReadChar();
286          if (++bufpos == available)
287            AdjustBuffSize();
288          buffer[bufpos] = 'x';
289          UpdateLineColumn('x');
290          try {
291            c = PeekChar();
292          }
293          catch (EOFException e) {
294            backup(xCnt);
295            return '\\';
296          }
297          if (c == '{') {
298            ReadChar();
299            column++;
300            // backup past the 'x's
301            bufpos -= xCnt;
302            if (bufpos < 0)
303              bufpos += bufsize;
304            break;
305          }
306          if (c != 'x') {
307            backup(xCnt);
308            return '\\';
309          }
310          xCnt++;
311        }
312        try {
313          int scalarValue = hexval(ReadChar());
314          column++;
315          if (scalarValue < 0)
316            throw new EscapeSyntaxException("illegal_hex_digit", line, column);
317          while ((c = ReadChar()) != '}') {
318            column++;
319            int n = hexval(c);
320            if (n < 0)
321              throw new EscapeSyntaxException("illegal_hex_digit", line, column);
322            scalarValue <<= 4;
323            scalarValue |= n;
324            if (scalarValue >= 0x110000)
325              throw new EscapeSyntaxException("char_code_too_big", line, column);
326          }
327          column++; // for the '}'
328          if (scalarValue <= 0xFFFF) {
329            c = (char)scalarValue;
330            switch (c) {
331            case '\n':
332            case '\r':
333            case '\t':
334              break;
335            default:
336              if (c >= 0x20 && !Utf16.isSurrogate(c))
337                break;
338              // fall through
339            case '\uFFFE':
340            case '\uFFFF':
341              throw new EscapeSyntaxException("illegal_char_code_ref", line, column);
342            }
343            buffer[bufpos] = c;
344            return c;
345          }
346          c = Utf16.surrogate1(scalarValue);
347          buffer[bufpos] = c;
348          int bufpos1 = bufpos;
349          if (++bufpos == bufsize)
350            bufpos = 0;
351          buffer[bufpos] = Utf16.surrogate2(scalarValue);
352          bufline[bufpos] = bufline[bufpos1];
353          bufcolumn[bufpos] = bufcolumn[bufpos1];
354          backup(1);
355          return c;
356        }
357        catch (EOFException e) {
358          throw new EscapeSyntaxException("incomplete_escape", line, column);
359        }
360      }
361    
362      /**
363       * @deprecated
364       * @see #getEndColumn
365       */
366    
367      public final int getColumn() {
368        return bufcolumn[bufpos];
369      }
370    
371      /**
372       * @deprecated
373       * @see #getEndLine
374       */
375    
376      public final int getLine() {
377        return bufline[bufpos];
378      }
379    
380      public final int getEndColumn() {
381        return bufcolumn[bufpos];
382      }
383    
384      public final int getEndLine() {
385        return bufline[bufpos];
386      }
387    
388      public final int getBeginColumn() {
389        return bufcolumn[tokenBegin];
390      }
391    
392      public final int getBeginLine() {
393        return bufline[tokenBegin];
394      }
395    
396      public final void backup(int amount) {
397    
398        inBuf += amount;
399        if ((bufpos -= amount) < 0)
400          bufpos += bufsize;
401      }
402    
403      public UCode_UCodeESC_CharStream(java.io.Reader dstream,
404                                       int startline, int startcolumn, int buffersize) {
405        inputStream = dstream;
406        line = startline;
407        column = startcolumn - 1;
408    
409        available = bufsize = buffersize;
410        buffer = new char[buffersize];
411        bufline = new int[buffersize];
412        bufcolumn = new int[buffersize];
413        nextCharBuf = new char[4096];
414        skipBOM();
415      }
416    
417      public UCode_UCodeESC_CharStream(java.io.Reader dstream,
418                                       int startline, int startcolumn) {
419        this(dstream, startline, startcolumn, 4096);
420      }
421    
422      public void ReInit(java.io.Reader dstream,
423                         int startline, int startcolumn, int buffersize) {
424        inputStream = dstream;
425        closed = false;
426        line = startline;
427        column = startcolumn - 1;
428    
429        if (buffer == null || buffersize != buffer.length) {
430          available = bufsize = buffersize;
431          buffer = new char[buffersize];
432          bufline = new int[buffersize];
433          bufcolumn = new int[buffersize];
434          nextCharBuf = new char[4096];
435        }
436        prevCharIsLF = false;
437        tokenBegin = inBuf = maxNextCharInd = 0;
438        nextCharInd = bufpos = -1;
439        skipBOM();
440      }
441    
442      public void ReInit(java.io.Reader dstream,
443                         int startline, int startcolumn) {
444        ReInit(dstream, startline, startcolumn, 4096);
445      }
446    
447      public UCode_UCodeESC_CharStream(java.io.InputStream dstream, int startline,
448                                       int startcolumn, int buffersize) {
449        this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
450      }
451    
452      public UCode_UCodeESC_CharStream(java.io.InputStream dstream, int startline,
453                                       int startcolumn) {
454        this(dstream, startline, startcolumn, 4096);
455      }
456    
457      public void ReInit(java.io.InputStream dstream, int startline,
458                         int startcolumn, int buffersize) {
459        ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
460      }
461    
462      public void ReInit(java.io.InputStream dstream, int startline,
463                         int startcolumn) {
464        ReInit(dstream, startline, startcolumn, 4096);
465      }
466    
467      static private final char BOM = '\ufeff';
468    
469      private void skipBOM() {
470        try {
471          if (PeekChar() == BOM)
472            ReadChar();
473        }
474        catch (EOFException e) {
475        }
476      }
477    
478      public final String GetImage() {
479        if (bufpos >= tokenBegin)
480          return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
481        else
482          return new String(buffer, tokenBegin, bufsize - tokenBegin) +
483                  new String(buffer, 0, bufpos + 1);
484      }
485    
486      public final char[] GetSuffix(int len) {
487        char[] ret = new char[len];
488    
489        if ((bufpos + 1) >= len)
490          System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
491        else {
492          System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
493                           len - bufpos - 1);
494          System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
495        }
496    
497        return ret;
498      }
499    
500      public void Done() {
501        nextCharBuf = null;
502        buffer = null;
503        bufline = null;
504        bufcolumn = null;
505      }
506    
507      /**
508       * Method to adjust line and column numbers for the start of a token.<BR>
509       */
510      public void adjustBeginLineColumn(int newLine, int newCol) {
511        int start = tokenBegin;
512        int len;
513    
514        if (bufpos >= tokenBegin) {
515          len = bufpos - tokenBegin + inBuf + 1;
516        }
517        else {
518          len = bufsize - tokenBegin + bufpos + 1 + inBuf;
519        }
520    
521        int i = 0, j = 0, k = 0;
522        int nextColDiff = 0, columnDiff = 0;
523    
524        while (i < len &&
525                bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) {
526          bufline[j] = newLine;
527          nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
528          bufcolumn[j] = newCol + columnDiff;
529          columnDiff = nextColDiff;
530          i++;
531        }
532    
533        if (i < len) {
534          bufline[j] = newLine++;
535          bufcolumn[j] = newCol + columnDiff;
536    
537          while (i++ < len) {
538            if (bufline[j = start % bufsize] != bufline[++start % bufsize])
539              bufline[j] = newLine++;
540            else
541              bufline[j] = newLine;
542          }
543        }
544    
545        line = bufline[j];
546        column = bufcolumn[j];
547      }
548    
549    }