< prev index next >
src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java
Print this page
*** 22,88 ****
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.jimage;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
! import java.nio.MappedByteBuffer;
! import java.nio.channels.FileChannel;
! import java.util.ArrayList;
! import java.util.Arrays;
! import java.util.List;
public class BasicImageReader {
private final String imagePath;
! private final PReader preader;
private final ByteOrder byteOrder;
! private final ImageHeader header;
! private final int indexSize;
! private final IntBuffer redirectBuffer;
! private final IntBuffer offsetsBuffer;
! private final ByteBuffer locationsBuffer;
! private final ByteBuffer stringsBuffer;
! private final ImageStrings strings;
! protected BasicImageReader(String imagePath, ByteOrder byteOrder) throws IOException {
this.imagePath = imagePath;
! this.preader = PReader.open(imagePath);
this.byteOrder = byteOrder;
! this.header = ImageHeader.readFrom(byteOrder, getIntBuffer(0, ImageHeader.getHeaderSize()));
! this.indexSize = header.getIndexSize();
! this.redirectBuffer = getIntBuffer(header.getRedirectOffset(), header.getRedirectSize());
! this.offsetsBuffer = getIntBuffer(header.getOffsetsOffset(), header.getOffsetsSize());
! this.locationsBuffer = getByteBuffer(header.getLocationsOffset(), header.getLocationsSize());
! this.stringsBuffer = getByteBuffer(header.getStringsOffset(), header.getStringsSize());
! this.strings = new ImageStrings(new ImageStream(stringsBuffer));
}
protected BasicImageReader(String imagePath) throws IOException {
this(imagePath, ByteOrder.nativeOrder());
}
public static BasicImageReader open(String imagePath) throws IOException {
return new BasicImageReader(imagePath, ByteOrder.nativeOrder());
}
public String imagePath() {
return imagePath;
}
public boolean isOpen() {
! return preader.isOpen();
}
public void close() throws IOException {
! preader.close();
}
! public ImageHeader getHeader() {
! return header;
}
public ImageLocation findLocation(String name) {
return findLocation(new UTF8String(name));
}
--- 22,113 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.jimage;
+ import java.io.ByteArrayInputStream;
import java.io.IOException;
+ import java.io.File;
+ import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
! import java.util.Comparator;
! import java.util.stream.IntStream;
public class BasicImageReader {
private final String imagePath;
! private final ImageSubstrate substrate;
private final ByteOrder byteOrder;
! private final ImageStringsReader strings;
! protected BasicImageReader(String imagePath, ByteOrder byteOrder)
! throws IOException {
this.imagePath = imagePath;
! this.substrate = openImageSubstrate(imagePath, byteOrder);
this.byteOrder = byteOrder;
! this.strings = new ImageStringsReader(this);
}
protected BasicImageReader(String imagePath) throws IOException {
this(imagePath, ByteOrder.nativeOrder());
}
+ private static ImageSubstrate openImageSubstrate(String imagePath, ByteOrder byteOrder)
+ throws IOException {
+ ImageSubstrate substrate;
+
+ try {
+ substrate = ImageNativeSubstrate.openImage(imagePath, byteOrder);
+ } catch (UnsatisfiedLinkError ex) {
+ substrate = ImageJavaSubstrate.openImage(imagePath, byteOrder);
+ }
+
+ return substrate;
+ }
+
public static BasicImageReader open(String imagePath) throws IOException {
return new BasicImageReader(imagePath, ByteOrder.nativeOrder());
}
+ public static void releaseByteBuffer(ByteBuffer buffer) {
+ ImageBufferCache.releaseBuffer(buffer);
+ }
+
+ public ByteOrder getByteOrder() {
+ return byteOrder;
+ }
+
public String imagePath() {
return imagePath;
}
+ public String imagePathName() {
+ int slash = imagePath().lastIndexOf(File.separator);
+
+ if (slash != -1) {
+ return imagePath().substring(slash + 1);
+ }
+
+ return imagePath();
+ }
+
public boolean isOpen() {
! return true;
}
public void close() throws IOException {
! substrate.close();
! }
!
! public ImageHeader getHeader() throws IOException {
! return ImageHeader.readFrom(
! getIndexIntBuffer(0, ImageHeader.getHeaderSize()));
}
! public ImageStringsReader getStrings() {
! return strings;
}
public ImageLocation findLocation(String name) {
return findLocation(new UTF8String(name));
}
*** 90,239 ****
public ImageLocation findLocation(byte[] name) {
return findLocation(new UTF8String(name));
}
public synchronized ImageLocation findLocation(UTF8String name) {
! int count = header.getLocationCount();
! int hash = name.hashCode() % count;
! int redirect = getRedirect(hash);
!
! if (redirect == 0) {
! return null;
}
! int index;
!
! if (redirect < 0) {
! // If no collision.
! index = -redirect - 1;
! } else {
! // If collision, recompute hash code.
! index = name.hashCode(redirect) % count;
}
! int offset = getOffset(index);
!
! if (offset == 0) {
! return null;
}
! ImageLocation location = getLocation(offset);
! return location.verify(name) ? location : null;
}
! public String[] getEntryNames() {
! return getEntryNames(true);
}
! public String[] getEntryNames(boolean sorted) {
! int count = header.getLocationCount();
! List<String> list = new ArrayList<>();
!
! for (int i = 0; i < count; i++) {
! int offset = getOffset(i);
!
! if (offset != 0) {
! ImageLocation location = ImageLocation.readFrom(locationsBuffer, offset, strings);
! list.add(location.getFullnameString());
! }
}
! String[] array = list.toArray(new String[0]);
!
! if (sorted) {
! Arrays.sort(array);
}
! return array;
}
! protected ImageLocation[] getAllLocations(boolean sorted) {
! int count = header.getLocationCount();
! List<ImageLocation> list = new ArrayList<>();
!
! for (int i = 0; i < count; i++) {
! int offset = getOffset(i);
! if (offset != 0) {
! ImageLocation location = ImageLocation.readFrom(locationsBuffer, offset, strings);
! list.add(location);
! }
}
! ImageLocation[] array = list.toArray(new ImageLocation[0]);
! if (sorted) {
! Arrays.sort(array, (ImageLocation loc1, ImageLocation loc2) ->
! loc1.getFullnameString().compareTo(loc2.getFullnameString()));
}
! return array;
}
! private IntBuffer getIntBuffer(long offset, long size) throws IOException {
! MappedByteBuffer buffer = preader.channel().map(FileChannel.MapMode.READ_ONLY, offset, size);
! buffer.order(byteOrder);
! return buffer.asIntBuffer();
}
! private ByteBuffer getByteBuffer(long offset, long size) throws IOException {
! MappedByteBuffer buffer = preader.channel().map(FileChannel.MapMode.READ_ONLY, offset, size);
! // order is not copied into the readonly copy.
! ByteBuffer readOnly = buffer.asReadOnlyBuffer();
! readOnly.order(byteOrder);
! return readOnly;
! }
! private int getRedirect(int index) {
! return redirectBuffer.get(index);
! }
! private int getOffset(int index) {
! return offsetsBuffer.get(index);
}
! private ImageLocation getLocation(int offset) {
! return ImageLocation.readFrom(locationsBuffer, offset, strings);
! }
! public String getString(int offset) {
! return strings.get(offset).toString();
}
! public byte[] getResource(ImageLocation loc) throws IOException {
long compressedSize = loc.getCompressedSize();
assert compressedSize < Integer.MAX_VALUE;
! if (compressedSize == 0) {
! return preader.read((int)loc.getUncompressedSize(),
! indexSize + loc.getContentOffset());
! } else {
! byte[] buf = preader.read((int)compressedSize,
! indexSize + loc.getContentOffset());
! return ImageFile.Compressor.decompress(buf);
}
}
! public byte[] getResource(String name) throws IOException {
! ImageLocation location = findLocation(name);
! return location != null ? getResource(location) : null;
}
! public List<String> getNames(String name) throws IOException {
! return getNames(getResource(name));
}
! public List<String> getNames(byte[] bytes) {
! IntBuffer buffer = ByteBuffer.wrap(bytes).asIntBuffer();
! List<String> names = new ArrayList<>();
! while (buffer.hasRemaining()) {
! int offset = buffer.get();
! names.add(getString(offset));
}
! return names;
}
}
--- 115,263 ----
public ImageLocation findLocation(byte[] name) {
return findLocation(new UTF8String(name));
}
public synchronized ImageLocation findLocation(UTF8String name) {
! return substrate.findLocation(name, strings);
}
! public String[] getEntryNames() {
! return IntStream.of(substrate.attributeOffsets())
! .filter(o -> o != 0)
! .mapToObj(o -> ImageLocation.readFrom(this, o).getFullNameString())
! .sorted()
! .toArray(String[]::new);
}
! protected ImageLocation[] getAllLocations(boolean sorted) {
! return IntStream.of(substrate.attributeOffsets())
! .filter(o -> o != 0)
! .mapToObj(o -> ImageLocation.readFrom(this, o))
! .sorted(Comparator.comparing(ImageLocation::getFullNameString))
! .toArray(ImageLocation[]::new);
}
! private IntBuffer getIndexIntBuffer(long offset, long size)
! throws IOException {
! ByteBuffer buffer = substrate.getIndexBuffer(offset, size);
! buffer.order(byteOrder);
! return buffer.asIntBuffer();
}
! ImageLocation getLocation(int offset) {
! return ImageLocation.readFrom(this, offset);
}
! public long[] getAttributes(int offset) {
! return substrate.getAttributes(offset);
}
! public String getString(int offset) {
! return getUTF8String(offset).toString();
}
! public UTF8String getUTF8String(int offset) {
! return new UTF8String(substrate.getStringBytes(offset));
}
! private byte[] getBufferBytes(ByteBuffer buffer, long size) {
! assert size < Integer.MAX_VALUE;
! byte[] bytes = new byte[(int)size];
! buffer.get(bytes);
! return bytes;
}
! private byte[] getBufferBytes(long offset, long size) {
! ByteBuffer buffer = substrate.getDataBuffer(offset, size);
! return getBufferBytes(buffer, size);
}
! public byte[] getResource(ImageLocation loc) {
! long offset = loc.getContentOffset();
! long compressedSize = loc.getCompressedSize();
! long uncompressedSize = loc.getUncompressedSize();
! assert compressedSize < Integer.MAX_VALUE;
! assert uncompressedSize < Integer.MAX_VALUE;
!
! if (substrate.supportsDataBuffer() && compressedSize == 0) {
! return getBufferBytes(offset, uncompressedSize);
}
! ByteBuffer uncompressedBuffer = ImageBufferCache.getBuffer(uncompressedSize);
! boolean isRead;
! if (compressedSize != 0) {
! ByteBuffer compressedBuffer = ImageBufferCache.getBuffer(compressedSize);
! isRead = substrate.read(offset, compressedBuffer, compressedSize,
! uncompressedBuffer, uncompressedSize);
! ImageBufferCache.releaseBuffer(compressedBuffer);
! } else {
! isRead = substrate.read(offset, uncompressedBuffer, uncompressedSize);
}
! byte[] bytes = isRead ? getBufferBytes(uncompressedBuffer,
! uncompressedSize) : null;
! ImageBufferCache.releaseBuffer(uncompressedBuffer);
! return bytes;
}
! public byte[] getResource(String name) {
! ImageLocation location = findLocation(name);
! return location != null ? getResource(location) : null;
}
! public ByteBuffer getResourceBuffer(ImageLocation loc) {
! long offset = loc.getContentOffset();
long compressedSize = loc.getCompressedSize();
+ long uncompressedSize = loc.getUncompressedSize();
assert compressedSize < Integer.MAX_VALUE;
+ assert uncompressedSize < Integer.MAX_VALUE;
! if (substrate.supportsDataBuffer() && compressedSize == 0) {
! return substrate.getDataBuffer(offset, uncompressedSize);
}
+
+ ByteBuffer uncompressedBuffer = ImageBufferCache.getBuffer(uncompressedSize);
+ boolean isRead;
+
+ if (compressedSize != 0) {
+ ByteBuffer compressedBuffer = ImageBufferCache.getBuffer(compressedSize);
+ isRead = substrate.read(offset, compressedBuffer, compressedSize,
+ uncompressedBuffer, uncompressedSize);
+ ImageBufferCache.releaseBuffer(compressedBuffer);
+ } else {
+ isRead = substrate.read(offset, uncompressedBuffer, uncompressedSize);
}
! if (isRead) {
! return uncompressedBuffer;
! } else {
! ImageBufferCache.releaseBuffer(uncompressedBuffer);
! return null;
! }
}
! public ByteBuffer getResourceBuffer(String name) {
! ImageLocation location = findLocation(name);
!
! return location != null ? getResourceBuffer(location) : null;
}
! public InputStream getResourceStream(ImageLocation loc) {
! byte[] bytes = getResource(loc);
! return new ByteArrayInputStream(bytes);
}
! public InputStream getResourceStream(String name) {
! ImageLocation location = findLocation(name);
!
! return location != null ? getResourceStream(location) : null;
}
}
< prev index next >