1/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 6.1 */
2/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
3/*
4 *
5 * This file is part of Java 1.8 parser and Abstract Syntax Tree.
6 *
7 * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
14 */
15package com.github.javaparser;
16
17/**
18 * An implementation of interface CharStream, where the stream is assumed to
19 * contain only ASCII characters (with java-like unicode escape processing).
20 */
21
22
23public
24class JavaCharStream
25{
26  /** Whether parser is static. */
27  public static final boolean staticFlag = false;
28
29
30  static final int hexval(char c) throws java.io.IOException {
31    switch(c)
32    {
33       case '0' :
34          return 0;
35       case '1' :
36          return 1;
37       case '2' :
38          return 2;
39       case '3' :
40          return 3;
41       case '4' :
42          return 4;
43       case '5' :
44          return 5;
45       case '6' :
46          return 6;
47       case '7' :
48          return 7;
49       case '8' :
50          return 8;
51       case '9' :
52          return 9;
53
54       case 'a' :
55       case 'A' :
56          return 10;
57       case 'b' :
58       case 'B' :
59          return 11;
60       case 'c' :
61       case 'C' :
62          return 12;
63       case 'd' :
64       case 'D' :
65          return 13;
66       case 'e' :
67       case 'E' :
68          return 14;
69       case 'f' :
70       case 'F' :
71          return 15;
72    }
73
74    throw new java.io.IOException(); // Should never come here
75  }
76
77/** Position in buffer. */
78  public int bufpos = -1;
79  int bufsize;
80  int available;
81  int tokenBegin;
82  protected int bufline[];
83  protected int bufcolumn[];
84
85  protected int column = 0;
86  protected int line = 1;
87
88  protected boolean prevCharIsCR = false;
89  protected boolean prevCharIsLF = false;
90
91  protected Provider inputStream;
92
93  protected char[] nextCharBuf;
94  protected char[] buffer;
95  protected int maxNextCharInd = 0;
96  protected int nextCharInd = -1;
97  protected int inBuf = 0;
98  protected int tabSize = 1;
99  protected boolean trackLineColumn = true;
100
101  public void setTabSize(int i) { tabSize = i; }
102  public int getTabSize(int i) { return tabSize; }
103
104  protected void ExpandBuff(boolean wrapAround)
105  {
106    char[] newbuffer = new char[bufsize + 2048];
107    int newbufline[] = new int[bufsize + 2048];
108    int newbufcolumn[] = new int[bufsize + 2048];
109
110    try
111    {
112      if (wrapAround)
113      {
114        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
115        System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
116        buffer = newbuffer;
117
118        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
119        System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
120        bufline = newbufline;
121
122        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
123        System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
124        bufcolumn = newbufcolumn;
125
126        bufpos += (bufsize - tokenBegin);
127    }
128    else
129    {
130        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
131        buffer = newbuffer;
132
133        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
134        bufline = newbufline;
135
136        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
137        bufcolumn = newbufcolumn;
138
139        bufpos -= tokenBegin;
140      }
141    }
142    catch (Exception t)
143    {
144      throw new RuntimeException(t.getMessage());
145    }
146
147    available = (bufsize += 2048);
148    tokenBegin = 0;
149  }
150
151  protected void FillBuff() throws java.io.IOException
152  {
153    int i;
154    if (maxNextCharInd == 4096)
155      maxNextCharInd = nextCharInd = 0;
156
157    try {
158      if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
159                                          4096 - maxNextCharInd)) == -1)
160      {
161        inputStream.close();
162        throw new java.io.IOException();
163      }
164      else
165         maxNextCharInd += i;
166      return;
167    }
168    catch(java.io.IOException e) {
169      if (bufpos != 0)
170      {
171        --bufpos;
172        backup(0);
173      }
174      else
175      {
176        bufline[bufpos] = line;
177        bufcolumn[bufpos] = column;
178      }
179      throw e;
180    }
181  }
182
183  protected char ReadByte() throws java.io.IOException
184  {
185    if (++nextCharInd >= maxNextCharInd)
186      FillBuff();
187
188    return nextCharBuf[nextCharInd];
189  }
190
191/** @return starting character for token. */
192  public char BeginToken() throws java.io.IOException
193  {
194    if (inBuf > 0)
195    {
196      --inBuf;
197
198      if (++bufpos == bufsize)
199        bufpos = 0;
200
201      tokenBegin = bufpos;
202      return buffer[bufpos];
203    }
204
205    tokenBegin = 0;
206    bufpos = -1;
207
208    return readChar();
209  }
210
211  protected void AdjustBuffSize()
212  {
213    if (available == bufsize)
214    {
215      if (tokenBegin > 2048)
216      {
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  protected void UpdateLineColumn(char c)
232  {
233    column++;
234
235    if (prevCharIsLF)
236    {
237      prevCharIsLF = false;
238      line += (column = 1);
239    }
240    else if (prevCharIsCR)
241    {
242      prevCharIsCR = false;
243      if (c == '\n')
244      {
245        prevCharIsLF = true;
246      }
247      else
248        line += (column = 1);
249    }
250
251    switch (c)
252    {
253      case '\r' :
254        prevCharIsCR = true;
255        break;
256      case '\n' :
257        prevCharIsLF = true;
258        break;
259      case '\t' :
260        column--;
261        column += (tabSize - (column % tabSize));
262        break;
263      default :
264        break;
265    }
266
267    bufline[bufpos] = line;
268    bufcolumn[bufpos] = column;
269  }
270
271/** Read a character. */
272  public char readChar() throws java.io.IOException
273  {
274    if (inBuf > 0)
275    {
276      --inBuf;
277
278      if (++bufpos == bufsize)
279        bufpos = 0;
280
281      return buffer[bufpos];
282    }
283
284    char c;
285
286    if (++bufpos == available)
287      AdjustBuffSize();
288
289    if ((buffer[bufpos] = c = ReadByte()) == '\\')
290    {
291      UpdateLineColumn(c);
292
293      int backSlashCnt = 1;
294
295      for (;;) // Read all the backslashes
296      {
297        if (++bufpos == available)
298          AdjustBuffSize();
299
300        try
301        {
302          if ((buffer[bufpos] = c = ReadByte()) != '\\')
303          {
304            UpdateLineColumn(c);
305            // found a non-backslash char.
306            if ((c == 'u') && ((backSlashCnt & 1) == 1))
307            {
308              if (--bufpos < 0)
309                bufpos = bufsize - 1;
310
311              break;
312            }
313
314            backup(backSlashCnt);
315            return '\\';
316          }
317        }
318        catch(java.io.IOException e)
319        {
320	  // We are returning one backslash so we should only backup (count-1)
321          if (backSlashCnt > 1)
322            backup(backSlashCnt-1);
323
324          return '\\';
325        }
326
327        UpdateLineColumn(c);
328        backSlashCnt++;
329      }
330
331      // Here, we have seen an odd number of backslash's followed by a 'u'
332      try
333      {
334        while ((c = ReadByte()) == 'u')
335          ++column;
336
337        buffer[bufpos] = c = (char)(hexval(c) << 12 |
338                                    hexval(ReadByte()) << 8 |
339                                    hexval(ReadByte()) << 4 |
340                                    hexval(ReadByte()));
341
342        column += 4;
343      }
344      catch(java.io.IOException e)
345      {
346        throw new RuntimeException("Invalid escape character at line " + line +
347                                         " column " + column + ".");
348      }
349
350      if (backSlashCnt == 1)
351        return c;
352      else
353      {
354        backup(backSlashCnt - 1);
355        return '\\';
356      }
357    }
358    else
359    {
360      UpdateLineColumn(c);
361      return c;
362    }
363  }
364
365  @Deprecated
366  /**
367   * @deprecated
368   * @see #getEndColumn
369   */
370  public int getColumn() {
371    return bufcolumn[bufpos];
372  }
373
374  @Deprecated
375  /**
376   * @deprecated
377   * @see #getEndLine
378   */
379  public int getLine() {
380    return bufline[bufpos];
381  }
382
383/** Get end column. */
384  public int getEndColumn() {
385    return bufcolumn[bufpos];
386  }
387
388/** Get end line. */
389  public int getEndLine() {
390    return bufline[bufpos];
391  }
392
393/** @return column of token start */
394  public int getBeginColumn() {
395    return bufcolumn[tokenBegin];
396  }
397
398/** @return line number of token start */
399  public int getBeginLine() {
400    return bufline[tokenBegin];
401  }
402
403/** Retreat. */
404  public void backup(int amount) {
405
406    inBuf += amount;
407    if ((bufpos -= amount) < 0)
408      bufpos += bufsize;
409  }
410
411/** Constructor. */
412  public JavaCharStream(Provider dstream,
413                 int startline, int startcolumn, int buffersize)
414  {
415    inputStream = dstream;
416    line = startline;
417    column = startcolumn - 1;
418
419    available = bufsize = buffersize;
420    buffer = new char[buffersize];
421    bufline = new int[buffersize];
422    bufcolumn = new int[buffersize];
423    nextCharBuf = new char[4096];
424  }
425
426/** Constructor. */
427  public JavaCharStream(Provider dstream,
428                                        int startline, int startcolumn)
429  {
430    this(dstream, startline, startcolumn, 4096);
431  }
432
433/** Constructor. */
434  public JavaCharStream(Provider dstream)
435  {
436    this(dstream, 1, 1, 4096);
437  }
438/** Reinitialise. */
439  public void ReInit(Provider dstream,
440                 int startline, int startcolumn, int buffersize)
441  {
442    inputStream = dstream;
443    line = startline;
444    column = startcolumn - 1;
445
446    if (buffer == null || buffersize != buffer.length)
447    {
448      available = bufsize = buffersize;
449      buffer = new char[buffersize];
450      bufline = new int[buffersize];
451      bufcolumn = new int[buffersize];
452      nextCharBuf = new char[4096];
453    }
454    prevCharIsLF = prevCharIsCR = false;
455    tokenBegin = inBuf = maxNextCharInd = 0;
456    nextCharInd = bufpos = -1;
457  }
458
459/** Reinitialise. */
460  public void ReInit(Provider dstream,
461                                        int startline, int startcolumn)
462  {
463    ReInit(dstream, startline, startcolumn, 4096);
464  }
465
466/** Reinitialise. */
467  public void ReInit(Provider dstream)
468  {
469    ReInit(dstream, 1, 1, 4096);
470  }
471
472
473
474  /** @return token image as String */
475  public String GetImage()
476  {
477    if (bufpos >= tokenBegin)
478      return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
479    else
480      return new String(buffer, tokenBegin, bufsize - tokenBegin) +
481                              new String(buffer, 0, bufpos + 1);
482  }
483
484  /** @return suffix */
485  public char[] GetSuffix(int len)
486  {
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    {
493      System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
494                                                        len - bufpos - 1);
495      System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
496    }
497
498    return ret;
499  }
500
501  /** Set buffers back to null when finished. */
502  public void Done()
503  {
504    nextCharBuf = null;
505    buffer = null;
506    bufline = null;
507    bufcolumn = null;
508  }
509
510  /**
511   * Method to adjust line and column numbers for the start of a token.
512   */
513  public void adjustBeginLineColumn(int newLine, int newCol)
514  {
515    int start = tokenBegin;
516    int len;
517
518    if (bufpos >= tokenBegin)
519    {
520      len = bufpos - tokenBegin + inBuf + 1;
521    }
522    else
523    {
524      len = bufsize - tokenBegin + bufpos + 1 + inBuf;
525    }
526
527    int i = 0, j = 0, k = 0;
528    int nextColDiff = 0, columnDiff = 0;
529
530    while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
531    {
532      bufline[j] = newLine;
533      nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
534      bufcolumn[j] = newCol + columnDiff;
535      columnDiff = nextColDiff;
536      i++;
537    }
538
539    if (i < len)
540    {
541      bufline[j] = newLine++;
542      bufcolumn[j] = newCol + columnDiff;
543
544      while (i++ < len)
545      {
546        if (bufline[j = start % bufsize] != bufline[++start % bufsize])
547          bufline[j] = newLine++;
548        else
549          bufline[j] = newLine;
550      }
551    }
552
553    line = bufline[j];
554    column = bufcolumn[j];
555  }
556  boolean getTrackLineColumn() { return trackLineColumn; }
557  void setTrackLineColumn(boolean tlc) { trackLineColumn = tlc; }
558
559}
560/* JavaCC - OriginalChecksum=9ab0136fd4b1e2a45a251f41181a5bd8 (do not edit this line) */
561