]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/impl/data/ResourceReader.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / impl / data / ResourceReader.java
1 /**\r
2  *******************************************************************************\r
3  * Copyright (C) 2001-2009, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 package com.ibm.icu.impl.data;\r
9 \r
10 import java.io.*;\r
11 \r
12 import com.ibm.icu.impl.ICUData;\r
13 import com.ibm.icu.impl.Utility;\r
14 \r
15 /**\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
24  *\r
25  * @author Alan Liu\r
26  */\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
32     \r
33     /**\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
37      */\r
38     private int lineNo;\r
39 \r
40     /**\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
49      */\r
50     public ResourceReader(String resourceName, String encoding)\r
51         throws UnsupportedEncodingException {\r
52         this(ICUData.class, "data/" + resourceName, encoding);\r
53     }\r
54 \r
55     /**\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
60      */\r
61     public ResourceReader(String resourceName) {\r
62         this(ICUData.class, "data/" + resourceName);\r
63     }\r
64 \r
65     /**\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
74      */\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
80         lineNo = -1;\r
81         _reset();\r
82     }\r
83 \r
84          /**\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
89           */\r
90           public ResourceReader(InputStream is, String resourceName, String encoding) {\r
91                    this.root = null;\r
92          this.resourceName = resourceName;\r
93          this.encoding = encoding;\r
94 \r
95          this.lineNo = -1;\r
96          try {\r
97              InputStreamReader isr = (encoding == null) \r
98                  ? new InputStreamReader(is)\r
99                  : new InputStreamReader(is, encoding);\r
100 \r
101              this.reader = new BufferedReader(isr);\r
102              this.lineNo= 0;\r
103          }\r
104          catch (UnsupportedEncodingException e) {\r
105          }\r
106      }\r
107 \r
108           /**\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
113            */\r
114           public ResourceReader(InputStream is, String resourceName) {\r
115               this(is, resourceName, null);\r
116           }\r
117 \r
118     /**\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
123      */\r
124     public ResourceReader(Class<?> rootClass, String resourceName) {\r
125         this.root = rootClass;\r
126         this.resourceName = resourceName;\r
127         this.encoding = null;\r
128         lineNo = -1;\r
129         try {\r
130             _reset();\r
131         } catch (UnsupportedEncodingException e) {}\r
132     }\r
133 \r
134     /**\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
137      */\r
138     public String readLine() throws IOException {\r
139         if (lineNo == 0) {\r
140             // Remove BOMs\r
141             ++lineNo;\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
146             }\r
147             return line;\r
148         }\r
149         ++lineNo;\r
150         return reader.readLine();\r
151     }\r
152 \r
153     /**\r
154      * Read a line, ignoring blank lines and lines that start with\r
155      * '#'.\r
156      * @param trim if true then trim leading rule white space.\r
157      */\r
158     public String readLineSkippingComments(boolean trim) throws IOException {\r
159         for (;;) {\r
160             String line = readLine();\r
161             if (line == null) {\r
162                 return line;\r
163             }\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
168                 continue;\r
169             }\r
170             // Process line\r
171             if (trim) line = line.substring(pos);\r
172             return line;\r
173         }\r
174     }\r
175 \r
176 \r
177     /**\r
178      * Read a line, ignoring blank lines and lines that start with\r
179      * '#'. Do not trim leading rule white space.\r
180      */\r
181     public String readLineSkippingComments() throws IOException {\r
182         return readLineSkippingComments(false);\r
183     }\r
184 \r
185     /**\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
190      */\r
191     public int getLineNumber() {\r
192         return lineNo;\r
193     }\r
194     \r
195     /**\r
196      * Return a string description of the position of the last line\r
197      * returned by readLine() or readLineSkippingComments().\r
198      */\r
199     public String describePosition() {\r
200         return resourceName + ':' + lineNo;\r
201     }\r
202     \r
203     /**\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
209      * between.\r
210      */\r
211     public void reset() {\r
212         try {\r
213             _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
218     }\r
219 \r
220     /**\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
226      */\r
227     private void _reset() throws UnsupportedEncodingException {\r
228         if (lineNo == 0) {\r
229             return;\r
230         }\r
231         InputStream is = ICUData.getStream(root, resourceName);\r
232         if (is == null) {\r
233             throw new IllegalArgumentException("Can't open " + resourceName);\r
234         }\r
235         \r
236         InputStreamReader isr =\r
237             (encoding == null) ? new InputStreamReader(is) :\r
238                                  new InputStreamReader(is, encoding);\r
239         reader = new BufferedReader(isr);\r
240         lineNo = 0;\r
241     }\r
242 }\r