View Javadoc
1   /* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 5.0 */
2   /* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=false */
3   /*
4    * #%L
5    * JsonParser.jj - mongodb-async-driver - Allanbank Consulting, Inc.
6    * %%
7    * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  package com.allanbank.mongodb.bson.json;
23  
24  /**
25   * An implementation of interface CharStream, where the stream is assumed to
26   * contain only ASCII characters (with java-like unicode escape processing).
27   */
28  
29  class JavaCharStream
30  {
31    /** Whether parser is static. */
32    public static final boolean staticFlag = false;
33  
34    static final int hexval(char c) throws java.io.IOException {
35      switch(c)
36      {
37         case '0' :
38            return 0;
39         case '1' :
40            return 1;
41         case '2' :
42            return 2;
43         case '3' :
44            return 3;
45         case '4' :
46            return 4;
47         case '5' :
48            return 5;
49         case '6' :
50            return 6;
51         case '7' :
52            return 7;
53         case '8' :
54            return 8;
55         case '9' :
56            return 9;
57  
58         case 'a' :
59         case 'A' :
60            return 10;
61         case 'b' :
62         case 'B' :
63            return 11;
64         case 'c' :
65         case 'C' :
66            return 12;
67         case 'd' :
68         case 'D' :
69            return 13;
70         case 'e' :
71         case 'E' :
72            return 14;
73         case 'f' :
74         case 'F' :
75            return 15;
76      }
77  
78      throw new java.io.IOException(); // Should never come here
79    }
80  
81  /** Position in buffer. */
82    public int bufpos = -1;
83    int bufsize;
84    int available;
85    int tokenBegin;
86    protected int bufline[];
87    protected int bufcolumn[];
88  
89    protected int column = 0;
90    protected int line = 1;
91  
92    protected boolean prevCharIsCR = false;
93    protected boolean prevCharIsLF = false;
94  
95    protected java.io.Reader inputStream;
96  
97    protected char[] nextCharBuf;
98    protected char[] buffer;
99    protected int maxNextCharInd = 0;
100   protected int nextCharInd = -1;
101   protected int inBuf = 0;
102   protected int tabSize = 8;
103 
104   protected void setTabSize(int i) { tabSize = i; }
105   protected int getTabSize(int i) { return tabSize; }
106 
107   protected void ExpandBuff(boolean wrapAround)
108   {
109     char[] newbuffer = new char[bufsize + 2048];
110     int newbufline[] = new int[bufsize + 2048];
111     int newbufcolumn[] = new int[bufsize + 2048];
112 
113     try
114     {
115       if (wrapAround)
116       {
117         System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
118         System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
119         buffer = newbuffer;
120 
121         System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
122         System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
123         bufline = newbufline;
124 
125         System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
126         System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
127         bufcolumn = newbufcolumn;
128 
129         bufpos += (bufsize - tokenBegin);
130     }
131     else
132     {
133         System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
134         buffer = newbuffer;
135 
136         System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
137         bufline = newbufline;
138 
139         System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
140         bufcolumn = newbufcolumn;
141 
142         bufpos -= tokenBegin;
143       }
144     }
145     catch (Throwable t)
146     {
147       throw new Error(t.getMessage());
148     }
149 
150     available = (bufsize += 2048);
151     tokenBegin = 0;
152   }
153 
154   protected void FillBuff() throws java.io.IOException
155   {
156     int i;
157     if (maxNextCharInd == 4096)
158       maxNextCharInd = nextCharInd = 0;
159 
160     try {
161       if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
162                                           4096 - maxNextCharInd)) == -1)
163       {
164         inputStream.close();
165         throw new java.io.IOException();
166       }
167       else
168          maxNextCharInd += i;
169       return;
170     }
171     catch(java.io.IOException e) {
172       if (bufpos != 0)
173       {
174         --bufpos;
175         backup(0);
176       }
177       else
178       {
179         bufline[bufpos] = line;
180         bufcolumn[bufpos] = column;
181       }
182       throw e;
183     }
184   }
185 
186   protected char ReadByte() throws java.io.IOException
187   {
188     if (++nextCharInd >= maxNextCharInd)
189       FillBuff();
190 
191     return nextCharBuf[nextCharInd];
192   }
193 
194 /** @return starting character for token. */
195   public char BeginToken() throws java.io.IOException
196   {
197     if (inBuf > 0)
198     {
199       --inBuf;
200 
201       if (++bufpos == bufsize)
202         bufpos = 0;
203 
204       tokenBegin = bufpos;
205       return buffer[bufpos];
206     }
207 
208     tokenBegin = 0;
209     bufpos = -1;
210 
211     return readChar();
212   }
213 
214   protected void AdjustBuffSize()
215   {
216     if (available == bufsize)
217     {
218       if (tokenBegin > 2048)
219       {
220         bufpos = 0;
221         available = tokenBegin;
222       }
223       else
224         ExpandBuff(false);
225     }
226     else if (available > tokenBegin)
227       available = bufsize;
228     else if ((tokenBegin - available) < 2048)
229       ExpandBuff(true);
230     else
231       available = tokenBegin;
232   }
233 
234   protected void UpdateLineColumn(char c)
235   {
236     column++;
237 
238     if (prevCharIsLF)
239     {
240       prevCharIsLF = false;
241       line += (column = 1);
242     }
243     else if (prevCharIsCR)
244     {
245       prevCharIsCR = false;
246       if (c == '\n')
247       {
248         prevCharIsLF = true;
249       }
250       else
251         line += (column = 1);
252     }
253 
254     switch (c)
255     {
256       case '\r' :
257         prevCharIsCR = true;
258         break;
259       case '\n' :
260         prevCharIsLF = true;
261         break;
262       case '\t' :
263         column--;
264         column += (tabSize - (column % tabSize));
265         break;
266       default :
267         break;
268     }
269 
270     bufline[bufpos] = line;
271     bufcolumn[bufpos] = column;
272   }
273 
274 /** Read a character. */
275   public char readChar() throws java.io.IOException
276   {
277     if (inBuf > 0)
278     {
279       --inBuf;
280 
281       if (++bufpos == bufsize)
282         bufpos = 0;
283 
284       return buffer[bufpos];
285     }
286 
287     char c;
288 
289     if (++bufpos == available)
290       AdjustBuffSize();
291 
292     if ((buffer[bufpos] = c = ReadByte()) == '\\')
293     {
294       UpdateLineColumn(c);
295 
296       int backSlashCnt = 1;
297 
298       for (;;) // Read all the backslashes
299       {
300         if (++bufpos == available)
301           AdjustBuffSize();
302 
303         try
304         {
305           if ((buffer[bufpos] = c = ReadByte()) != '\\')
306           {
307             UpdateLineColumn(c);
308             // found a non-backslash char.
309             if ((c == 'u') && ((backSlashCnt & 1) == 1))
310             {
311               if (--bufpos < 0)
312                 bufpos = bufsize - 1;
313 
314               break;
315             }
316 
317             backup(backSlashCnt);
318             return '\\';
319           }
320         }
321         catch(java.io.IOException e)
322         {
323 	  // We are returning one backslash so we should only backup (count-1)
324           if (backSlashCnt > 1)
325             backup(backSlashCnt-1);
326 
327           return '\\';
328         }
329 
330         UpdateLineColumn(c);
331         backSlashCnt++;
332       }
333 
334       // Here, we have seen an odd number of backslash's followed by a 'u'
335       try
336       {
337         while ((c = ReadByte()) == 'u')
338           ++column;
339 
340         buffer[bufpos] = c = (char)(hexval(c) << 12 |
341                                     hexval(ReadByte()) << 8 |
342                                     hexval(ReadByte()) << 4 |
343                                     hexval(ReadByte()));
344 
345         column += 4;
346       }
347       catch(java.io.IOException e)
348       {
349         throw new Error("Invalid escape character at line " + line +
350                                          " column " + column + ".");
351       }
352 
353       if (backSlashCnt == 1)
354         return c;
355       else
356       {
357         backup(backSlashCnt - 1);
358         return '\\';
359       }
360     }
361     else
362     {
363       UpdateLineColumn(c);
364       return c;
365     }
366   }
367 
368   @Deprecated
369   /**
370    * @deprecated
371    * @see #getEndColumn
372    */
373   public int getColumn() {
374     return bufcolumn[bufpos];
375   }
376 
377   @Deprecated
378   /**
379    * @deprecated
380    * @see #getEndLine
381    */
382   public int getLine() {
383     return bufline[bufpos];
384   }
385 
386 /** Get end column. */
387   public int getEndColumn() {
388     return bufcolumn[bufpos];
389   }
390 
391 /** Get end line. */
392   public int getEndLine() {
393     return bufline[bufpos];
394   }
395 
396 /** @return column of token start */
397   public int getBeginColumn() {
398     return bufcolumn[tokenBegin];
399   }
400 
401 /** @return line number of token start */
402   public int getBeginLine() {
403     return bufline[tokenBegin];
404   }
405 
406 /** Retreat. */
407   public void backup(int amount) {
408 
409     inBuf += amount;
410     if ((bufpos -= amount) < 0)
411       bufpos += bufsize;
412   }
413 
414 /** Constructor. */
415   public JavaCharStream(java.io.Reader dstream,
416                  int startline, int startcolumn, int buffersize)
417   {
418     inputStream = dstream;
419     line = startline;
420     column = startcolumn - 1;
421 
422     available = bufsize = buffersize;
423     buffer = new char[buffersize];
424     bufline = new int[buffersize];
425     bufcolumn = new int[buffersize];
426     nextCharBuf = new char[4096];
427   }
428 
429 /** Constructor. */
430   public JavaCharStream(java.io.Reader dstream,
431                                         int startline, int startcolumn)
432   {
433     this(dstream, startline, startcolumn, 4096);
434   }
435 
436 /** Constructor. */
437   public JavaCharStream(java.io.Reader dstream)
438   {
439     this(dstream, 1, 1, 4096);
440   }
441 /** Reinitialise. */
442   public void ReInit(java.io.Reader dstream,
443                  int startline, int startcolumn, int buffersize)
444   {
445     inputStream = dstream;
446     line = startline;
447     column = startcolumn - 1;
448 
449     if (buffer == null || buffersize != buffer.length)
450     {
451       available = bufsize = buffersize;
452       buffer = new char[buffersize];
453       bufline = new int[buffersize];
454       bufcolumn = new int[buffersize];
455       nextCharBuf = new char[4096];
456     }
457     prevCharIsLF = prevCharIsCR = false;
458     tokenBegin = inBuf = maxNextCharInd = 0;
459     nextCharInd = bufpos = -1;
460   }
461 
462 /** Reinitialise. */
463   public void ReInit(java.io.Reader dstream,
464                                         int startline, int startcolumn)
465   {
466     ReInit(dstream, startline, startcolumn, 4096);
467   }
468 
469 /** Reinitialise. */
470   public void ReInit(java.io.Reader dstream)
471   {
472     ReInit(dstream, 1, 1, 4096);
473   }
474 /** Constructor. */
475   public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
476   int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
477   {
478     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
479   }
480 
481 /** Constructor. */
482   public JavaCharStream(java.io.InputStream dstream, int startline,
483   int startcolumn, int buffersize)
484   {
485     this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
486   }
487 
488 /** Constructor. */
489   public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
490                         int startcolumn) throws java.io.UnsupportedEncodingException
491   {
492     this(dstream, encoding, startline, startcolumn, 4096);
493   }
494 
495 /** Constructor. */
496   public JavaCharStream(java.io.InputStream dstream, int startline,
497                         int startcolumn)
498   {
499     this(dstream, startline, startcolumn, 4096);
500   }
501 
502 /** Constructor. */
503   public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
504   {
505     this(dstream, encoding, 1, 1, 4096);
506   }
507 
508 /** Constructor. */
509   public JavaCharStream(java.io.InputStream dstream)
510   {
511     this(dstream, 1, 1, 4096);
512   }
513 
514 /** Reinitialise. */
515   public void ReInit(java.io.InputStream dstream, String encoding, int startline,
516   int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
517   {
518     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
519   }
520 
521 /** Reinitialise. */
522   public void ReInit(java.io.InputStream dstream, int startline,
523   int startcolumn, int buffersize)
524   {
525     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
526   }
527 /** Reinitialise. */
528   public void ReInit(java.io.InputStream dstream, String encoding, int startline,
529                      int startcolumn) throws java.io.UnsupportedEncodingException
530   {
531     ReInit(dstream, encoding, startline, startcolumn, 4096);
532   }
533 /** Reinitialise. */
534   public void ReInit(java.io.InputStream dstream, int startline,
535                      int startcolumn)
536   {
537     ReInit(dstream, startline, startcolumn, 4096);
538   }
539 /** Reinitialise. */
540   public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
541   {
542     ReInit(dstream, encoding, 1, 1, 4096);
543   }
544 
545 /** Reinitialise. */
546   public void ReInit(java.io.InputStream dstream)
547   {
548     ReInit(dstream, 1, 1, 4096);
549   }
550 
551   /** @return token image as String */
552   public String GetImage()
553   {
554     if (bufpos >= tokenBegin)
555       return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
556     else
557       return new String(buffer, tokenBegin, bufsize - tokenBegin) +
558                               new String(buffer, 0, bufpos + 1);
559   }
560 
561   /** @return suffix */
562   public char[] GetSuffix(int len)
563   {
564     char[] ret = new char[len];
565 
566     if ((bufpos + 1) >= len)
567       System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
568     else
569     {
570       System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
571                                                         len - bufpos - 1);
572       System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
573     }
574 
575     return ret;
576   }
577 
578   /** Set buffers back to null when finished. */
579   public void Done()
580   {
581     nextCharBuf = null;
582     buffer = null;
583     bufline = null;
584     bufcolumn = null;
585   }
586 
587   /**
588    * Method to adjust line and column numbers for the start of a token.
589    */
590   public void adjustBeginLineColumn(int newLine, int newCol)
591   {
592     int start = tokenBegin;
593     int len;
594 
595     if (bufpos >= tokenBegin)
596     {
597       len = bufpos - tokenBegin + inBuf + 1;
598     }
599     else
600     {
601       len = bufsize - tokenBegin + bufpos + 1 + inBuf;
602     }
603 
604     int i = 0, j = 0, k = 0;
605     int nextColDiff = 0, columnDiff = 0;
606 
607     while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
608     {
609       bufline[j] = newLine;
610       nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
611       bufcolumn[j] = newCol + columnDiff;
612       columnDiff = nextColDiff;
613       i++;
614     }
615 
616     if (i < len)
617     {
618       bufline[j] = newLine++;
619       bufcolumn[j] = newCol + columnDiff;
620 
621       while (i++ < len)
622       {
623         if (bufline[j = start % bufsize] != bufline[++start % bufsize])
624           bufline[j] = newLine++;
625         else
626           bufline[j] = newLine;
627       }
628     }
629 
630     line = bufline[j];
631     column = bufcolumn[j];
632   }
633 
634 }
635 /* JavaCC - OriginalChecksum=700e2c84db732807a120906eeb4bed3a (do not edit this line) */