001: package org.apache.velocity.runtime.parser;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: /**
023: * NOTE : This class was originally an ASCII_CharStream autogenerated
024: * by Javacc. It was then modified via changing class name with appropriate
025: * fixes for CTORS, and mods to readChar().
026: *
027: * This is safe because we *always* use Reader with this class, and never a
028: * InputStream. This guarantees that we have a correct stream of 16-bit
029: * chars - all encoding transformations have been done elsewhere, so we
030: * believe that there is no risk in doing this. Time will tell :)
031: */
032:
033: /**
034: * An implementation of interface CharStream, where the stream is assumed to
035: * contain only ASCII characters (without unicode processing).
036: */
037:
038: public final class VelocityCharStream implements CharStream {
039: /** */
040: public static final boolean staticFlag = false;
041: int bufsize;
042: int available;
043: int tokenBegin;
044: /** */
045: public int bufpos = -1;
046: private int bufline[];
047: private int bufcolumn[];
048:
049: private int column = 0;
050: private int line = 1;
051:
052: private boolean prevCharIsCR = false;
053: private boolean prevCharIsLF = false;
054:
055: private java.io.Reader inputStream;
056:
057: private char[] buffer;
058: private int maxNextCharInd = 0;
059: private int inBuf = 0;
060:
061: private final void ExpandBuff(boolean wrapAround) {
062: char[] newbuffer = new char[bufsize + 2048];
063: int newbufline[] = new int[bufsize + 2048];
064: int newbufcolumn[] = new int[bufsize + 2048];
065:
066: try {
067: if (wrapAround) {
068: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
069: bufsize - tokenBegin);
070: System.arraycopy(buffer, 0, newbuffer, bufsize
071: - tokenBegin, bufpos);
072: buffer = newbuffer;
073:
074: System.arraycopy(bufline, tokenBegin, newbufline, 0,
075: bufsize - tokenBegin);
076: System.arraycopy(bufline, 0, newbufline, bufsize
077: - tokenBegin, bufpos);
078: bufline = newbufline;
079:
080: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
081: 0, bufsize - tokenBegin);
082: System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize
083: - tokenBegin, bufpos);
084: bufcolumn = newbufcolumn;
085:
086: maxNextCharInd = (bufpos += (bufsize - tokenBegin));
087: } else {
088: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
089: bufsize - tokenBegin);
090: buffer = newbuffer;
091:
092: System.arraycopy(bufline, tokenBegin, newbufline, 0,
093: bufsize - tokenBegin);
094: bufline = newbufline;
095:
096: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
097: 0, bufsize - tokenBegin);
098: bufcolumn = newbufcolumn;
099:
100: maxNextCharInd = (bufpos -= tokenBegin);
101: }
102: } catch (Throwable t) {
103: throw new Error(t.getMessage());
104: }
105:
106: bufsize += 2048;
107: available = bufsize;
108: tokenBegin = 0;
109: }
110:
111: private final void FillBuff() throws java.io.IOException {
112: if (maxNextCharInd == available) {
113: if (available == bufsize) {
114: if (tokenBegin > 2048) {
115: bufpos = maxNextCharInd = 0;
116: available = tokenBegin;
117: } else if (tokenBegin < 0)
118: bufpos = maxNextCharInd = 0;
119: else
120: ExpandBuff(false);
121: } else if (available > tokenBegin)
122: available = bufsize;
123: else if ((tokenBegin - available) < 2048)
124: ExpandBuff(true);
125: else
126: available = tokenBegin;
127: }
128:
129: int i;
130: try {
131: if ((i = inputStream.read(buffer, maxNextCharInd, available
132: - maxNextCharInd)) == -1) {
133: inputStream.close();
134: throw new java.io.IOException();
135: } else
136: maxNextCharInd += i;
137: return;
138: } catch (java.io.IOException e) {
139: --bufpos;
140: backup(0);
141: if (tokenBegin == -1)
142: tokenBegin = bufpos;
143: throw e;
144: }
145: }
146:
147: /**
148: * @see org.apache.velocity.runtime.parser.CharStream#BeginToken()
149: */
150: public final char BeginToken() throws java.io.IOException {
151: tokenBegin = -1;
152: char c = readChar();
153: tokenBegin = bufpos;
154:
155: return c;
156: }
157:
158: private final void UpdateLineColumn(char c) {
159: column++;
160:
161: if (prevCharIsLF) {
162: prevCharIsLF = false;
163: line += (column = 1);
164: } else if (prevCharIsCR) {
165: prevCharIsCR = false;
166: if (c == '\n') {
167: prevCharIsLF = true;
168: } else
169: line += (column = 1);
170: }
171:
172: switch (c) {
173: case '\r':
174: prevCharIsCR = true;
175: break;
176: case '\n':
177: prevCharIsLF = true;
178: break;
179: case '\t':
180: column--;
181: column += (8 - (column & 07));
182: break;
183: default:
184: break;
185: }
186:
187: bufline[bufpos] = line;
188: bufcolumn[bufpos] = column;
189: }
190:
191: /**
192: * @see org.apache.velocity.runtime.parser.CharStream#readChar()
193: */
194: public final char readChar() throws java.io.IOException {
195: if (inBuf > 0) {
196: --inBuf;
197:
198: /*
199: * was : return (char)((char)0xff & buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]);
200: */
201: return buffer[(bufpos == bufsize - 1) ? (bufpos = 0)
202: : ++bufpos];
203: }
204:
205: if (++bufpos >= maxNextCharInd)
206: FillBuff();
207:
208: /*
209: * was : char c = (char)((char)0xff & buffer[bufpos]);
210: */
211: char c = buffer[bufpos];
212:
213: UpdateLineColumn(c);
214: return (c);
215: }
216:
217: /**
218: * @see org.apache.velocity.runtime.parser.CharStream#getColumn()
219: * @deprecated
220: */
221: public final int getColumn() {
222: return bufcolumn[bufpos];
223: }
224:
225: /**
226: * @see org.apache.velocity.runtime.parser.CharStream#getLine()
227: * @deprecated
228: */
229: public final int getLine() {
230: return bufline[bufpos];
231: }
232:
233: /**
234: * @see org.apache.velocity.runtime.parser.CharStream#getEndColumn()
235: */
236: public final int getEndColumn() {
237: return bufcolumn[bufpos];
238: }
239:
240: /**
241: * @see org.apache.velocity.runtime.parser.CharStream#getEndLine()
242: */
243: public final int getEndLine() {
244: return bufline[bufpos];
245: }
246:
247: /**
248: * @see org.apache.velocity.runtime.parser.CharStream#getBeginColumn()
249: */
250: public final int getBeginColumn() {
251: return bufcolumn[tokenBegin];
252: }
253:
254: /**
255: * @see org.apache.velocity.runtime.parser.CharStream#getBeginLine()
256: */
257: public final int getBeginLine() {
258: return bufline[tokenBegin];
259: }
260:
261: /**
262: * @see org.apache.velocity.runtime.parser.CharStream#backup(int)
263: */
264: public final void backup(int amount) {
265:
266: inBuf += amount;
267: if ((bufpos -= amount) < 0)
268: bufpos += bufsize;
269: }
270:
271: /**
272: * @param dstream
273: * @param startline
274: * @param startcolumn
275: * @param buffersize
276: */
277: public VelocityCharStream(java.io.Reader dstream, int startline,
278: int startcolumn, int buffersize) {
279: inputStream = dstream;
280: line = startline;
281: column = startcolumn - 1;
282:
283: available = bufsize = buffersize;
284: buffer = new char[buffersize];
285: bufline = new int[buffersize];
286: bufcolumn = new int[buffersize];
287: }
288:
289: /**
290: * @param dstream
291: * @param startline
292: * @param startcolumn
293: */
294: public VelocityCharStream(java.io.Reader dstream, int startline,
295: int startcolumn) {
296: this (dstream, startline, startcolumn, 4096);
297: }
298:
299: /**
300: * @param dstream
301: * @param startline
302: * @param startcolumn
303: * @param buffersize
304: */
305: public void ReInit(java.io.Reader dstream, int startline,
306: int startcolumn, int buffersize) {
307: inputStream = dstream;
308: line = startline;
309: column = startcolumn - 1;
310:
311: if (buffer == null || buffersize != buffer.length) {
312: available = bufsize = buffersize;
313: buffer = new char[buffersize];
314: bufline = new int[buffersize];
315: bufcolumn = new int[buffersize];
316: }
317: prevCharIsLF = prevCharIsCR = false;
318: tokenBegin = inBuf = maxNextCharInd = 0;
319: bufpos = -1;
320: }
321:
322: /**
323: * @param dstream
324: * @param startline
325: * @param startcolumn
326: */
327: public void ReInit(java.io.Reader dstream, int startline,
328: int startcolumn) {
329: ReInit(dstream, startline, startcolumn, 4096);
330: }
331:
332: /**
333: * @param dstream
334: * @param startline
335: * @param startcolumn
336: * @param buffersize
337: */
338: public VelocityCharStream(java.io.InputStream dstream,
339: int startline, int startcolumn, int buffersize) {
340: this (new java.io.InputStreamReader(dstream), startline,
341: startcolumn, 4096);
342: }
343:
344: /**
345: * @param dstream
346: * @param startline
347: * @param startcolumn
348: */
349: public VelocityCharStream(java.io.InputStream dstream,
350: int startline, int startcolumn) {
351: this (dstream, startline, startcolumn, 4096);
352: }
353:
354: /**
355: * @param dstream
356: * @param startline
357: * @param startcolumn
358: * @param buffersize
359: */
360: public void ReInit(java.io.InputStream dstream, int startline,
361: int startcolumn, int buffersize) {
362: ReInit(new java.io.InputStreamReader(dstream), startline,
363: startcolumn, 4096);
364: }
365:
366: /**
367: * @param dstream
368: * @param startline
369: * @param startcolumn
370: */
371: public void ReInit(java.io.InputStream dstream, int startline,
372: int startcolumn) {
373: ReInit(dstream, startline, startcolumn, 4096);
374: }
375:
376: /**
377: * @see org.apache.velocity.runtime.parser.CharStream#GetImage()
378: */
379: public final String GetImage() {
380: if (bufpos >= tokenBegin)
381: return new String(buffer, tokenBegin, bufpos - tokenBegin
382: + 1);
383: else
384: return new String(buffer, tokenBegin, bufsize - tokenBegin)
385: + new String(buffer, 0, bufpos + 1);
386: }
387:
388: /**
389: * @see org.apache.velocity.runtime.parser.CharStream#GetSuffix(int)
390: */
391: public final char[] GetSuffix(int len) {
392: char[] ret = new char[len];
393:
394: if ((bufpos + 1) >= len)
395: System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
396: else {
397: System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret,
398: 0, len - bufpos - 1);
399: System.arraycopy(buffer, 0, ret, len - bufpos - 1,
400: bufpos + 1);
401: }
402:
403: return ret;
404: }
405:
406: /**
407: * @see org.apache.velocity.runtime.parser.CharStream#Done()
408: */
409: public void Done() {
410: buffer = null;
411: bufline = null;
412: bufcolumn = null;
413: }
414:
415: /**
416: * Method to adjust line and column numbers for the start of a token.<BR>
417: * @param newLine
418: * @param newCol
419: */
420: public void adjustBeginLineColumn(int newLine, int newCol) {
421: int start = tokenBegin;
422: int len;
423:
424: if (bufpos >= tokenBegin) {
425: len = bufpos - tokenBegin + inBuf + 1;
426: } else {
427: len = bufsize - tokenBegin + bufpos + 1 + inBuf;
428: }
429:
430: int i = 0, j = 0, k = 0;
431: int nextColDiff = 0, columnDiff = 0;
432:
433: while (i < len
434: && bufline[j = start % bufsize] == bufline[k = ++start
435: % bufsize]) {
436: bufline[j] = newLine;
437: nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
438: bufcolumn[j] = newCol + columnDiff;
439: columnDiff = nextColDiff;
440: i++;
441: }
442:
443: if (i < len) {
444: bufline[j] = newLine++;
445: bufcolumn[j] = newCol + columnDiff;
446:
447: while (i++ < len) {
448: if (bufline[j = start % bufsize] != bufline[++start
449: % bufsize])
450: bufline[j] = newLine++;
451: else
452: bufline[j] = newLine;
453: }
454: }
455:
456: line = bufline[j];
457: column = bufcolumn[j];
458: }
459:
460: }
|