< prev index next >

src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.internal.jimage;
  27 
  28 import java.nio.ByteBuffer;
  29 
  30 public final class ImageLocation {
  31     final static int ATTRIBUTE_END = 0;
  32     final static int ATTRIBUTE_BASE = 1;
  33     final static int ATTRIBUTE_PARENT = 2;
  34     final static int ATTRIBUTE_EXTENSION = 3;
  35     final static int ATTRIBUTE_OFFSET = 4;
  36     final static int ATTRIBUTE_COMPRESSED = 5;
  37     final static int ATTRIBUTE_UNCOMPRESSED = 6;
  38     final static int ATTRIBUTE_COUNT = 7;
  39 
  40     private int locationOffset;
  41     private long[] attributes;
  42     private byte[] bytes;
  43     private final ImageStrings strings;
  44 
  45     private ImageLocation(ImageStrings strings) {
  46         this.strings = strings;
  47     }
  48 
  49     void writeTo(ImageStream stream) {
  50         compress();
  51         locationOffset = stream.getPosition();
  52         stream.put(bytes, 0, bytes.length);
  53     }
  54 
  55     static ImageLocation readFrom(ByteBuffer locationsBuffer, int offset, ImageStrings strings) {
  56         final long[] attributes = new long[ATTRIBUTE_COUNT];
  57 
  58         for (int i = offset; true; ) {
  59             int data = locationsBuffer.get(i++) & 0xFF;
  60             int kind = attributeKind(data);
  61             assert ATTRIBUTE_END <= kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind";
  62 
  63             if (kind == ATTRIBUTE_END) {
  64                 break;
  65             }
  66 
  67             int length = attributeLength(data);
  68             long value = 0;
  69 
  70             for (int j = 0; j < length; j++) {
  71                 value <<= 8;
  72                 value |= locationsBuffer.get(i++) & 0xFF;
  73             }
  74 
  75             attributes[kind] = value;
  76         }
  77 
  78         ImageLocation location =  new ImageLocation(strings);
  79         location.attributes = attributes;
  80 
  81         return location;
  82     }
  83 
  84     private static int attributeLength(int data) {
  85         return (data & 0x7) + 1;
  86     }
  87 
  88     private static int attributeKind(int data) {
  89         return data >>> 3;
  90     }
  91 
  92     public boolean verify(UTF8String name) {
  93         UTF8String match = UTF8String.match(name, getParent());
  94 
  95         if (match == null) {
  96             return false;
  97         }
  98 
  99         match = UTF8String.match(match, getBase());
 100 
 101         if (match == null) {
 102             return false;
 103         }
 104 
 105         match = UTF8String.match(match, getExtension());
 106 
 107         return match != null && match.length() == 0;
 108     }
 109 
 110 
 111     long getAttribute(int kind) {
 112         assert ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind";
 113         decompress();
 114 
 115         return attributes[kind];
 116     }
 117 
 118     UTF8String getAttributeUTF8String(int kind) {
 119         assert ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind";
 120         decompress();
 121 
 122         return strings.get((int)attributes[kind]);
 123     }
 124 
 125     String getAttributeString(int kind) {
 126         return getAttributeUTF8String(kind).toString();
 127     }
 128 
 129     ImageLocation addAttribute(int kind, long value) {
 130         assert ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind";
 131         decompress();
 132         attributes[kind] = value;
 133         return this;
 134     }
 135 
 136     private void decompress() {
 137         if (attributes == null) {
 138             attributes = new long[ATTRIBUTE_COUNT];
 139         }
 140 
 141         if (bytes != null) {
 142             for (int i = 0; i < bytes.length; ) {
 143                 int data = bytes[i++] & 0xFF;
 144                 int kind = attributeKind(data);
 145 
 146                 if (kind == ATTRIBUTE_END) {
 147                     break;
 148                 }
 149 
 150                 assert ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT : "Invalid attribute kind";
 151                 int length = attributeLength(data);
 152                 long value = 0;
 153 
 154                 for (int j = 0; j < length; j++) {
 155                     value <<= 8;
 156                     value |= bytes[i++] & 0xFF;
 157                 }
 158 
 159                  attributes[kind] = value;
 160             }
 161 
 162             bytes = null;
 163         }
 164     }
 165 
 166     private void compress() {
 167         if (bytes == null) {
 168             ImageStream stream = new ImageStream(16);
 169 
 170             for (int kind = ATTRIBUTE_END + 1; kind < ATTRIBUTE_COUNT; kind++) {
 171                 long value = attributes[kind];
 172 
 173                 if (value != 0) {
 174                     int n = (63 - Long.numberOfLeadingZeros(value)) >> 3;
 175                     stream.put((kind << 3) | n);
 176 
 177                     for (int i = n; i >= 0; i--) {
 178                         stream.put((int)(value >> (i << 3)));
 179                     }
 180                 }
 181             }
 182 
 183             stream.put(ATTRIBUTE_END << 3);
 184             bytes = stream.toArray();
 185             attributes = null;
 186         }
 187     }
 188 
 189     static ImageLocation newLocation(UTF8String fullname, ImageStrings strings, long contentOffset, long compressedSize, long uncompressedSize) {
 190         UTF8String base;
 191         UTF8String extension = extension(fullname);
 192         int parentOffset = ImageStrings.EMPTY_OFFSET;
 193         int extensionOffset = ImageStrings.EMPTY_OFFSET;
 194         int baseOffset;
 195 
 196         if (extension.length() != 0) {
 197             UTF8String parent = parent(fullname);
 198             base = base(fullname);
 199             parentOffset = strings.add(parent);
 200             extensionOffset = strings.add(extension);
 201         } else {
 202             base = fullname;
 203         }
 204 
 205         baseOffset = strings.add(base);
 206 
 207         return new ImageLocation(strings)
 208                .addAttribute(ATTRIBUTE_BASE, baseOffset)
 209                .addAttribute(ATTRIBUTE_PARENT, parentOffset)
 210                .addAttribute(ATTRIBUTE_EXTENSION, extensionOffset)
 211                .addAttribute(ATTRIBUTE_OFFSET, contentOffset)
 212                .addAttribute(ATTRIBUTE_COMPRESSED, compressedSize)
 213                .addAttribute(ATTRIBUTE_UNCOMPRESSED, uncompressedSize);
 214     }
 215 
 216     @Override
 217     public int hashCode() {
 218         return getExtension().hashCode(getBase().hashCode(getParent().hashCode()));
 219     }
 220 
 221     int hashCode(int base) {
 222         return getExtension().hashCode(getBase().hashCode(getParent().hashCode(base)));
 223     }
 224 
 225     @Override
 226     public boolean equals(Object obj) {
 227         if (this == obj) {
 228             return true;
 229         }
 230 
 231         if (!(obj instanceof ImageLocation)) {
 232             return false;
 233         }
 234 
 235         ImageLocation other = (ImageLocation)obj;
 236 
 237         return getBaseOffset() == other.getBaseOffset() &&
 238                getParentOffset() == other.getParentOffset() &&
 239                getExtensionOffset() == other.getExtensionOffset();
 240     }
 241 
 242     static UTF8String parent(UTF8String fullname) {
 243         int slash = fullname.lastIndexOf('/');
 244 
 245         return slash == UTF8String.NOT_FOUND ? UTF8String.EMPTY_STRING : fullname.substring(0, slash + 1);
 246     }
 247 
 248     static UTF8String extension(UTF8String fullname) {
 249         int dot = fullname.lastIndexOf('.');
 250 
 251         return dot == UTF8String.NOT_FOUND ? UTF8String.EMPTY_STRING : fullname.substring(dot);
 252     }
 253 
 254     static UTF8String base(UTF8String fullname) {
 255         int slash = fullname.lastIndexOf('/');
 256 
 257         if (slash != UTF8String.NOT_FOUND) {
 258             fullname = fullname.substring(slash + 1);
 259         }
 260 
 261         int dot = fullname.lastIndexOf('.');
 262 
 263         if (dot != UTF8String.NOT_FOUND) {
 264             fullname = fullname.substring(0, dot);
 265         }
 266 
 267         return fullname;
 268     }
 269 
 270     int getLocationOffset() {
 271         return locationOffset;
 272     }
 273 
 274     UTF8String getBase() {
 275         return getAttributeUTF8String(ATTRIBUTE_BASE);
 276     }
 277 
 278     public String getBaseString() {
 279         return  getBase().toString();
 280     }
 281 
 282     int getBaseOffset() {
 283         return (int)getAttribute(ATTRIBUTE_BASE);
 284     }
 285 
 286     UTF8String getParent() {
 287         return getAttributeUTF8String(ATTRIBUTE_PARENT);
 288     }
 289 
 290     public String getParentString() {
 291         return getParent().toString();
 292     }
 293 
 294     int getParentOffset() {
 295         return (int)getAttribute(ATTRIBUTE_PARENT);
 296     }
 297 
 298     UTF8String getExtension() {
 299         return getAttributeUTF8String(ATTRIBUTE_EXTENSION);
 300     }
 301 
 302     public String getExtensionString() {
 303         return getExtension().toString();
 304     }
 305 
 306     int getExtensionOffset() {
 307         return (int)getAttribute(ATTRIBUTE_EXTENSION);
 308     }
 309 
 310     UTF8String getName() {
 311         return getBase().concat(getExtension());
 312     }
 313 
 314     String getNameString() {
 315         return getName().toString();
 316     }
 317 
 318     UTF8String getFullname() {
 319         return getParent().concat(getBase(), getExtension());
 320     }
 321 
 322     String getFullnameString() {
 323         return getFullname().toString();
 324     }
 325 
 326     public long getContentOffset() {
 327         return getAttribute(ATTRIBUTE_OFFSET);
 328     }
 329 
 330     public long getCompressedSize() {
 331         return getAttribute(ATTRIBUTE_COMPRESSED);
 332     }
 333 
 334     public long getUncompressedSize() {
 335         return getAttribute(ATTRIBUTE_UNCOMPRESSED);
 336     }
 337 
 338     @Override
 339     public String toString() {
 340         final StringBuilder sb = new StringBuilder();
 341         decompress();
 342 
 343         for (int kind = ATTRIBUTE_END + 1; kind < ATTRIBUTE_COUNT; kind++) {
 344             long value = attributes[kind];
 345 
 346             if (value == 0) {
 347                 continue;
 348             }
 349 
 350             switch (kind) {
 351                 case ATTRIBUTE_BASE:
 352                     sb.append("Base: ");
 353                     sb.append(value);
 354                     sb.append(' ');
 355                     sb.append(strings.get((int)value).toString());
 356                     break;
 357 
 358                 case ATTRIBUTE_PARENT:
 359                     sb.append("Parent: ");
 360                     sb.append(value);
 361                     sb.append(' ');
 362                     sb.append(strings.get((int)value).toString());
 363                     break;
 364 
 365                 case ATTRIBUTE_EXTENSION:
 366                     sb.append("Extension: ");
 367                     sb.append(value);
 368                     sb.append(' ');
 369                     sb.append(strings.get((int)value).toString());
 370                     break;
 371 
 372                 case ATTRIBUTE_OFFSET:
 373                     sb.append("Offset: ");
 374                     sb.append(value);
 375                     break;
 376 
 377                 case ATTRIBUTE_COMPRESSED:
 378                     sb.append("Compressed: ");
 379                     sb.append(value);
 380                     break;
 381 
 382                 case ATTRIBUTE_UNCOMPRESSED:
 383                     sb.append("Uncompressed: ");
 384                     sb.append(value);
 385                     break;
 386            }
 387 
 388            sb.append("; ");
 389         }
 390 
 391         return sb.toString();
 392     }
 393 }


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.internal.jimage;
  27 
  28 public final class ImageLocation  extends ImageLocationBase {
  29     ImageLocation(long[] attributes, ImageStringsReader strings) {
  30         super(attributes, strings);








































































  31     }
  32 
  33     static ImageLocation readFrom(BasicImageReader reader, int offset) {
  34         long[] attributes = reader.getAttributes(offset);
  35         ImageStringsReader strings = reader.getStrings();


























































































































































































































































































  36 
  37         return new ImageLocation(attributes, strings);
  38     }
  39 }
< prev index next >