view src/java.base/share/classes/jdk/internal/jimage/ImageNativeSubstrate.java @ 12745:f068a4ffddd2

8136583: Core libraries should use blessed modifier order Summary: Run blessed-modifier-order script (see bug) Reviewed-by: psandoz, chegar, alanb, plevart
author martin
date Tue, 15 Sep 2015 21:56:04 -0700
parents d7f0c840a572
children
line wrap: on
line source

/*
 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * 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 sun.misc.JavaNioAccess;
import sun.misc.SharedSecrets;

public final class ImageNativeSubstrate implements ImageSubstrate {
    static {
        java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction<Void>() {
                @Override
                public Void run() {
                    System.loadLibrary("jimage");
                    return null;
                }
            });
     }

    private static final JavaNioAccess NIOACCESS =
            SharedSecrets.getJavaNioAccess();

    private final long id;
    private final long indexAddress;
    private final long dataAddress;

    static native long openImage(String imagePath, boolean bigEndian);
    static native void closeImage(long id);
    static native long getIndexAddress(long id);
    static native long getDataAddress(long id);
    static native boolean readCompressed(long id, long offset,
            ByteBuffer compressedBuffer, long compressedSize,
            ByteBuffer uncompressedBuffer, long uncompressedSize);
    static native boolean read(long id, long offset,
            ByteBuffer uncompressedBuffer, long uncompressedSize);
    static native byte[] getStringBytes(long id, int offset);
    static native long[] getAttributes(long id, int offset);
    static native long[] findAttributes(long id, byte[] path);
    static native int[] attributeOffsets(long id);

    public static native long JIMAGE_Open(String path) throws IOException;
    public static native void JIMAGE_Close(long jimageHandle);
    public static native long JIMAGE_FindResource(long jimageHandle,
                    String moduleName, String Version, String path,
                    long[] size);
    public static native long JIMAGE_GetResource(long jimageHandle,
                    long locationHandle, byte[] buffer, long size);
    // Get an array of names that match; return the count found upto array size
    public static native int JIMAGE_Resources(long jimageHandle,
                    String[] outputNames);
    // Return the module name for the package
    public static native String JIMAGE_PackageToModule(long imageHandle,
                    String packageName);

    static ByteBuffer newDirectByteBuffer(long address, long capacity) {
        assert capacity < Integer.MAX_VALUE;
        return NIOACCESS.newDirectByteBuffer(address, (int)capacity, null);
    }

    private ImageNativeSubstrate(long id) {
        this.id = id;
        this.indexAddress = getIndexAddress(id);
        this.dataAddress = getDataAddress(id);
    }

    static ImageSubstrate openImage(String imagePath, ByteOrder byteOrder)
            throws IOException {
        long id = openImage(imagePath, byteOrder == ByteOrder.BIG_ENDIAN);

        if (id == 0) {
             throw new IOException("Image not found \"" + imagePath + "\"");
        }

        return new ImageNativeSubstrate(id);
    }

    @Override
    public void close() {
        closeImage(id);
    }

    @Override
    public ByteBuffer getIndexBuffer(long offset, long size) {
        return newDirectByteBuffer(indexAddress + offset, size);
    }

    @Override
    public ByteBuffer getDataBuffer(long offset, long size) {
        return dataAddress != 0 ?
                newDirectByteBuffer(dataAddress + offset, size) : null;
    }

    @Override
    public boolean supportsDataBuffer() {
        return dataAddress != 0;
    }

    @Override
    public boolean read(long offset,
                 ByteBuffer compressedBuffer, long compressedSize,
                 ByteBuffer uncompressedBuffer, long uncompressedSize) {
        return readCompressed(id, offset,
                    compressedBuffer, compressedSize,
                    uncompressedBuffer, uncompressedSize);
    }

    @Override
    public boolean read(long offset,
                 ByteBuffer uncompressedBuffer, long uncompressedSize) {
        return read(id, offset, uncompressedBuffer, uncompressedSize);
    }

    @Override
    public byte[] getStringBytes(int offset) {
        byte[] ret = getStringBytes(id, offset);
        if (ret == null) {
            throw new OutOfMemoryError("Error accessing array at offset "
                    + offset);
        }
        return ret;
    }

    @Override
    public long[] getAttributes(int offset) {
        return getAttributes(id, offset);
    }

    @Override
    public ImageLocation findLocation(UTF8String name, ImageStringsReader strings) {
        long[] attributes = findAttributes(id, name.getBytes());

        return attributes != null ? new ImageLocation(attributes, strings) : null;
    }

    @Override
    public int[] attributeOffsets() {
        return attributeOffsets(id);
    }
}