1 /* ====================================================================
2
3 * The Apache Software License, Version 1.1
4
5 *
6
7 * Copyright (c) 2002 The Apache Software Foundation. All rights
8
9 * reserved.
10
11 *
12
13 * Redistribution and use in source and binary forms, with or without
14
15 * modification, are permitted provided that the following conditions
16
17 * are met:
18
19 *
20
21 * 1. Redistributions of source code must retain the above copyright
22
23 * notice, this list of conditions and the following disclaimer.
24
25 *
26
27 * 2. Redistributions in binary form must reproduce the above copyright
28
29 * notice, this list of conditions and the following disclaimer in
30
31 * the documentation and/or other materials provided with the
32
33 * distribution.
34
35 *
36
37 * 3. The end-user documentation included with the redistribution,
38
39 * if any, must include the following acknowledgment:
40
41 * "This product includes software developed by the
42
43 * Apache Software Foundation (http://www.apache.org/)."
44
45 * Alternately, this acknowledgment may appear in the software itself,
46
47 * if and wherever such third-party acknowledgments normally appear.
48
49 *
50
51 * 4. The names "Apache" and "Apache Software Foundation" and
52
53 * "Apache POI" must not be used to endorse or promote products
54
55 * derived from this software without prior written permission. For
56
57 * written permission, please contact apache@apache.org.
58
59 *
60
61 * 5. Products derived from this software may not be called "Apache",
62
63 * "Apache POI", nor may "Apache" appear in their name, without
64
65 * prior written permission of the Apache Software Foundation.
66
67 *
68
69 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
70
71 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
72
73 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74
75 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
76
77 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
78
79 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
80
81 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
82
83 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
84
85 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
86
87 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
88
89 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
90
91 * SUCH DAMAGE.
92
93 * ====================================================================
94
95 *
96
97 * This software consists of voluntary contributions made by many
98
99 * individuals on behalf of the Apache Software Foundation. For more
100
101 * information on the Apache Software Foundation, please see
102
103 * <http://www.apache.org/>.
104
105 */
106
107
108
109 package org.apache.poi.util;
110
111
112
113 import java.io.IOException;
114
115 import java.io.File;
116
117 import java.io.FileInputStream;
118
119 import java.io.InputStream;
120
121 import java.util.List;
122
123 import java.util.ArrayList;
124
125
126
127 /**
128
129 * Utilities to read hex from files.
130
131 *
132
133 * @author Marc Johnson
134
135 * @author Glen Stampoultzis (glens at apache.org)
136
137 */
138
139 public class HexRead
140
141 {
142
143 /**
144
145 * This method reads hex data from a filename and returns a byte array.
146
147 * The file may contain line comments that are preceeded with a # symbol.
148
149 *
150
151 * @param filename The filename to read
152
153 * @return The bytes read from the file.
154
155 * @throws IOException If there was a problem while reading the file.
156
157 */
158
159 public static byte[] readData( String filename )
160
161 throws IOException
162
163 {
164
165 File file = new File( filename );
166
167 FileInputStream stream = new FileInputStream( file );
168
169 try
170
171 {
172
173 return readData(stream, -1);
174
175 }
176
177 finally
178
179 {
180
181 stream.close();
182
183 }
184
185 }
186
187
188
189 /**
190
191 * Same as readData(String) except that this method allows you to specify sections within
192
193 * a file. Sections are referenced using section headers in the form:
194
195 * <pre>
196
197 * [sectioname]
198
199 * </pre>
200
201 *
202
203 * @see #readData(String)
204
205 */
206
207 public static byte[] readData(String filename, String section)
208
209 throws IOException
210
211 {
212
213 File file = new File( filename );
214
215 FileInputStream stream = new FileInputStream( file );
216
217 try
218
219 {
220
221 StringBuffer sectionText = new StringBuffer();
222
223 boolean inSection = false;
224
225 int c = stream.read();
226
227 while (c != -1)
228
229 {
230
231 switch(c)
232
233 {
234
235 case '[':
236
237 inSection = true;
238
239 break;
240
241 case '\n': case '\r':
242
243 inSection = false;
244
245 sectionText = new StringBuffer();
246
247 break;
248
249 case ']':
250
251 inSection = false;
252
253 if (sectionText.toString().equals(section))
254
255 return readData(stream, '[');
256
257 sectionText = new StringBuffer();
258
259 break;
260
261 default:
262
263 if (inSection)
264
265 sectionText.append((char)c);
266
267 }
268
269
270
271 c = stream.read();
272
273 }
274
275 }
276
277 finally
278
279 {
280
281 stream.close();
282
283 }
284
285 throw new IOException("Section '" + section + "' not found");
286
287 }
288
289
290
291 static private byte[] readData( FileInputStream stream, int eofChar ) throws IOException
292
293 {
294
295 int characterCount = 0;
296
297 byte b = (byte) 0;
298
299 List bytes = new ArrayList();
300
301 boolean done = false;
302
303
304
305 while ( !done )
306
307 {
308
309 int count = stream.read();
310
311 char baseChar = 'a';
312
313
314
315 if ( count == eofChar)
316
317 break;
318
319
320
321 switch ( count )
322
323 {
324
325
326
327 case '#':
328
329 readToEOL(stream);
330
331 break;
332
333 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
334
335 b <<= 4;
336
337 b += (byte) ( count - '0' );
338
339 characterCount++;
340
341 if ( characterCount == 2 )
342
343 {
344
345 bytes.add( new Byte( b ) );
346
347 characterCount = 0;
348
349 b = (byte) 0;
350
351 }
352
353 break;
354
355
356
357 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
358
359 baseChar = 'A';
360
361
362
363 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
364
365 b <<= 4;
366
367 b += (byte) ( count + 10 - baseChar );
368
369 characterCount++;
370
371 if ( characterCount == 2 )
372
373 {
374
375 bytes.add( new Byte( b ) );
376
377 characterCount = 0;
378
379 b = (byte) 0;
380
381 }
382
383 break;
384
385
386
387 case -1:
388
389 done = true;
390
391 break;
392
393
394
395 default :
396
397 break;
398
399 }
400
401 }
402
403 Byte[] polished = (Byte[]) bytes.toArray( new Byte[0] );
404
405 byte[] rval = new byte[polished.length];
406
407
408
409 for ( int j = 0; j < polished.length; j++ )
410
411 {
412
413 rval[j] = polished[j].byteValue();
414
415 }
416
417 return rval;
418
419 }
420
421
422
423 static private void readToEOL( InputStream stream ) throws IOException
424
425 {
426
427 int c = stream.read();
428
429 while ( c != -1 && c != '\n' && c != '\r')
430
431 {
432
433 c = stream.read();
434
435 }
436
437 }
438
439
440
441
442
443 }
444
445 HexReadreadDatafilenamefilereadDatastreamstreamreadDatafilenamefilestreamccinSectioninSectionsectionTextinSectionsectionTextsectionreadDatastreamsectionTextinSectionsectionTextccstreamstreamsectionreadDatadonestreamcounteofCharcountreadToEOLstreambbcountcharacterCountcharacterCountbytesbcharacterCountbbaseCharbbcountbaseCharcharacterCountcharacterCountbytesbcharacterCountbdonebytesbytepolishedjpolishedjrvaljpolishedjrvalreadToEOLstreamccccstream