View Javadoc

1   /*
2    * Copyright (c) 2001-2003 The XDoclet team
3    * All rights reserved.
4    */
5   package xjavadoc;
6   
7   import java.io.*;
8   
9   /***
10   * A reader which strips away any spaces and stars at the beginning of javadoc.
11   * It also keeps track of line numbers, which is needed for error reporting.
12   *
13   * @author    Aslak Hellesøy
14   * @created   3. januar 2002
15   */
16  final class JavaDocReader extends FilterReader
17  {
18  	private boolean    badChar = true;
19  	private boolean    endOfLine = true;
20  //	private boolean    lastStar = true;
21  	private int        c = -1;
22  	private int        lastC = -1;
23  	private boolean    atEnd = false;
24  
25  	private int        _lineOffset = 0;
26  
27      private int nextChar = -1;
28  
29  	/***
30  	 * @param in  the underlying reader, containing javadoc
31  	 */
32  	public JavaDocReader( Reader in )
33  	{
34  		super( in );
35  		// we can skip the slash-star-star
36  		try
37  		{
38  			in.read();
39  			in.read();
40  			in.read();
41  		}
42  		catch( IOException e )
43  		{
44  			throw new RuntimeException( "We weren't given javadoc!!" );
45  		}
46  	}
47  
48  	/***
49  	 * Returns the line offset we're currently reading
50  	 *
51  	 * @return   line in the javadoc.
52  	 */
53  	public int getLineOffset()
54  	{
55  		return _lineOffset;
56  	}
57  
58  	/***
59  	 * Reads a byte of data. The method will block if no input is available.
60  	 *
61  	 * @return                 the byte read, or -1 if the end of the stream is
62  	 *      reached.
63  	 * @exception IOException  If an I/O error has occurred.
64  	 */
65  	public int read() throws IOException
66  	{
67  		if( atEnd )
68  		{
69  			return -1;
70  		}
71  		if( endOfLine )
72  		{
73  			endOfLine = false;
74  			badChar = true;
75  		}
76  
77  		do
78  		{
79              if( c == -1 ) {
80                  // will only happen 1st time
81                  c = in.read();
82              } else {
83                  c = nextChar;
84              }
85              if( c == -1 ) {
86                  return c;
87              }
88              nextChar = in.read();
89  
90  			if( c == '*' && nextChar == '/' )
91  			{
92  				atEnd = true;
93  				return -1;
94  			}
95  			// UNIX: \n  (LF)
96  			// MAC:  \r  (CR)
97  			// PC:   \r\n (CR/LF)
98  			//
99  			// We don't want to interpret \r\n as two newlines
100 			if( c == '\r' || c == '\n' || c == '\f' )
101 			{
102 				badChar = false;
103 				endOfLine = true;
104 				if( !( lastC == '\r' && c == '\n' ) )
105 				{
106 					_lineOffset++;
107 				}
108 			}
109 			else
110 			{
111 				if( !( badChar && ( c == '\t' || c == ' ' || c == '*' ) ) )
112 				{
113 					// finally found something not a star or spaceish
114 					badChar = false;
115 				}
116 			}
117 			lastC = c;
118 		}while ( badChar && c != -1 );
119 		return c;
120 	}
121 
122 	/***
123 	 * Reads into an array of bytes. Blocks until some input is available.
124 	 *
125 	 * @param b                the buffer into which the data is read
126 	 * @param off              the start offset of the data
127 	 * @param len              the maximum number of bytes read
128 	 * @return                 the actual number of bytes read, -1 is returned when
129 	 *      the end of the stream is reached.
130 	 * @exception IOException  If an I/O error has occurred.
131 	 */
132 	public int read( char[] b, int off, int len ) throws IOException
133 	{
134 		if( atEnd )
135 		{
136 			return -1;
137 		}
138 		for( int i = off; i < len; i++ )
139 		{
140 			int c = read();
141 
142 			if( c == -1 )
143 			{
144 				atEnd = true;
145 				return i - off;
146 			}
147 			b[i] = ( char ) c;
148 		}
149 		return len;
150 	}
151 
152 	/***
153 	 * Skips bytes of input.
154 	 *
155 	 * @param n                bytes to be skipped
156 	 * @return                 actual number of bytes skipped
157 	 * @exception IOException  If an I/O error has occurred.
158 	 */
159 	public long skip( long n ) throws IOException
160 	{
161 		// Can't just read n bytes from 'in' and throw them
162 		// away, because n bytes from 'in' doesn't necessarily
163 		// correspond to n bytes from 'this'.
164 		for( int i = 1; i <= n; i++ )
165 		{
166 			int c = read();
167 
168 			if( c == -1 )
169 			{
170 				return i - 1;
171 			}
172 		}
173 		return n;
174 	}
175 
176 	/***
177 	 * Returns the number of bytes that can be read without blocking.
178 	 *
179 	 * @return                 the number of available bytes
180 	 * @exception IOException  Describe the exception
181 	 */
182 	public int available() throws IOException
183 	{
184 		// We don't really know.  We can ask 'in', but some of those bytes
185 		// are probably whitespace, and it's possible that all of them are.
186 		// So we have to be conservative and return zero.
187 		return 0;
188 	}
189 }