< prev index next >

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

Print this page

 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 package jdk.internal.jimage;
 26 
 27 import java.io.ByteArrayInputStream;
 28 import java.io.IOException;
 29 import java.io.InputStream;
 30 import java.lang.reflect.InvocationTargetException;
 31 import java.lang.reflect.Method;
 32 import java.nio.ByteBuffer;
 33 import java.nio.ByteOrder;
 34 import java.nio.IntBuffer;
 35 import java.nio.channels.FileChannel;
 36 import java.nio.file.Path;
 37 import java.nio.file.StandardOpenOption;
 38 import java.security.AccessController;
 39 import java.security.PrivilegedAction;

 40 import java.util.Objects;

 41 import java.util.stream.IntStream;


 42 import jdk.internal.jimage.decompressor.Decompressor;
 43 
 44 /**
 45  * @implNote This class needs to maintain JDK 8 source compatibility.
 46  *
 47  * It is used internally in the JDK to implement jimage/jrtfs access,
 48  * but also compiled and delivered as part of the jrtfs.jar to support access
 49  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
 50  */
 51 public class BasicImageReader implements AutoCloseable {
 52     @SuppressWarnings({ "removal", "suppression" })
 53     private static boolean isSystemProperty(String key, String value, String def) {
 54         // No lambdas during bootstrap
 55         return AccessController.doPrivileged(
 56             new PrivilegedAction<Boolean>() {
 57                 @Override
 58                 public Boolean run() {
 59                     return value.equals(System.getProperty(key, def));
 60                 }
 61             });

300             // index is twos complement of location attributes index.
301             return -index - 1;
302         } else if (index > 0) {
303             // index is hash seed needed to compute location attributes index.
304             return ImageStringsReader.hashCode(module, name, index) % count;
305         } else {
306             // No entry.
307             return -1;
308         }
309     }
310 
311     public String[] getEntryNames() {
312         return IntStream.range(0, offsets.capacity())
313                 .map(offsets::get)
314                 .filter(o -> o != 0)
315                 .mapToObj(o -> ImageLocation.readFrom(this, o).getFullName())
316                 .sorted()
317                 .toArray(String[]::new);
318     }
319 


















































