Applying pteague's patch (re #685)
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / text / SubstitutionTextReader.java
1 /**********************************************************************
2  Copyright (c) 2000, 2002 IBM Corp. and others.
3  All rights reserved. This program and the accompanying materials
4  are made available under the terms of the Common Public License v1.0
5  which accompanies this distribution, and is available at
6  http://www.eclipse.org/legal/cpl-v10.html
7
8  Contributors:
9  IBM Corporation - Initial implementation
10  **********************************************************************/
11
12 package net.sourceforge.phpdt.internal.ui.text;
13
14 import java.io.IOException;
15 import java.io.Reader;
16
17 import net.sourceforge.phpdt.internal.corext.phpdoc.SingleCharReader;
18
19 /**
20  * Reads the text contents from a reader and computes for each character a
21  * potential substitution. The substitution may eat more characters than only
22  * the one passed into the computation routine.
23  */
24 public abstract class SubstitutionTextReader extends SingleCharReader {
25
26         protected static final String LINE_DELIM = System.getProperty(
27                         "line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
28
29         private Reader fReader;
30
31         private boolean fWasWhiteSpace;
32
33         private int fCharAfterWhiteSpace;
34
35         /**
36          * Tells whether white space characters are skipped.
37          */
38         private boolean fSkipWhiteSpace = true;
39
40         private boolean fReadFromBuffer;
41
42         private StringBuffer fBuffer;
43
44         private int fIndex;
45
46         protected SubstitutionTextReader(Reader reader) {
47                 fReader = reader;
48                 fBuffer = new StringBuffer();
49                 fIndex = 0;
50                 fReadFromBuffer = false;
51                 fCharAfterWhiteSpace = -1;
52                 fWasWhiteSpace = true;
53         }
54
55         /**
56          * Implement to compute the substitution for the given character and if
57          * necessary subsequent characters. Use <code>nextChar</code> to read
58          * subsequent characters.
59          */
60         protected abstract String computeSubstitution(int c) throws IOException;
61
62         /**
63          * Returns the internal reader.
64          */
65         protected Reader getReader() {
66                 return fReader;
67         }
68
69         /**
70          * Returns the next character.
71          */
72         protected int nextChar() throws IOException {
73                 fReadFromBuffer = (fBuffer.length() > 0);
74                 if (fReadFromBuffer) {
75                         char ch = fBuffer.charAt(fIndex++);
76                         if (fIndex >= fBuffer.length()) {
77                                 fBuffer.setLength(0);
78                                 fIndex = 0;
79                         }
80                         return ch;
81                 } else {
82                         int ch = fCharAfterWhiteSpace;
83                         if (ch == -1) {
84                                 ch = fReader.read();
85                         }
86                         if (fSkipWhiteSpace && Character.isWhitespace((char) ch)) {
87                                 do {
88                                         ch = fReader.read();
89                                 } while (Character.isWhitespace((char) ch));
90                                 if (ch != -1) {
91                                         fCharAfterWhiteSpace = ch;
92                                         return ' ';
93                                 }
94                         } else {
95                                 fCharAfterWhiteSpace = -1;
96                         }
97                         return ch;
98                 }
99         }
100
101         /**
102          * @see Reader#read()
103          */
104         public int read() throws IOException {
105                 int c;
106                 do {
107
108                         c = nextChar();
109                         while (!fReadFromBuffer) {
110                                 String s = computeSubstitution(c);
111                                 if (s == null)
112                                         break;
113                                 if (s.length() > 0)
114                                         fBuffer.insert(0, s);
115                                 c = nextChar();
116                         }
117
118                 } while (fSkipWhiteSpace && fWasWhiteSpace && (c == ' '));
119                 fWasWhiteSpace = (c == ' ' || c == '\r' || c == '\n');
120                 return c;
121         }
122
123         /**
124          * @see Reader#ready()
125          */
126         public boolean ready() throws IOException {
127                 return fReader.ready();
128         }
129
130         /**
131          * @see Reader#close()
132          */
133         public void close() throws IOException {
134                 fReader.close();
135         }
136
137         /**
138          * @see Reader#reset()
139          */
140         public void reset() throws IOException {
141                 fReader.reset();
142                 fWasWhiteSpace = true;
143                 fCharAfterWhiteSpace = -1;
144                 fBuffer.setLength(0);
145                 fIndex = 0;
146         }
147
148         protected final void setSkipWhitespace(boolean state) {
149                 fSkipWhiteSpace = state;
150         }
151
152         protected final boolean isSkippingWhitespace() {
153                 return fSkipWhiteSpace;
154         }
155 }