< 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             });

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


















































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

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