1 /*
2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package test.java.text.testlib;
25 
26 import java.io.BufferedReader;
27 import java.io.ByteArrayInputStream;
28 import java.io.File;
29 import java.io.FileInputStream;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.util.ArrayList;
33 import java.util.List;
34 
35 /**
36  * HexDumpReader provides utility methods to read a hex dump text file
37  * and convert to an InputStream.  The format supported by the methods
38  * can be generated by the following command.
39  *
40  * $ od -vw -t x1 foo | sed -r -e 's/^[0-9]+ ?//' -e 's/ //g' -e '/^$/d'
41  */
42 public class HexDumpReader {
getStreamFromHexDump(String fileName)43     public static InputStream getStreamFromHexDump(String fileName) {
44         return getStreamFromHexDump(new File(System.getProperty("test.src", "."),
45                                              fileName));
46     }
47 
getStreamFromHexDump(File hexFile)48     public static InputStream getStreamFromHexDump(File hexFile) {
49         ByteArrayBuilder bab = new ByteArrayBuilder();
50         int lineNo = 0;
51         try (BufferedReader reader
52                  = new BufferedReader(new InputStreamReader(new FileInputStream(hexFile),
53                                                             "us-ascii"))) {
54             String line;
55             while ((line = reader.readLine()) != null) {
56                 lineNo++;
57                 line = line.trim();
58                 // Skip blank and comment lines.
59                 if (line.length() == 0) {
60                     continue;
61                 }
62                 int x = line.indexOf('#');
63                 if (x == 0) {
64                     continue;
65                 }
66                 if (x > 0) {
67                     line = line.substring(0, x).trim();
68                 }
69                 int len = line.length();
70                 for (int i = 0; i < len; i += 2) {
71                     bab.put((byte)Integer.parseInt(line, i, i + 2, 16));
72                 }
73             }
74         } catch (Exception e) {
75             throw new RuntimeException(hexFile.getName() + ":error:" + lineNo + ": " + e, e);
76         }
77         return new ByteArrayInputStream(bab.toArray());
78     }
79 
80 
81     private static class ByteArrayBuilder {
82         private static final int BUFFER_SIZE = 4096;
83 
84         private int size;
85         private List<byte[]> bytes;
86         private byte[] current;
87         private int offset;
88 
ByteArrayBuilder()89         ByteArrayBuilder() {
90             bytes = new ArrayList<>();
91             current = new byte[BUFFER_SIZE];
92         }
93 
put(byte b)94         void put(byte b) {
95             if (offset == BUFFER_SIZE) {
96                 bytes.add(current);
97                 current = new byte[BUFFER_SIZE];
98                 offset = 0;
99             }
100             current[offset++] = b;
101             size++;
102         }
103 
toArray()104         byte[] toArray() {
105             byte[] buf = new byte[size];
106             int ptr = 0;
107             for (byte[] ba : bytes) {
108                 System.arraycopy(ba, 0, buf, ptr, ba.length);
109                 ptr += ba.length;
110             }
111             System.arraycopy(current, 0, buf, ptr, offset);
112             assert ptr + offset == size;
113             return buf;
114         }
115     }
116 
117 }
118