69 } 70 71 // public methods -------------------------------------------------------- 72 73 /** 74 * Loads an ICU binary data file and returns it as a ByteBuffer. 75 * The buffer contents is normally read-only, but its position etc. can be modified. 76 * 77 * @param itemPath Relative ICU data item path, for example "root.res" or "coll/ucadata.icu". 78 * @return The data as a read-only ByteBuffer. 79 */ 80 public static ByteBuffer getRequiredData(String itemPath) { 81 final Class<ICUBinary> root = ICUBinary.class; 82 83 try (InputStream is = AccessController.doPrivileged(new PrivilegedAction<InputStream>() { 84 public InputStream run() { 85 return root.getResourceAsStream(itemPath); 86 } 87 })) { 88 89 BufferedInputStream b=new BufferedInputStream(is, 4096 /* data buffer size */); 90 DataInputStream inputStream = new DataInputStream(b); 91 byte[] bb = new byte[130000]; 92 int n = inputStream.read(bb); 93 ByteBuffer bytes = ByteBuffer.wrap(bb, 0, n); 94 return bytes; 95 } 96 catch (IOException e) { 97 throw new UncheckedIOException(e); 98 } 99 } 100 101 /** 102 * Same as readHeader(), but returns a VersionInfo rather than a compact int. 103 */ 104 public static VersionInfo readHeaderAndDataVersion(ByteBuffer bytes, 105 int dataFormat, 106 Authenticate authenticate) 107 throws IOException { 108 return getVersionInfoFromCompactInt(readHeader(bytes, dataFormat, authenticate)); 109 } 110 111 private static final byte BIG_ENDIAN_ = 1; 112 public static final byte[] readHeader(InputStream inputStream, 113 byte dataFormatIDExpected[], 114 Authenticate authenticate) | 69 } 70 71 // public methods -------------------------------------------------------- 72 73 /** 74 * Loads an ICU binary data file and returns it as a ByteBuffer. 75 * The buffer contents is normally read-only, but its position etc. can be modified. 76 * 77 * @param itemPath Relative ICU data item path, for example "root.res" or "coll/ucadata.icu". 78 * @return The data as a read-only ByteBuffer. 79 */ 80 public static ByteBuffer getRequiredData(String itemPath) { 81 final Class<ICUBinary> root = ICUBinary.class; 82 83 try (InputStream is = AccessController.doPrivileged(new PrivilegedAction<InputStream>() { 84 public InputStream run() { 85 return root.getResourceAsStream(itemPath); 86 } 87 })) { 88 89 // is.available() may return 0, or 1, or the total number of bytes in the stream, 90 // or some other number. 91 // Do not try to use is.available() == 0 to find the end of the stream! 92 byte[] bytes; 93 int avail = is.available(); 94 if (avail > 32) { 95 // There are more bytes available than just the ICU data header length. 96 // With luck, it is the total number of bytes. 97 bytes = new byte[avail]; 98 } else { 99 bytes = new byte[128]; // empty .res files are even smaller 100 } 101 // Call is.read(...) until one returns a negative value. 102 int length = 0; 103 for(;;) { 104 if (length < bytes.length) { 105 int numRead = is.read(bytes, length, bytes.length - length); 106 if (numRead < 0) { 107 break; // end of stream 108 } 109 length += numRead; 110 } else { 111 // See if we are at the end of the stream before we grow the array. 112 int nextByte = is.read(); 113 if (nextByte < 0) { 114 break; 115 } 116 int capacity = 2 * bytes.length; 117 if (capacity < 128) { 118 capacity = 128; 119 } else if (capacity < 0x4000) { 120 capacity *= 2; // Grow faster until we reach 16kB. 121 } 122 // TODO Java 6 replace new byte[] and arraycopy(): bytes = Arrays.copyOf(bytes, capacity); 123 byte[] newBytes = new byte[capacity]; 124 System.arraycopy(bytes, 0, newBytes, 0, length); 125 bytes = newBytes; 126 bytes[length++] = (byte) nextByte; 127 } 128 } 129 return ByteBuffer.wrap(bytes, 0, length); 130 } 131 catch (IOException e) { 132 throw new UncheckedIOException(e); 133 } 134 } 135 136 /** 137 * Same as readHeader(), but returns a VersionInfo rather than a compact int. 138 */ 139 public static VersionInfo readHeaderAndDataVersion(ByteBuffer bytes, 140 int dataFormat, 141 Authenticate authenticate) 142 throws IOException { 143 return getVersionInfoFromCompactInt(readHeader(bytes, dataFormat, authenticate)); 144 } 145 146 private static final byte BIG_ENDIAN_ = 1; 147 public static final byte[] readHeader(InputStream inputStream, 148 byte dataFormatIDExpected[], 149 Authenticate authenticate) |