2 *******************************************************************************
\r
3 * Copyright (C) 2001-2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.impl.data;
\r
12 import com.ibm.icu.impl.ICUData;
\r
13 import com.ibm.icu.impl.Utility;
\r
16 * A reader for text resource data in the current package or the package
\r
17 * of a given class object. The
\r
18 * resource data is loaded through the class loader, so it will
\r
19 * typically be a file in the same directory as the *.class files, or
\r
20 * a file within a JAR file in the corresponding subdirectory. The
\r
21 * file must be a text file in one of the supported encodings; when the
\r
22 * resource is opened by constructing a <code>ResourceReader</code>
\r
23 * object the encoding is specified.
\r
27 public class ResourceReader {
\r
28 private BufferedReader reader;
\r
29 private String resourceName;
\r
30 private String encoding; // null for default encoding
\r
31 private Class<?> root;
\r
34 * The one-based line number. Has the special value -1 before the
\r
35 * object is initialized. Has the special value 0 after initialization
\r
36 * but before the first line is read.
\r
41 * Construct a reader object for the text file of the given name
\r
42 * in this package, using the given encoding.
\r
43 * @param resourceName the name of the text file located in this
\r
44 * package's ".data" subpackage.
\r
45 * @param encoding the encoding of the text file; if unsupported
\r
46 * an exception is thrown
\r
47 * @exception UnsupportedEncodingException if
\r
48 * <code>encoding</code> is not supported by the JDK.
\r
50 public ResourceReader(String resourceName, String encoding)
\r
51 throws UnsupportedEncodingException {
\r
52 this(ICUData.class, "data/" + resourceName, encoding);
\r
56 * Construct a reader object for the text file of the given name
\r
57 * in this package, using the default encoding.
\r
58 * @param resourceName the name of the text file located in this
\r
59 * package's ".data" subpackage.
\r
61 public ResourceReader(String resourceName) {
\r
62 this(ICUData.class, "data/" + resourceName);
\r
66 * Construct a reader object for the text file of the given name
\r
67 * in the given class's package, using the given encoding.
\r
68 * @param resourceName the name of the text file located in the
\r
69 * given class's package.
\r
70 * @param encoding the encoding of the text file; if unsupported
\r
71 * an exception is thrown
\r
72 * @exception UnsupportedEncodingException if
\r
73 * <code>encoding</code> is not supported by the JDK.
\r
75 public ResourceReader(Class<?> rootClass, String resourceName, String encoding)
\r
76 throws UnsupportedEncodingException {
\r
77 this.root = rootClass;
\r
78 this.resourceName = resourceName;
\r
79 this.encoding = encoding;
\r
85 * Construct a reader object for the input stream associated with
\r
86 * the given resource name.
\r
87 * @param is the input stream of the resource
\r
88 * @param resourceName the name of the resource
\r
90 public ResourceReader(InputStream is, String resourceName, String encoding) {
\r
92 this.resourceName = resourceName;
\r
93 this.encoding = encoding;
\r
97 InputStreamReader isr = (encoding == null)
\r
98 ? new InputStreamReader(is)
\r
99 : new InputStreamReader(is, encoding);
\r
101 this.reader = new BufferedReader(isr);
\r
104 catch (UnsupportedEncodingException e) {
\r
109 * Construct a reader object for the input stream associated with
\r
110 * the given resource name.
\r
111 * @param is the input stream of the resource
\r
112 * @param resourceName the name of the resource
\r
114 public ResourceReader(InputStream is, String resourceName) {
\r
115 this(is, resourceName, null);
\r
119 * Construct a reader object for the text file of the given name
\r
120 * in the given class's package, using the default encoding.
\r
121 * @param resourceName the name of the text file located in the
\r
122 * given class's package.
\r
124 public ResourceReader(Class<?> rootClass, String resourceName) {
\r
125 this.root = rootClass;
\r
126 this.resourceName = resourceName;
\r
127 this.encoding = null;
\r
131 } catch (UnsupportedEncodingException e) {}
\r
135 * Read and return the next line of the file or <code>null</code>
\r
136 * if the end of the file has been reached.
\r
138 public String readLine() throws IOException {
\r
142 String line = reader.readLine();
\r
143 if (line.charAt(0) == '\uFFEF' ||
\r
144 line.charAt(0) == '\uFEFF') {
\r
145 line = line.substring(1);
\r
150 return reader.readLine();
\r
154 * Read a line, ignoring blank lines and lines that start with
\r
156 * @param trim if true then trim leading rule white space.
\r
158 public String readLineSkippingComments(boolean trim) throws IOException {
\r
160 String line = readLine();
\r
161 if (line == null) {
\r
164 // Skip over white space
\r
165 int pos = Utility.skipWhitespace(line, 0);
\r
166 // Ignore blank lines and comment lines
\r
167 if (pos == line.length() || line.charAt(pos) == '#') {
\r
171 if (trim) line = line.substring(pos);
\r
178 * Read a line, ignoring blank lines and lines that start with
\r
179 * '#'. Do not trim leading rule white space.
\r
181 public String readLineSkippingComments() throws IOException {
\r
182 return readLineSkippingComments(false);
\r
186 * Return the one-based line number of the last line returned by
\r
187 * readLine() or readLineSkippingComments(). Should only be called
\r
188 * after a call to one of these methods; otherwise the return
\r
189 * value is undefined.
\r
191 public int getLineNumber() {
\r
196 * Return a string description of the position of the last line
\r
197 * returned by readLine() or readLineSkippingComments().
\r
199 public String describePosition() {
\r
200 return resourceName + ':' + lineNo;
\r
204 * Reset this reader so that the next call to
\r
205 * <code>readLine()</code> returns the first line of the file
\r
206 * again. This is a somewhat expensive call, however, calling
\r
207 * <code>reset()</code> after calling it the first time does
\r
208 * nothing if <code>readLine()</code> has not been called in
\r
211 public void reset() {
\r
214 } catch (UnsupportedEncodingException e) {}
\r
215 // We swallow this exception, if there is one. If the encoding is
\r
216 // invalid, the constructor will have thrown this exception already and
\r
217 // the caller shouldn't use the object afterwards.
\r
221 * Reset to the start by reconstructing the stream and readers.
\r
222 * We could also use mark() and reset() on the stream or reader,
\r
223 * but that would cause them to keep the stream data around in
\r
224 * memory. We don't want that because some of the resource files
\r
225 * are large, e.g., 400k.
\r
227 private void _reset() throws UnsupportedEncodingException {
\r
231 InputStream is = ICUData.getStream(root, resourceName);
\r
233 throw new IllegalArgumentException("Can't open " + resourceName);
\r
236 InputStreamReader isr =
\r
237 (encoding == null) ? new InputStreamReader(is) :
\r
238 new InputStreamReader(is, encoding);
\r
239 reader = new BufferedReader(isr);
\r