001: /* ====================================================================
002: * Tea - Copyright (c) 1997-2000 Walt Disney Internet Group
003: * ====================================================================
004: * The Tea Software License, Version 1.1
005: *
006: * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Walt Disney Internet Group (http://opensource.go.com/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact opensource@dig.com.
031: *
032: * 5. Products derived from this software may not be called "Tea",
033: * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
034: * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
035: * written permission of the Walt Disney Internet Group.
036: *
037: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
038: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
039: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
040: * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
041: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
042: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
043: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
044: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
045: * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
046: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
047: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
048: * ====================================================================
049: *
050: * For more information about Tea, please see http://opensource.go.com/.
051: */
052:
053: package com.go.tea.io;
054:
055: import java.io.*;
056:
057: /******************************************************************************
058: * The PushbackPositionReader is a kind of pushback reader that tracks the
059: * postion in the stream of the next character to be read.
060: * The java.io.PushbackReader allows arbitrary characters
061: * to be pushed back. Since this Reader may need to keep track of how many
062: * characters were scanned from the underlying Reader to actually produce
063: * a character, the unread operation cannot accept any arbitrary character.
064: *
065: * @author Brian S O'Neill
066: * @version
067: * <!--$$Revision:--> 11 <!-- $-->, <!--$$JustDate:--> 12/11/00 <!-- $-->
068: * @deprecated Moved to com.go.trove.io package.
069: * @see java.io.PushbackReader
070: */
071: public class PushbackPositionReader extends PositionReader {
072: /** Maximum pushback allowed. */
073: private int mMaxPushback;
074:
075: /** Most recently read characters with escapes already processed. */
076: private int[] mCharacters;
077:
078: /** The scan lengths of the most recently read characters. */
079: private int[] mPositions;
080:
081: /** The cursor marks the position in the arrays of the last character. */
082: private int mCursor;
083:
084: /** Amount of characters currently pushed back. */
085: private int mPushback;
086:
087: public PushbackPositionReader(Reader reader) {
088: this (reader, 0);
089: }
090:
091: public PushbackPositionReader(Reader reader, int pushback) {
092: super (reader);
093:
094: // Two more are required for correct operation
095: pushback += 2;
096:
097: mMaxPushback = pushback;
098: mCharacters = new int[pushback];
099: mPositions = new int[pushback];
100: mCursor = 0;
101: mPushback = 0;
102: }
103:
104: /**
105: * @return the start position of the last read character.
106: */
107: public int getStartPosition() {
108: int back = mCursor - 2;
109: if (back < 0)
110: back += mMaxPushback;
111:
112: return mPositions[back];
113: }
114:
115: public int read() throws IOException {
116: int c;
117:
118: if (mPushback > 0) {
119: mPushback--;
120:
121: mPosition = mPositions[mCursor];
122: c = mCharacters[mCursor++];
123: if (mCursor >= mMaxPushback)
124: mCursor = 0;
125:
126: return c;
127: }
128:
129: c = super .read();
130:
131: mPositions[mCursor] = mPosition;
132: mCharacters[mCursor++] = c;
133: if (mCursor >= mMaxPushback)
134: mCursor = 0;
135:
136: return c;
137: }
138:
139: public int peek() throws IOException {
140: int c = read();
141: unread();
142: return c;
143: }
144:
145: /**
146: * Unread the last several characters read.
147: *
148: * <p>Unlike PushbackReader, unread does not allow arbitrary characters to
149: * to be unread. Rather, it functions like an undo operation.
150: *
151: * @param amount Amount of characters to unread.
152: * @see java.io.PushbackReader#unread(int)
153: */
154: public void unread(int amount) throws IOException {
155: for (int i = 0; i < amount; i++) {
156: unread();
157: }
158: }
159:
160: /**
161: * Unread the last character read.
162: *
163: * <p>Unlike PushbackReader, unread does not allow arbitrary characters to
164: * to be unread. Rather, it functions like an undo operation.
165: *
166: * @see java.io.PushbackReader#unread(int)
167: */
168: public void unread() throws IOException {
169: mPushback++;
170:
171: if (mPushback > mMaxPushback - 2) {
172: throw new IOException(this .getClass().getName()
173: + ": pushback exceeded " + (mMaxPushback - 2));
174: }
175:
176: if ((--mCursor) < 0)
177: mCursor += mMaxPushback;
178:
179: if (mCursor > 0) {
180: mPosition = mPositions[mCursor - 1];
181: } else {
182: mPosition = mPositions[mMaxPushback - 1];
183: }
184:
185: unreadHook(mCharacters[mCursor]);
186: }
187:
188: /**
189: * A hook call from the unread method(s). Every unread character is
190: * passed to this method.
191: */
192: protected void unreadHook(int c) {
193: }
194: }
|