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  ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????HexRead??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????readData???????????????????????????????filename???????????????????????????????????????????????????????file????????????????????readData?????????????????????????????stream?????????????stream????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????readData???????????????????????????????filename???????????????????????????????????????????????????????file?????????????????????stream????????????????????c????????????????????????c?????????????????????????inSection?????????????????????????inSection?????????????????????????sectionText?????????????????????????inSection?????????????????????????????sectionText???????????????????????????????????????????????????????????section????????????????????????????????????readData?????????????????????????????????????????????stream?????????????????????????sectionText?????????????????????????????inSection?????????????????????????????sectionText??????????????????????????????????????????????????????c?????????????????c?????????????????????stream?????????????stream?????????????????????????????????????????????section???????????????????????????readData??????????????????done?????????????????????????stream??????????????????count???????????????????????????eofChar??????????????????????count?????????????????????readToEOL???????????????????????????????stream?????????????????????b?????????????????????b???????????????????????????????????count?????????????????????characterCount??????????????????????????characterCount?????????????????????????bytes??????????????????????????????????????????????b?????????????????????????characterCount?????????????????????????b?????????????????????baseChar?????????????????????b?????????????????????b???????????????????????????????????count????????????????????????????????????????????????baseChar?????????????????????characterCount??????????????????????????characterCount?????????????????????????bytes??????????????????????????????????????????????b?????????????????????????characterCount?????????????????????????b?????????????????????done????????????????????????????????????bytes???????????????????????????byte????????????????????????????????polished??????????????????????????j??????????????????????????????polished???????????????????????????????????????????????j?????????????rval??????????????????j???????????????????????polished????????????????????????????????j????????????????rval?????????????????????????readToEOL?????????????????stream?????????????????c????????????????????????????c?????????????????????????????????????????c?????????????c?????????????????stream