1 /*
   2  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 /*
  26  * Copyright (C) 2004-2011
  27  *
  28  * Permission is hereby granted, free of charge, to any person obtaining a copy
  29  * of this software and associated documentation files (the "Software"), to deal
  30  * in the Software without restriction, including without limitation the rights
  31  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  32  * copies of the Software, and to permit persons to whom the Software is
  33  * furnished to do so, subject to the following conditions:
  34  *
  35  * The above copyright notice and this permission notice shall be included in
  36  * all copies or substantial portions of the Software.
  37  *
  38  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  39  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  40  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  41  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  42  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  43  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  44  * THE SOFTWARE.
  45  */
  46 /* Generated By:JavaCC: Do not edit this line. UCode_UCodeESC_CharStream.java Version 0.7pre6 */
  47 /* The previous line keeps JavaCC quiet. In fact, the JavaCC generated file
  48    has been edited to fix some bugs. */
  49 package com.sun.xml.internal.rngom.parse.compact;
  50 
  51 import com.sun.xml.internal.rngom.util.Utf16;
  52 import com.sun.xml.internal.rngom.ast.builder.BuildException;
  53 
  54 import java.io.IOException;
  55 
  56 /**
  57  * An implementation of interface CharStream, where the stream is assumed to
  58  * contain 16-bit unicode characters.
  59  */
  60 public final class UCode_UCodeESC_CharStream {
  61   public static final boolean staticFlag = false;
  62 
  63   static final int hexval(char c) {
  64     switch (c) {
  65     case '0':
  66       return 0;
  67     case '1':
  68       return 1;
  69     case '2':
  70       return 2;
  71     case '3':
  72       return 3;
  73     case '4':
  74       return 4;
  75     case '5':
  76       return 5;
  77     case '6':
  78       return 6;
  79     case '7':
  80       return 7;
  81     case '8':
  82       return 8;
  83     case '9':
  84       return 9;
  85 
  86     case 'a':
  87     case 'A':
  88       return 10;
  89     case 'b':
  90     case 'B':
  91       return 11;
  92     case 'c':
  93     case 'C':
  94       return 12;
  95     case 'd':
  96     case 'D':
  97       return 13;
  98     case 'e':
  99     case 'E':
 100       return 14;
 101     case 'f':
 102     case 'F':
 103       return 15;
 104     }
 105     return -1;
 106   }
 107 
 108   public int bufpos = -1;
 109   int bufsize;
 110   int available;
 111   int tokenBegin;
 112   private int bufline[];
 113   private int bufcolumn[];
 114 
 115   private int column = 0;
 116   private int line = 1;
 117 
 118   private java.io.Reader inputStream;
 119   private boolean closed = false;
 120 
 121   private boolean prevCharIsLF = false;
 122 
 123   private char[] nextCharBuf;
 124   private char[] buffer;
 125   private int maxNextCharInd = 0;
 126   private int nextCharInd = -1;
 127   private int inBuf = 0;
 128 
 129   private final void ExpandBuff(boolean wrapAround) {
 130     char[] newbuffer = new char[bufsize + 2048];
 131     int newbufline[] = new int[bufsize + 2048];
 132     int newbufcolumn[] = new int[bufsize + 2048];
 133 
 134     if (wrapAround) {
 135       System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
 136       System.arraycopy(buffer, 0, newbuffer,
 137                        bufsize - tokenBegin, bufpos);
 138       buffer = newbuffer;
 139 
 140       System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
 141       System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
 142       bufline = newbufline;
 143 
 144       System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
 145       System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
 146       bufcolumn = newbufcolumn;
 147 
 148       bufpos += (bufsize - tokenBegin);
 149     }
 150     else {
 151       System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
 152       buffer = newbuffer;
 153 
 154       System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
 155       bufline = newbufline;
 156 
 157       System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
 158       bufcolumn = newbufcolumn;
 159 
 160       bufpos -= tokenBegin;
 161     }
 162 
 163     available = (bufsize += 2048);
 164     tokenBegin = 0;
 165   }
 166 
 167   private final void FillBuff() throws EOFException {
 168     int i;
 169     if (maxNextCharInd == 4096)
 170       maxNextCharInd = nextCharInd = 0;
 171 
 172     if (closed)
 173       throw new EOFException();
 174     try {
 175       if ((i = inputStream.read(nextCharBuf, maxNextCharInd, 4096 - maxNextCharInd)) == -1) {
 176         closed = true;
 177         inputStream.close();
 178         throw new EOFException();
 179       }
 180       else
 181         maxNextCharInd += i;
 182     }
 183     catch (IOException e) {
 184       throw new BuildException(e);
 185     }
 186   }
 187 
 188   private final char ReadChar() throws EOFException {
 189     if (++nextCharInd >= maxNextCharInd)
 190       FillBuff();
 191 
 192     return nextCharBuf[nextCharInd];
 193   }
 194 
 195   private final char PeekChar() throws EOFException {
 196     char c = ReadChar();
 197     --nextCharInd;
 198     return c;
 199   }
 200 
 201   public final char BeginToken() throws EOFException {
 202     if (inBuf > 0) {
 203       --inBuf;
 204       return buffer[tokenBegin = (bufpos == bufsize - 1) ? (bufpos = 0)
 205               : ++bufpos];
 206     }
 207 
 208     tokenBegin = 0;
 209     bufpos = -1;
 210 
 211     return readChar();
 212   }
 213 
 214   private final void AdjustBuffSize() {
 215     if (available == bufsize) {
 216       if (tokenBegin > 2048) {
 217         bufpos = 0;
 218         available = tokenBegin;
 219       }
 220       else
 221         ExpandBuff(false);
 222     }
 223     else if (available > tokenBegin)
 224       available = bufsize;
 225     else if ((tokenBegin - available) < 2048)
 226       ExpandBuff(true);
 227     else
 228       available = tokenBegin;
 229   }
 230 
 231   private final void UpdateLineColumn(char c) {
 232     column++;
 233 
 234     if (prevCharIsLF) {
 235       prevCharIsLF = false;
 236       line += (column = 1);
 237     }
 238 
 239     switch (c) {
 240     case NEWLINE_MARKER:
 241       prevCharIsLF = true;
 242       break;
 243     case '\t':
 244       column--;
 245       column += (8 - (column & 07));
 246       break;
 247     default :
 248       break;
 249     }
 250 
 251     bufline[bufpos] = line;
 252     bufcolumn[bufpos] = column;
 253   }
 254 
 255   private final char NEWLINE_MARKER = '\u0000';
 256 
 257   public final char readChar() throws EOFException {
 258     if (inBuf > 0) {
 259       --inBuf;
 260       return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
 261     }
 262 
 263     char c;
 264     try {
 265       c = ReadChar();
 266       switch (c) {
 267       case '\r':
 268         c = NEWLINE_MARKER;
 269         try {
 270           if (PeekChar() == '\n')
 271             ReadChar();
 272         }
 273         catch (EOFException e) {
 274         }
 275         break;
 276       case '\n':
 277         c = NEWLINE_MARKER;
 278         break;
 279       case '\t':
 280         break;
 281       default:
 282         if (c >= 0x20) {
 283           if (Utf16.isSurrogate(c)) {
 284             if (Utf16.isSurrogate2(c))
 285               throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 1);
 286             if (++bufpos == available)
 287               AdjustBuffSize();
 288             buffer[bufpos] = c;
 289             // UpdateLineColumn(c);
 290             try {
 291               c = ReadChar();
 292             }
 293             catch (EOFException e) {
 294               throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 1);
 295             }
 296             if (!Utf16.isSurrogate2(c))
 297               throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 2);
 298           }
 299           break;
 300         }
 301         // fall through
 302       case '\uFFFE':
 303       case '\uFFFF':
 304         throw new EscapeSyntaxException("illegal_char_code", line, column + 1);
 305       }
 306     }
 307     catch (EOFException e) {
 308       if (bufpos == -1) {
 309         if (++bufpos == available)
 310           AdjustBuffSize();
 311         bufline[bufpos] = line;
 312         bufcolumn[bufpos] = column;
 313       }
 314       throw e;
 315     }
 316     if (++bufpos == available)
 317       AdjustBuffSize();
 318     buffer[bufpos] = c;
 319     UpdateLineColumn(c);
 320     try {
 321       if (c != '\\' || PeekChar() != 'x')
 322         return c;
 323     }
 324     catch (EOFException e) {
 325       return c;
 326     }
 327 
 328     int xCnt = 1;
 329     for (;;) {
 330       ReadChar();
 331       if (++bufpos == available)
 332         AdjustBuffSize();
 333       buffer[bufpos] = 'x';
 334       UpdateLineColumn('x');
 335       try {
 336         c = PeekChar();
 337       }
 338       catch (EOFException e) {
 339         backup(xCnt);
 340         return '\\';
 341       }
 342       if (c == '{') {
 343         ReadChar();
 344         column++;
 345         // backup past the 'x's
 346         bufpos -= xCnt;
 347         if (bufpos < 0)
 348           bufpos += bufsize;
 349         break;
 350       }
 351       if (c != 'x') {
 352         backup(xCnt);
 353         return '\\';
 354       }
 355       xCnt++;
 356     }
 357     try {
 358       int scalarValue = hexval(ReadChar());
 359       column++;
 360       if (scalarValue < 0)
 361         throw new EscapeSyntaxException("illegal_hex_digit", line, column);
 362       while ((c = ReadChar()) != '}') {
 363         column++;
 364         int n = hexval(c);
 365         if (n < 0)
 366           throw new EscapeSyntaxException("illegal_hex_digit", line, column);
 367         scalarValue <<= 4;
 368         scalarValue |= n;
 369         if (scalarValue >= 0x110000)
 370           throw new EscapeSyntaxException("char_code_too_big", line, column);
 371       }
 372       column++; // for the '}'
 373       if (scalarValue <= 0xFFFF) {
 374         c = (char)scalarValue;
 375         switch (c) {
 376         case '\n':
 377         case '\r':
 378         case '\t':
 379           break;
 380         default:
 381           if (c >= 0x20 && !Utf16.isSurrogate(c))
 382             break;
 383           // fall through
 384         case '\uFFFE':
 385         case '\uFFFF':
 386           throw new EscapeSyntaxException("illegal_char_code_ref", line, column);
 387         }
 388         buffer[bufpos] = c;
 389         return c;
 390       }
 391       c = Utf16.surrogate1(scalarValue);
 392       buffer[bufpos] = c;
 393       int bufpos1 = bufpos;
 394       if (++bufpos == bufsize)
 395         bufpos = 0;
 396       buffer[bufpos] = Utf16.surrogate2(scalarValue);
 397       bufline[bufpos] = bufline[bufpos1];
 398       bufcolumn[bufpos] = bufcolumn[bufpos1];
 399       backup(1);
 400       return c;
 401     }
 402     catch (EOFException e) {
 403       throw new EscapeSyntaxException("incomplete_escape", line, column);
 404     }
 405   }
 406 
 407   /**
 408    * @deprecated
 409    * @see #getEndColumn
 410    */
 411 
 412   public final int getColumn() {
 413     return bufcolumn[bufpos];
 414   }
 415 
 416   /**
 417    * @deprecated
 418    * @see #getEndLine
 419    */
 420 
 421   public final int getLine() {
 422     return bufline[bufpos];
 423   }
 424 
 425   public final int getEndColumn() {
 426     return bufcolumn[bufpos];
 427   }
 428 
 429   public final int getEndLine() {
 430     return bufline[bufpos];
 431   }
 432 
 433   public final int getBeginColumn() {
 434     return bufcolumn[tokenBegin];
 435   }
 436 
 437   public final int getBeginLine() {
 438     return bufline[tokenBegin];
 439   }
 440 
 441   public final void backup(int amount) {
 442 
 443     inBuf += amount;
 444     if ((bufpos -= amount) < 0)
 445       bufpos += bufsize;
 446   }
 447 
 448   public UCode_UCodeESC_CharStream(java.io.Reader dstream,
 449                                    int startline, int startcolumn, int buffersize) {
 450     inputStream = dstream;
 451     line = startline;
 452     column = startcolumn - 1;
 453 
 454     available = bufsize = buffersize;
 455     buffer = new char[buffersize];
 456     bufline = new int[buffersize];
 457     bufcolumn = new int[buffersize];
 458     nextCharBuf = new char[4096];
 459     skipBOM();
 460   }
 461 
 462   public UCode_UCodeESC_CharStream(java.io.Reader dstream,
 463                                    int startline, int startcolumn) {
 464     this(dstream, startline, startcolumn, 4096);
 465   }
 466 
 467   public void ReInit(java.io.Reader dstream,
 468                      int startline, int startcolumn, int buffersize) {
 469     inputStream = dstream;
 470     closed = false;
 471     line = startline;
 472     column = startcolumn - 1;
 473 
 474     if (buffer == null || buffersize != buffer.length) {
 475       available = bufsize = buffersize;
 476       buffer = new char[buffersize];
 477       bufline = new int[buffersize];
 478       bufcolumn = new int[buffersize];
 479       nextCharBuf = new char[4096];
 480     }
 481     prevCharIsLF = false;
 482     tokenBegin = inBuf = maxNextCharInd = 0;
 483     nextCharInd = bufpos = -1;
 484     skipBOM();
 485   }
 486 
 487   public void ReInit(java.io.Reader dstream,
 488                      int startline, int startcolumn) {
 489     ReInit(dstream, startline, startcolumn, 4096);
 490   }
 491 
 492   public UCode_UCodeESC_CharStream(java.io.InputStream dstream, int startline,
 493                                    int startcolumn, int buffersize) {
 494     this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
 495   }
 496 
 497   public UCode_UCodeESC_CharStream(java.io.InputStream dstream, int startline,
 498                                    int startcolumn) {
 499     this(dstream, startline, startcolumn, 4096);
 500   }
 501 
 502   public void ReInit(java.io.InputStream dstream, int startline,
 503                      int startcolumn, int buffersize) {
 504     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
 505   }
 506 
 507   public void ReInit(java.io.InputStream dstream, int startline,
 508                      int startcolumn) {
 509     ReInit(dstream, startline, startcolumn, 4096);
 510   }
 511 
 512   static private final char BOM = '\ufeff';
 513 
 514   private void skipBOM() {
 515     try {
 516       if (PeekChar() == BOM)
 517         ReadChar();
 518     }
 519     catch (EOFException e) {
 520     }
 521   }
 522 
 523   public final String GetImage() {
 524     if (bufpos >= tokenBegin)
 525       return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
 526     else
 527       return new String(buffer, tokenBegin, bufsize - tokenBegin) +
 528               new String(buffer, 0, bufpos + 1);
 529   }
 530 
 531   public final char[] GetSuffix(int len) {
 532     char[] ret = new char[len];
 533 
 534     if ((bufpos + 1) >= len)
 535       System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
 536     else {
 537       System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
 538                        len - bufpos - 1);
 539       System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
 540     }
 541 
 542     return ret;
 543   }
 544 
 545   public void Done() {
 546     nextCharBuf = null;
 547     buffer = null;
 548     bufline = null;
 549     bufcolumn = null;
 550   }
 551 
 552   /**
 553    * Method to adjust line and column numbers for the start of a token.<BR>
 554    */
 555   public void adjustBeginLineColumn(int newLine, int newCol) {
 556     int start = tokenBegin;
 557     int len;
 558 
 559     if (bufpos >= tokenBegin) {
 560       len = bufpos - tokenBegin + inBuf + 1;
 561     }
 562     else {
 563       len = bufsize - tokenBegin + bufpos + 1 + inBuf;
 564     }
 565 
 566     int i = 0, j = 0, k = 0;
 567     int nextColDiff = 0, columnDiff = 0;
 568 
 569     while (i < len &&
 570             bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) {
 571       bufline[j] = newLine;
 572       nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
 573       bufcolumn[j] = newCol + columnDiff;
 574       columnDiff = nextColDiff;
 575       i++;
 576     }
 577 
 578     if (i < len) {
 579       bufline[j] = newLine++;
 580       bufcolumn[j] = newCol + columnDiff;
 581 
 582       while (i++ < len) {
 583         if (bufline[j = start % bufsize] != bufline[++start % bufsize])
 584           bufline[j] = newLine++;
 585         else
 586           bufline[j] = newLine;
 587       }
 588     }
 589 
 590     line = bufline[j];
 591     column = bufcolumn[j];
 592   }
 593 
 594 }