1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the GNU General Public License v3+, or later.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.plugin
.util
;
12 import java
.io
.BufferedReader
;
13 import java
.io
.IOException
;
14 import java
.io
.InputStream
;
15 import java
.io
.InputStreamReader
;
16 import java
.io
.Reader
;
17 import java
.io
.UnsupportedEncodingException
;
20 * This is used to read comments from a source code file.
24 public class CommentReader
27 /** The source reader. */
28 protected final BufferedReader source
;
30 /** Extra character queue. */
31 private final StringBuilder _queue
=
34 /** Line remainder. */
35 private final StringBuilder _remainder
=
38 /** Are we in multi-line comment? */
39 private boolean _inMultiLine
;
42 * Initializes the comment reader.
44 * @param __in The input source.
45 * @throws NullPointerException On null arguments.
48 public CommentReader(InputStream __in
)
49 throws NullPointerException
53 this.source
= new BufferedReader(
54 new InputStreamReader(__in
, "utf-8"));
56 catch (UnsupportedEncodingException e
)
58 throw new RuntimeException("UTF-8 is not supported?", e
);
78 public int read(char[] __c
, int __o
, int __l
)
79 throws IndexOutOfBoundsException
, IOException
81 if (__o
< 0 || __l
< 0 || (__o
+ __l
) < 0 || (__o
+ __l
) > __c
.length
)
82 throw new IndexOutOfBoundsException();
84 BufferedReader source
= this.source
;
85 StringBuilder queue
= this._queue
;
86 StringBuilder remainder
= this._remainder
;
87 boolean inMultiLine
= this._inMultiLine
;
89 // Constantly try to fill the output buffer
91 while (putCount
< __l
)
93 // If there are characters in the queue, drain from it
94 if (queue
.length() > 0)
96 // Extract the first character
97 char ch
= queue
.charAt(0);
98 queue
.deleteCharAt(0);
100 // Place it in the output
108 // Read the next source line
109 String ln
= (remainder
.length() > 0 ? remainder
.toString() :
112 return (putCount
> 0 ? putCount
: -1);
114 // Always trim lines to remove extra clutter
117 // Always clear the remainder, since we might push it again later
118 remainder
.setLength(0);
120 // The length of the line
121 int len
= ln
.length();
123 // Are we in a multi-line comment still?
126 // This is likely a JavaDoc continuation so drop that
127 if (ln
.startsWith("* "))
128 ln
= ln
.substring(2);
130 // Length may have changed so recalculate it
134 int eml
= ln
.indexOf("*/");
136 // There are no ending slashes, use entire line
140 // Otherwise our multi-line is going to end and we need to
141 // process the remainder of the line
144 // Add starting chunk to the queue for output
145 queue
.append(ln
, 0, eml
);
147 // Store the remainder of the line since we may still have
148 // another comment on it
149 remainder
.append(ln
, eml
+ 2, len
);
151 // Stop being in multi-line mode
159 // Get potential start positions of lines
160 int sng
= ln
.indexOf("//");
161 int mul
= ln
.indexOf("/*");
163 // Detect double star for JavaDoc
166 int jdoc
= ln
.indexOf("/**", mul
);
171 // No comment on this line
172 if (sng
< 0 && mul
< 0)
175 // Single line comment
176 if (sng
>= 0 && (mul
< 0 || sng
< mul
))
178 // Add fragment to the queue
179 queue
.append(ln
, sng
+ 2, len
);
182 // Multi-line comment
185 // Does the multi-line end on the same line?
186 int eml
= ln
.indexOf("*/", mul
+ 2);
189 // Add the comment area to the queue
190 queue
.append(ln
, mul
+ 2, eml
);
192 // Add the rest of the line to the remainder for
194 remainder
.append(ln
, eml
+ 2, len
);
197 // Does not, so keep reading
200 // Now in a multi-line
203 // Add our comment into the queue
204 queue
.append(ln
, mul
+ 2, len
);
210 // Store comment type for later runs
211 this._inMultiLine
= inMultiLine
;
213 // Return the number out placed characters
218 * Reads the entire file to a string.
220 * @param __sb The input buffer to write to.
221 * @return {@code __sb}.
222 * @throws IOException On read errors.
223 * @throws NullPointerException On null arguments.
226 public final StringBuilder
readAll(StringBuilder __sb
)
227 throws IOException
, NullPointerException
230 throw new NullPointerException();
232 char[] buf
= new char[512];
235 int rc
= this.read(buf
, 0, 512);
240 __sb
.append(buf
, 0, rc
);
247 * The type of comment being parsed.
251 private enum CommentType
256 /** Single line comment. */
259 /** Block comment. */