320     ImageLocation getLocation(int offset) {
321         return ImageLocation.readFrom(this, offset);
322     }
323 
324     public long[] getAttributes(int offset) {
325         if (offset < 0 || offset >= locations.limit()) {
326             throw new IndexOutOfBoundsException("offset");
327         }
328         return ImageLocation.decompress(locations, offset);
329     }
330 
331     public String getString(int offset) {
332         if (offset < 0 || offset >= strings.limit()) {
333             throw new IndexOutOfBoundsException("offset");
334         }
335         return ImageStringsReader.stringFromByteBuffer(strings, offset);
336     }
337 
338     public int match(int offset, String string, int stringOffset) {
339         if (offset < 0 || offset >= strings.limit()) {

 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 package jdk.internal.jimage;
 26 
 27 import java.io.ByteArrayInputStream;
 28 import java.io.IOException;
 29 import java.io.InputStream;
 30 import java.lang.reflect.InvocationTargetException;
 31 import java.lang.reflect.Method;
 32 import java.nio.ByteBuffer;
 33 import java.nio.ByteOrder;
 34 import java.nio.IntBuffer;
 35 import java.nio.channels.FileChannel;
 36 import java.nio.file.Path;
 37 import java.nio.file.StandardOpenOption;
 38 import java.security.AccessController;
 39 import java.security.PrivilegedAction;
 40 import java.util.NoSuchElementException;
 41 import java.util.Objects;
 42 import java.util.Random;
 43 import java.util.stream.IntStream;
 44 import java.util.stream.Stream;
 45 
 46 import jdk.internal.jimage.decompressor.Decompressor;
 47 
 48 /**
 49  * @implNote This class needs to maintain JDK 8 source compatibility.
 50  *
 51  * It is used internally in the JDK to implement jimage/jrtfs access,
 52  * but also compiled and delivered as part of the jrtfs.jar to support access
 53  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
 54  */
 55 public class BasicImageReader implements AutoCloseable {
 56     @SuppressWarnings({ "removal", "suppression" })
 57     private static boolean isSystemProperty(String key, String value, String def) {
 58         // No lambdas during bootstrap
 59         return AccessController.doPrivileged(
 60             new PrivilegedAction<Boolean>() {
 61                 @Override
 62                 public Boolean run() {
 63                     return value.equals(System.getProperty(key, def));
 64                 }
 65             });

304             // index is twos complement of location attributes index.
305             return -index - 1;
306         } else if (index > 0) {
307             // index is hash seed needed to compute location attributes index.
308             return ImageStringsReader.hashCode(module, name, index) % count;
309         } else {
310             // No entry.
311             return -1;
312         }
313     }
314 
315     public String[] getEntryNames() {
316         return IntStream.range(0, offsets.capacity())
317                 .map(offsets::get)
318                 .filter(o -> o != 0)
319                 .mapToObj(o -> ImageLocation.readFrom(this, o).getFullName())
320                 .sorted()
321                 .toArray(String[]::new);
322     }
323 
324     /**
325      * Returns the "raw" API for accessing underlying jimage resource entries.
326      *
327      * <p>This is only meaningful for use by code dealing directly with jimage
328      * files, and cannot be used to reliably lookup resources used at runtime.
329      *
330      * <p>This API remains valid until the image reader from which it was
331      * obtained is closed.
332      */
333     // Package visible for use by ImageReader.
334     ResourceEntries getResourceEntries() {
335         return new ResourceEntries() {
336             @Override
337             public Stream<String> getEntryNames(String module) {
338                 if (module.isEmpty() || module.equals("modules") || module.equals("packages")) {
339                     throw new IllegalArgumentException("Invalid module name: " + module);
340                 }
341                 return IntStream.range(0, offsets.capacity())
342                         .map(offsets::get)
343                         .filter(offset -> offset != 0)
344                         // Reusing a location instance or getting the module
345                         // offset directly would save a lot of allocations here.
346                         .mapToObj(offset -> ImageLocation.readFrom(BasicImageReader.this, offset))
347                         // Reverse lookup of module offset would be faster here.
348                         .filter(loc -> module.equals(loc.getModule()))
349                         .map(ImageLocation::getFullName);
350             }
351 
352             private ImageLocation getResourceLocation(String name) {
353                 if (!name.startsWith("/modules/") && !name.startsWith("/packages/")) {
354                     ImageLocation location = BasicImageReader.this.findLocation(name);
355                     if (location != null) {
356                         return location;
357                     }
358                 }
359                 throw new NoSuchElementException("No such resource entry: " + name);
360             }
361 
362             @Override
363             public long getSize(String name) {
364                 return getResourceLocation(name).getUncompressedSize();
365             }
366 
367             @Override
368             public byte[] getBytes(String name) {
369                 return BasicImageReader.this.getResource(getResourceLocation(name));
370             }
371         };
372     }
373 
374     ImageLocation getLocation(int offset) {
375         return ImageLocation.readFrom(this, offset);
376     }
377 
378     public long[] getAttributes(int offset) {
379         if (offset < 0 || offset >= locations.limit()) {
380             throw new IndexOutOfBoundsException("offset");
381         }
382         return ImageLocation.decompress(locations, offset);
383     }
384 
385     public String getString(int offset) {
386         if (offset < 0 || offset >= strings.limit()) {
387             throw new IndexOutOfBoundsException("offset");
388         }
389         return ImageStringsReader.stringFromByteBuffer(strings, offset);
390     }
391 
392     public int match(int offset, String string, int stringOffset) {
393         if (offset < 0 || offset >= strings.limit()) {
< prev index next >