--- old/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java 2015-06-23 14:28:53.000000000 +0200 +++ new/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java 2015-06-23 14:28:53.000000000 +0200 @@ -25,369 +25,15 @@ package jdk.internal.jimage; -import java.nio.ByteBuffer; - -public final class ImageLocation { - final static int ATTRIBUTE_END = 0; - final static int ATTRIBUTE_BASE = 1; - final static int ATTRIBUTE_PARENT = 2; - final static int ATTRIBUTE_EXTENSION = 3; - final static int ATTRIBUTE_OFFSET = 4; - final static int ATTRIBUTE_COMPRESSED = 5; - final static int ATTRIBUTE_UNCOMPRESSED = 6; - final static int ATTRIBUTE_COUNT = 7; - - private int locationOffset; - private long[] attributes; - private byte[] bytes; - private final ImageStrings strings; - - private ImageLocation(ImageStrings strings) { - this.strings = strings; - } - - void writeTo(ImageStream stream) { - compress(); - locationOffset = stream.getPosition(); - stream.put(bytes, 0, bytes.length); - } - - static ImageLocation readFrom(ByteBuffer locationsBuffer, int offset, ImageStrings strings) { - final long[] attributes = new long[ATTRIBUTE_COUNT]; - - for (int i = offset; true; ) { - int data = locationsBuffer.get(i++) & 0xFF; - int kind = attributeKind(data); - assert ATTRIBUTE_END <= kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind"; - - if (kind == ATTRIBUTE_END) { - break; - } - - int length = attributeLength(data); - long value = 0; - - for (int j = 0; j < length; j++) { - value <<= 8; - value |= locationsBuffer.get(i++) & 0xFF; - } - - attributes[kind] = value; - } - - ImageLocation location = new ImageLocation(strings); - location.attributes = attributes; - - return location; - } - - private static int attributeLength(int data) { - return (data & 0x7) + 1; - } - - private static int attributeKind(int data) { - return data >>> 3; - } - - public boolean verify(UTF8String name) { - UTF8String match = UTF8String.match(name, getParent()); - - if (match == null) { - return false; - } - - match = UTF8String.match(match, getBase()); - - if (match == null) { - return false; - } - - match = UTF8String.match(match, getExtension()); - - return match != null && match.length() == 0; - } - - - long getAttribute(int kind) { - assert ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind"; - decompress(); - - return attributes[kind]; - } - - UTF8String getAttributeUTF8String(int kind) { - assert ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind"; - decompress(); - - return strings.get((int)attributes[kind]); - } - - String getAttributeString(int kind) { - return getAttributeUTF8String(kind).toString(); - } - - ImageLocation addAttribute(int kind, long value) { - assert ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind"; - decompress(); - attributes[kind] = value; - return this; - } - - private void decompress() { - if (attributes == null) { - attributes = new long[ATTRIBUTE_COUNT]; - } - - if (bytes != null) { - for (int i = 0; i < bytes.length; ) { - int data = bytes[i++] & 0xFF; - int kind = attributeKind(data); - - if (kind == ATTRIBUTE_END) { - break; - } - - assert ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind"; - int length = attributeLength(data); - long value = 0; - - for (int j = 0; j < length; j++) { - value <<= 8; - value |= bytes[i++] & 0xFF; - } - - attributes[kind] = value; - } - - bytes = null; - } - } - - private void compress() { - if (bytes == null) { - ImageStream stream = new ImageStream(16); - - for (int kind = ATTRIBUTE_END + 1; kind < ATTRIBUTE_COUNT; kind++) { - long value = attributes[kind]; - - if (value != 0) { - int n = (63 - Long.numberOfLeadingZeros(value)) >> 3; - stream.put((kind << 3) | n); - - for (int i = n; i >= 0; i--) { - stream.put((int)(value >> (i << 3))); - } - } - } - - stream.put(ATTRIBUTE_END << 3); - bytes = stream.toArray(); - attributes = null; - } +public final class ImageLocation extends ImageLocationBase { + ImageLocation(long[] attributes, ImageStringsReader strings) { + super(attributes, strings); } - static ImageLocation newLocation(UTF8String fullname, ImageStrings strings, long contentOffset, long compressedSize, long uncompressedSize) { - UTF8String base; - UTF8String extension = extension(fullname); - int parentOffset = ImageStrings.EMPTY_OFFSET; - int extensionOffset = ImageStrings.EMPTY_OFFSET; - int baseOffset; - - if (extension.length() != 0) { - UTF8String parent = parent(fullname); - base = base(fullname); - parentOffset = strings.add(parent); - extensionOffset = strings.add(extension); - } else { - base = fullname; - } - - baseOffset = strings.add(base); - - return new ImageLocation(strings) - .addAttribute(ATTRIBUTE_BASE, baseOffset) - .addAttribute(ATTRIBUTE_PARENT, parentOffset) - .addAttribute(ATTRIBUTE_EXTENSION, extensionOffset) - .addAttribute(ATTRIBUTE_OFFSET, contentOffset) - .addAttribute(ATTRIBUTE_COMPRESSED, compressedSize) - .addAttribute(ATTRIBUTE_UNCOMPRESSED, uncompressedSize); - } - - @Override - public int hashCode() { - return getExtension().hashCode(getBase().hashCode(getParent().hashCode())); - } - - int hashCode(int base) { - return getExtension().hashCode(getBase().hashCode(getParent().hashCode(base))); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (!(obj instanceof ImageLocation)) { - return false; - } - - ImageLocation other = (ImageLocation)obj; - - return getBaseOffset() == other.getBaseOffset() && - getParentOffset() == other.getParentOffset() && - getExtensionOffset() == other.getExtensionOffset(); - } - - static UTF8String parent(UTF8String fullname) { - int slash = fullname.lastIndexOf('/'); - - return slash == UTF8String.NOT_FOUND ? UTF8String.EMPTY_STRING : fullname.substring(0, slash + 1); - } - - static UTF8String extension(UTF8String fullname) { - int dot = fullname.lastIndexOf('.'); - - return dot == UTF8String.NOT_FOUND ? UTF8String.EMPTY_STRING : fullname.substring(dot); - } - - static UTF8String base(UTF8String fullname) { - int slash = fullname.lastIndexOf('/'); - - if (slash != UTF8String.NOT_FOUND) { - fullname = fullname.substring(slash + 1); - } - - int dot = fullname.lastIndexOf('.'); - - if (dot != UTF8String.NOT_FOUND) { - fullname = fullname.substring(0, dot); - } - - return fullname; - } - - int getLocationOffset() { - return locationOffset; - } - - UTF8String getBase() { - return getAttributeUTF8String(ATTRIBUTE_BASE); - } - - public String getBaseString() { - return getBase().toString(); - } - - int getBaseOffset() { - return (int)getAttribute(ATTRIBUTE_BASE); - } - - UTF8String getParent() { - return getAttributeUTF8String(ATTRIBUTE_PARENT); - } - - public String getParentString() { - return getParent().toString(); - } - - int getParentOffset() { - return (int)getAttribute(ATTRIBUTE_PARENT); - } - - UTF8String getExtension() { - return getAttributeUTF8String(ATTRIBUTE_EXTENSION); - } - - public String getExtensionString() { - return getExtension().toString(); - } - - int getExtensionOffset() { - return (int)getAttribute(ATTRIBUTE_EXTENSION); - } - - UTF8String getName() { - return getBase().concat(getExtension()); - } - - String getNameString() { - return getName().toString(); - } - - UTF8String getFullname() { - return getParent().concat(getBase(), getExtension()); - } - - String getFullnameString() { - return getFullname().toString(); - } - - public long getContentOffset() { - return getAttribute(ATTRIBUTE_OFFSET); - } - - public long getCompressedSize() { - return getAttribute(ATTRIBUTE_COMPRESSED); - } - - public long getUncompressedSize() { - return getAttribute(ATTRIBUTE_UNCOMPRESSED); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - decompress(); - - for (int kind = ATTRIBUTE_END + 1; kind < ATTRIBUTE_COUNT; kind++) { - long value = attributes[kind]; - - if (value == 0) { - continue; - } - - switch (kind) { - case ATTRIBUTE_BASE: - sb.append("Base: "); - sb.append(value); - sb.append(' '); - sb.append(strings.get((int)value).toString()); - break; - - case ATTRIBUTE_PARENT: - sb.append("Parent: "); - sb.append(value); - sb.append(' '); - sb.append(strings.get((int)value).toString()); - break; - - case ATTRIBUTE_EXTENSION: - sb.append("Extension: "); - sb.append(value); - sb.append(' '); - sb.append(strings.get((int)value).toString()); - break; - - case ATTRIBUTE_OFFSET: - sb.append("Offset: "); - sb.append(value); - break; - - case ATTRIBUTE_COMPRESSED: - sb.append("Compressed: "); - sb.append(value); - break; - - case ATTRIBUTE_UNCOMPRESSED: - sb.append("Uncompressed: "); - sb.append(value); - break; - } - - sb.append("; "); - } + static ImageLocation readFrom(BasicImageReader reader, int offset) { + long[] attributes = reader.getAttributes(offset); + ImageStringsReader strings = reader.getStrings(); - return sb.toString(); + return new ImageLocation(attributes, strings); } }