]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_8_1_1/main/classes/core/src/com/ibm/icu/impl/data/ResourceReader.java
Added flags.
[Dictionary.git] / jars / icu4j-4_8_1_1 / main / classes / core / src / com / ibm / icu / impl / data / ResourceReader.java
1 /**
2  *******************************************************************************
3  * Copyright (C) 2001-2011, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7
8 package com.ibm.icu.impl.data;
9
10 import java.io.BufferedReader;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.io.InputStreamReader;
14 import java.io.UnsupportedEncodingException;
15
16 import com.ibm.icu.impl.ICUData;
17 import com.ibm.icu.impl.PatternProps;
18
19 /**
20  * A reader for text resource data in the current package or the package
21  * of a given class object.  The
22  * resource data is loaded through the class loader, so it will
23  * typically be a file in the same directory as the *.class files, or
24  * a file within a JAR file in the corresponding subdirectory.  The
25  * file must be a text file in one of the supported encodings; when the
26  * resource is opened by constructing a <code>ResourceReader</code>
27  * object the encoding is specified.
28  *
29  * @author Alan Liu
30  */
31 public class ResourceReader {
32     private BufferedReader reader;
33     private String resourceName;
34     private String encoding; // null for default encoding
35     private Class<?> root;
36     
37     /**
38      * The one-based line number. Has the special value -1 before the
39      * object is initialized. Has the special value 0 after initialization
40      * but before the first line is read.
41      */
42     private int lineNo;
43
44     /**
45      * Construct a reader object for the text file of the given name
46      * in this package, using the given encoding.
47      * @param resourceName the name of the text file located in this
48      * package's ".data" subpackage.
49      * @param encoding the encoding of the text file; if unsupported
50      * an exception is thrown
51      * @exception UnsupportedEncodingException if
52      * <code>encoding</code> is not supported by the JDK.
53      */
54     public ResourceReader(String resourceName, String encoding)
55         throws UnsupportedEncodingException {
56         this(ICUData.class, "data/" + resourceName, encoding);
57     }
58
59     /**
60      * Construct a reader object for the text file of the given name
61      * in this package, using the default encoding.
62      * @param resourceName the name of the text file located in this
63      * package's ".data" subpackage.
64      */
65     public ResourceReader(String resourceName) {
66         this(ICUData.class, "data/" + resourceName);
67     }
68
69     /**
70      * Construct a reader object for the text file of the given name
71      * in the given class's package, using the given encoding.
72      * @param resourceName the name of the text file located in the
73      * given class's package.
74      * @param encoding the encoding of the text file; if unsupported
75      * an exception is thrown
76      * @exception UnsupportedEncodingException if
77      * <code>encoding</code> is not supported by the JDK.
78      */
79     public ResourceReader(Class<?> rootClass, String resourceName, String encoding)
80         throws UnsupportedEncodingException {
81         this.root = rootClass;
82         this.resourceName = resourceName;
83         this.encoding = encoding;
84         lineNo = -1;
85         _reset();
86     }
87
88          /**
89           * Construct a reader object for the input stream associated with
90           * the given resource name.
91           * @param is the input stream of the resource
92           * @param resourceName the name of the resource
93           */
94           public ResourceReader(InputStream is, String resourceName, String encoding) {
95                    this.root = null;
96          this.resourceName = resourceName;
97          this.encoding = encoding;
98
99          this.lineNo = -1;
100          try {
101              InputStreamReader isr = (encoding == null) 
102                  ? new InputStreamReader(is)
103                  : new InputStreamReader(is, encoding);
104
105              this.reader = new BufferedReader(isr);
106              this.lineNo= 0;
107          }
108          catch (UnsupportedEncodingException e) {
109          }
110      }
111
112           /**
113            * Construct a reader object for the input stream associated with
114            * the given resource name.
115            * @param is the input stream of the resource
116            * @param resourceName the name of the resource
117            */
118           public ResourceReader(InputStream is, String resourceName) {
119               this(is, resourceName, null);
120           }
121
122     /**
123      * Construct a reader object for the text file of the given name
124      * in the given class's package, using the default encoding.
125      * @param resourceName the name of the text file located in the
126      * given class's package.
127      */
128     public ResourceReader(Class<?> rootClass, String resourceName) {
129         this.root = rootClass;
130         this.resourceName = resourceName;
131         this.encoding = null;
132         lineNo = -1;
133         try {
134             _reset();
135         } catch (UnsupportedEncodingException e) {}
136     }
137
138     /**
139      * Read and return the next line of the file or <code>null</code>
140      * if the end of the file has been reached.
141      */
142     public String readLine() throws IOException {
143         if (lineNo == 0) {
144             // Remove BOMs
145             ++lineNo;
146             String line = reader.readLine();
147             if (line.charAt(0) == '\uFFEF' ||
148                 line.charAt(0) == '\uFEFF') {
149                 line = line.substring(1);
150             }
151             return line;
152         }
153         ++lineNo;
154         return reader.readLine();
155     }
156
157     /**
158      * Read a line, ignoring blank lines and lines that start with
159      * '#'.
160      * @param trim if true then trim leading Pattern_White_Space.
161      */
162     public String readLineSkippingComments(boolean trim) throws IOException {
163         for (;;) {
164             String line = readLine();
165             if (line == null) {
166                 return line;
167             }
168             // Skip over white space
169             int pos = PatternProps.skipWhiteSpace(line, 0);
170             // Ignore blank lines and comment lines
171             if (pos == line.length() || line.charAt(pos) == '#') {
172                 continue;
173             }
174             // Process line
175             if (trim) line = line.substring(pos);
176             return line;
177         }
178     }
179
180
181     /**
182      * Read a line, ignoring blank lines and lines that start with
183      * '#'. Do not trim leading Pattern_White_Space.
184      */
185     public String readLineSkippingComments() throws IOException {
186         return readLineSkippingComments(false);
187     }
188
189     /**
190      * Return the one-based line number of the last line returned by
191      * readLine() or readLineSkippingComments(). Should only be called
192      * after a call to one of these methods; otherwise the return
193      * value is undefined.
194      */
195     public int getLineNumber() {
196         return lineNo;
197     }
198     
199     /**
200      * Return a string description of the position of the last line
201      * returned by readLine() or readLineSkippingComments().
202      */
203     public String describePosition() {
204         return resourceName + ':' + lineNo;
205     }
206     
207     /**
208      * Reset this reader so that the next call to
209      * <code>readLine()</code> returns the first line of the file
210      * again.  This is a somewhat expensive call, however, calling
211      * <code>reset()</code> after calling it the first time does
212      * nothing if <code>readLine()</code> has not been called in
213      * between.
214      */
215     public void reset() {
216         try {
217             _reset();
218         } catch (UnsupportedEncodingException e) {}
219         // We swallow this exception, if there is one.  If the encoding is
220         // invalid, the constructor will have thrown this exception already and
221         // the caller shouldn't use the object afterwards.
222     }
223
224     /**
225      * Reset to the start by reconstructing the stream and readers.
226      * We could also use mark() and reset() on the stream or reader,
227      * but that would cause them to keep the stream data around in
228      * memory.  We don't want that because some of the resource files
229      * are large, e.g., 400k.
230      */
231     private void _reset() throws UnsupportedEncodingException {
232         if (lineNo == 0) {
233             return;
234         }
235         InputStream is = ICUData.getStream(root, resourceName);
236         if (is == null) {
237             throw new IllegalArgumentException("Can't open " + resourceName);
238         }
239         
240         InputStreamReader isr =
241             (encoding == null) ? new InputStreamReader(is) :
242                                  new InputStreamReader(is, encoding);
243         reader = new BufferedReader(isr);
244         lineNo = 0;
245     }
246 }