1/*
2 * Copyright (c) 2005, 2013, 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-2012
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. */
49package com.sun.xml.internal.rngom.parse.compact;
50
51import com.sun.xml.internal.rngom.util.Utf16;
52import com.sun.xml.internal.rngom.ast.builder.BuildException;
53
54import java.io.IOException;
55
56/**
57 * An implementation of interface CharStream, where the stream is assumed to
58 * contain 16-bit unicode characters.
59 */
60public final class UCode_UCodeESC_CharStream {
61
62    public static final boolean staticFlag = false;
63
64    static final int hexval(char c) {
65        switch (c) {
66            case '0':
67                return 0;
68            case '1':
69                return 1;
70            case '2':
71                return 2;
72            case '3':
73                return 3;
74            case '4':
75                return 4;
76            case '5':
77                return 5;
78            case '6':
79                return 6;
80            case '7':
81                return 7;
82            case '8':
83                return 8;
84            case '9':
85                return 9;
86
87            case 'a':
88            case 'A':
89                return 10;
90            case 'b':
91            case 'B':
92                return 11;
93            case 'c':
94            case 'C':
95                return 12;
96            case 'd':
97            case 'D':
98                return 13;
99            case 'e':
100            case 'E':
101                return 14;
102            case 'f':
103            case 'F':
104                return 15;
105        }
106        return -1;
107    }
108    public int bufpos = -1;
109    int bufsize;
110    int available;
111    int tokenBegin;
112    private int bufline[];
113    private int bufcolumn[];
114    private int column = 0;
115    private int line = 1;
116    private java.io.Reader inputStream;
117    private boolean closed = false;
118    private boolean prevCharIsLF = false;
119    private char[] nextCharBuf;
120    private char[] buffer;
121    private int maxNextCharInd = 0;
122    private int nextCharInd = -1;
123    private int inBuf = 0;
124
125    private final void ExpandBuff(boolean wrapAround) {
126        char[] newbuffer = new char[bufsize + 2048];
127        int newbufline[] = new int[bufsize + 2048];
128        int newbufcolumn[] = new int[bufsize + 2048];
129
130        if (wrapAround) {
131            System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
132            System.arraycopy(buffer, 0, newbuffer,
133                    bufsize - tokenBegin, bufpos);
134            buffer = newbuffer;
135
136            System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
137            System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
138            bufline = newbufline;
139
140            System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
141            System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
142            bufcolumn = newbufcolumn;
143
144            bufpos += (bufsize - tokenBegin);
145        } else {
146            System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
147            buffer = newbuffer;
148
149            System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
150            bufline = newbufline;
151
152            System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
153            bufcolumn = newbufcolumn;
154
155            bufpos -= tokenBegin;
156        }
157
158        available = (bufsize += 2048);
159        tokenBegin = 0;
160    }
161
162    private final void FillBuff() throws EOFException {
163        int i;
164        if (maxNextCharInd == 4096) {
165            maxNextCharInd = nextCharInd = 0;
166        }
167
168        if (closed) {
169            throw new EOFException();
170        }
171        try {
172            if ((i = inputStream.read(nextCharBuf, maxNextCharInd, 4096 - maxNextCharInd)) == -1) {
173                closed = true;
174                inputStream.close();
175                throw new EOFException();
176            } else {
177                maxNextCharInd += i;
178            }
179        } catch (IOException e) {
180            throw new BuildException(e);
181        }
182    }
183
184    private final char ReadChar() throws EOFException {
185        if (++nextCharInd >= maxNextCharInd) {
186            FillBuff();
187        }
188
189        return nextCharBuf[nextCharInd];
190    }
191
192    private final char PeekChar() throws EOFException {
193        char c = ReadChar();
194        --nextCharInd;
195        return c;
196    }
197
198    public final char BeginToken() throws EOFException {
199        if (inBuf > 0) {
200            --inBuf;
201            return buffer[tokenBegin = (bufpos == bufsize - 1) ? (bufpos = 0)
202                    : ++bufpos];
203        }
204
205        tokenBegin = 0;
206        bufpos = -1;
207
208        return readChar();
209    }
210
211    private final void AdjustBuffSize() {
212        if (available == bufsize) {
213            if (tokenBegin > 2048) {
214                bufpos = 0;
215                available = tokenBegin;
216            } else {
217                ExpandBuff(false);
218            }
219        } else if (available > tokenBegin) {
220            available = bufsize;
221        } else if ((tokenBegin - available) < 2048) {
222            ExpandBuff(true);
223        } else {
224            available = tokenBegin;
225        }
226    }
227
228    private final void UpdateLineColumn(char c) {
229        column++;
230
231        if (prevCharIsLF) {
232            prevCharIsLF = false;
233            line += (column = 1);
234        }
235
236        switch (c) {
237            case NEWLINE_MARKER:
238                prevCharIsLF = true;
239                break;
240            case '\t':
241                column--;
242                column += (8 - (column & 07));
243                break;
244            default:
245                break;
246        }
247
248        bufline[bufpos] = line;
249        bufcolumn[bufpos] = column;
250    }
251    private static final char NEWLINE_MARKER = '\u0000';
252
253    public final char readChar() throws EOFException {
254        if (inBuf > 0) {
255            --inBuf;
256            return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
257        }
258
259        char c;
260        try {
261            c = ReadChar();
262            switch (c) {
263                case '\r':
264                    c = NEWLINE_MARKER;
265                    try {
266                        if (PeekChar() == '\n') {
267                            ReadChar();
268                        }
269                    } catch (EOFException e) {
270                    }
271                    break;
272                case '\n':
273                    c = NEWLINE_MARKER;
274                    break;
275                case '\t':
276                    break;
277                default:
278                    if (c >= 0x20) {
279                        if (Utf16.isSurrogate(c)) {
280                            if (Utf16.isSurrogate2(c)) {
281                                throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 1);
282                            }
283                            if (++bufpos == available) {
284                                AdjustBuffSize();
285                            }
286                            buffer[bufpos] = c;
287                            // UpdateLineColumn(c);
288                            try {
289                                c = ReadChar();
290                            } catch (EOFException e) {
291                                throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 1);
292                            }
293                            if (!Utf16.isSurrogate2(c)) {
294                                throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 2);
295                            }
296                        }
297                        break;
298                    }
299                // fall through
300                case '\uFFFE':
301                case '\uFFFF':
302                    throw new EscapeSyntaxException("illegal_char_code", line, column + 1);
303            }
304        } catch (EOFException e) {
305            if (bufpos == -1) {
306                if (++bufpos == available) {
307                    AdjustBuffSize();
308                }
309                bufline[bufpos] = line;
310                bufcolumn[bufpos] = column;
311            }
312            throw e;
313        }
314        if (++bufpos == available) {
315            AdjustBuffSize();
316        }
317        buffer[bufpos] = c;
318        UpdateLineColumn(c);
319        try {
320            if (c != '\\' || PeekChar() != 'x') {
321                return c;
322            }
323        } catch (EOFException e) {
324            return c;
325        }
326
327        int xCnt = 1;
328        for (;;) {
329            ReadChar();
330            if (++bufpos == available) {
331                AdjustBuffSize();
332            }
333            buffer[bufpos] = 'x';
334            UpdateLineColumn('x');
335            try {
336                c = PeekChar();
337            } catch (EOFException e) {
338                backup(xCnt);
339                return '\\';
340            }
341            if (c == '{') {
342                ReadChar();
343                column++;
344                // backup past the 'x's
345                bufpos -= xCnt;
346                if (bufpos < 0) {
347                    bufpos += bufsize;
348                }
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            }
363            while ((c = ReadChar()) != '}') {
364                column++;
365                int n = hexval(c);
366                if (n < 0) {
367                    throw new EscapeSyntaxException("illegal_hex_digit", line, column);
368                }
369                scalarValue <<= 4;
370                scalarValue |= n;
371                if (scalarValue >= 0x110000) {
372                    throw new EscapeSyntaxException("char_code_too_big", line, column);
373                }
374            }
375            column++; // for the '}'
376            if (scalarValue <= 0xFFFF) {
377                c = (char) scalarValue;
378                switch (c) {
379                    case '\n':
380                    case '\r':
381                    case '\t':
382                        break;
383                    default:
384                        if (c >= 0x20 && !Utf16.isSurrogate(c)) {
385                            break;
386                        }
387                    // fall through
388                    case '\uFFFE':
389                    case '\uFFFF':
390                        throw new EscapeSyntaxException("illegal_char_code_ref", line, column);
391                }
392                buffer[bufpos] = c;
393                return c;
394            }
395            c = Utf16.surrogate1(scalarValue);
396            buffer[bufpos] = c;
397            int bufpos1 = bufpos;
398            if (++bufpos == bufsize) {
399                bufpos = 0;
400            }
401            buffer[bufpos] = Utf16.surrogate2(scalarValue);
402            bufline[bufpos] = bufline[bufpos1];
403            bufcolumn[bufpos] = bufcolumn[bufpos1];
404            backup(1);
405            return c;
406        } catch (EOFException e) {
407            throw new EscapeSyntaxException("incomplete_escape", line, column);
408        }
409    }
410
411    /**
412     * @deprecated @see #getEndColumn
413     */
414    public final int getColumn() {
415        return bufcolumn[bufpos];
416    }
417
418    /**
419     * @deprecated @see #getEndLine
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
449    public UCode_UCodeESC_CharStream(java.io.Reader dstream,
450            int startline, int startcolumn, int buffersize) {
451        inputStream = dstream;
452        line = startline;
453        column = startcolumn - 1;
454
455        available = bufsize = buffersize;
456        buffer = new char[buffersize];
457        bufline = new int[buffersize];
458        bufcolumn = new int[buffersize];
459        nextCharBuf = new char[4096];
460        skipBOM();
461    }
462
463    public UCode_UCodeESC_CharStream(java.io.Reader dstream,
464            int startline, int startcolumn) {
465        this(dstream, startline, startcolumn, 4096);
466    }
467
468    public void ReInit(java.io.Reader dstream,
469            int startline, int startcolumn, int buffersize) {
470        inputStream = dstream;
471        closed = false;
472        line = startline;
473        column = startcolumn - 1;
474
475        if (buffer == null || buffersize != buffer.length) {
476            available = bufsize = buffersize;
477            buffer = new char[buffersize];
478            bufline = new int[buffersize];
479            bufcolumn = new int[buffersize];
480            nextCharBuf = new char[4096];
481        }
482        prevCharIsLF = false;
483        tokenBegin = inBuf = maxNextCharInd = 0;
484        nextCharInd = bufpos = -1;
485        skipBOM();
486    }
487
488    public void ReInit(java.io.Reader dstream,
489            int startline, int startcolumn) {
490        ReInit(dstream, startline, startcolumn, 4096);
491    }
492
493    public UCode_UCodeESC_CharStream(java.io.InputStream dstream, int startline,
494            int startcolumn, int buffersize) {
495        this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
496    }
497
498    public UCode_UCodeESC_CharStream(java.io.InputStream dstream, int startline,
499            int startcolumn) {
500        this(dstream, startline, startcolumn, 4096);
501    }
502
503    public void ReInit(java.io.InputStream dstream, int startline,
504            int startcolumn, int buffersize) {
505        ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
506    }
507
508    public void ReInit(java.io.InputStream dstream, int startline,
509            int startcolumn) {
510        ReInit(dstream, startline, startcolumn, 4096);
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
532    public final char[] GetSuffix(int len) {
533        char[] ret = new char[len];
534
535        if ((bufpos + 1) >= len) {
536            System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
537        } else {
538            System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
539                    len - bufpos - 1);
540            System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
541        }
542
543        return ret;
544    }
545
546    public void Done() {
547        nextCharBuf = null;
548        buffer = null;
549        bufline = null;
550        bufcolumn = null;
551    }
552
553    /**
554     * Method to adjust line and column numbers for the start of a token.<BR>
555     */
556    public void adjustBeginLineColumn(int newLine, int newCol) {
557        int start = tokenBegin;
558        int len;
559
560        if (bufpos >= tokenBegin) {
561            len = bufpos - tokenBegin + inBuf + 1;
562        } else {
563            len = bufsize - tokenBegin + bufpos + 1 + inBuf;
564        }
565
566        int i = 0, j = 0, k = 0;
567        int nextColDiff, 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
591        line = bufline[j];
592        column = bufcolumn[j];
593    }
594}
595