bb5de762da
Add asserts to diagnose Reviewed-by: jlaskey
656 lines
22 KiB
C++
656 lines
22 KiB
C++
/*
|
|
* Copyright (c) 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.
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "jni.h"
|
|
#include "jni_util.h"
|
|
|
|
#include "endian.hpp"
|
|
#include "imageDecompressor.hpp"
|
|
#include "imageFile.hpp"
|
|
#include "inttypes.hpp"
|
|
#include "jimage.hpp"
|
|
#include "osSupport.hpp"
|
|
|
|
#include "jdk_internal_jimage_ImageNativeSubstrate.h"
|
|
|
|
extern bool MemoryMapImage;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Static function for primitive throw since libjimage is not linked with libjava
|
|
static void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg)
|
|
{
|
|
jclass cls = (env)->FindClass(name);
|
|
|
|
if (cls != 0) /* Otherwise an exception has already been thrown */
|
|
(env)->ThrowNew(cls, msg);
|
|
}
|
|
|
|
// jdk.internal.jimage /////////////////////////////////////////////////////////
|
|
|
|
// Java entry to open an image file for sharing.
|
|
|
|
static jlong JIMAGE_Open(JNIEnv *env, const char *nativePath, jboolean big_endian) {
|
|
// Open image file for reading.
|
|
ImageFileReader* reader = ImageFileReader::open(nativePath, big_endian != JNI_FALSE);
|
|
// Return image ID as a jlong.
|
|
return ImageFileReader::readerToID(reader);
|
|
}
|
|
|
|
// Java entry for closing a shared image file.
|
|
|
|
static void JIMAGE_Close(JNIEnv *env, jlong id) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// If valid reader the close.
|
|
if (reader != NULL) {
|
|
ImageFileReader::close(reader);
|
|
}
|
|
}
|
|
|
|
// Java entry for accessing the base address of the image index.
|
|
|
|
static jlong JIMAGE_GetIndexAddress(JNIEnv *env, jlong id) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// If valid reader return index base address (as jlong) else zero.
|
|
return reader != NULL ? (jlong) reader->get_index_address() : 0L;
|
|
}
|
|
|
|
// Java entry for accessing the base address of the image data.
|
|
|
|
static jlong JIMAGE_GetDataAddress(JNIEnv *env, jlong id) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// If valid reader return data base address (as jlong) else zero.
|
|
return MemoryMapImage && reader != NULL ? (jlong) reader->get_data_address() : 0L;
|
|
}
|
|
|
|
// Java entry for reading an uncompressed resource from the image.
|
|
|
|
static jboolean JIMAGE_Read(JNIEnv *env, jlong id, jlong offset,
|
|
unsigned char* uncompressedAddress, jlong uncompressed_size) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);\
|
|
// If not a valid reader the fail the read.
|
|
if (reader == NULL) return false;
|
|
// Get the file offset of resource data.
|
|
u8 file_offset = reader->get_index_size() + offset;
|
|
// Check validity of arguments.
|
|
if (offset < 0 ||
|
|
uncompressed_size < 0 ||
|
|
file_offset > reader->file_size() - uncompressed_size) {
|
|
return false;
|
|
}
|
|
// Read file content into buffer.
|
|
return (jboolean) reader->read_at((u1*) uncompressedAddress, uncompressed_size,
|
|
file_offset);
|
|
}
|
|
|
|
// Java entry for reading a compressed resource from the image.
|
|
|
|
static jboolean JIMAGE_ReadCompressed(JNIEnv *env,
|
|
jlong id, jlong offset,
|
|
unsigned char* compressedAddress, jlong compressed_size,
|
|
unsigned char* uncompressedAddress, jlong uncompressed_size) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// If not a valid reader the fail the read.
|
|
if (reader == NULL) return false;
|
|
// Get the file offset of resource data.
|
|
u8 file_offset = reader->get_index_size() + offset;
|
|
// Check validity of arguments.
|
|
if (offset < 0 ||
|
|
compressed_size < 0 ||
|
|
uncompressed_size < 0 ||
|
|
file_offset > reader->file_size() - compressed_size) {
|
|
return false;
|
|
}
|
|
|
|
// Read file content into buffer.
|
|
bool is_read = reader->read_at(compressedAddress, compressed_size,
|
|
file_offset);
|
|
// If successfully read then decompress.
|
|
if (is_read) {
|
|
const ImageStrings strings = reader->get_strings();
|
|
ImageDecompressor::decompress_resource(compressedAddress, uncompressedAddress,
|
|
(u4) uncompressed_size, &strings);
|
|
}
|
|
return (jboolean) is_read;
|
|
}
|
|
|
|
// Java entry for retrieving UTF-8 bytes from image string table.
|
|
|
|
static const char* JIMAGE_GetStringBytes(JNIEnv *env, jlong id, jint offset) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// Fail if not valid reader.
|
|
if (reader == NULL) return NULL;
|
|
// Manage image string table.
|
|
ImageStrings strings = reader->get_strings();
|
|
// Retrieve string adrress from table.
|
|
const char* data = strings.get(offset);
|
|
return data;
|
|
}
|
|
|
|
// Utility function to copy location information into a jlong array.
|
|
// WARNING: This function is experimental and temporary during JDK 9 development
|
|
// cycle. It will not be supported in the eventual JDK 9 release.
|
|
|
|
static void image_expand_location(JNIEnv *env, jlong* rawAttributes, ImageLocation& location) {
|
|
// Copy attributes from location.
|
|
for (int kind = ImageLocation::ATTRIBUTE_END + 1;
|
|
kind < ImageLocation::ATTRIBUTE_COUNT;
|
|
kind++) {
|
|
rawAttributes[kind] = location.get_attribute(kind);
|
|
}
|
|
}
|
|
|
|
// Java entry for retrieving location attributes for attribute offset.
|
|
|
|
static jlong* JIMAGE_GetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// Fail if not valid reader.
|
|
if (reader == NULL) return NULL;
|
|
// Retrieve first byte address of resource's location attribute stream.
|
|
u1* data = reader->get_location_offset_data(offset);
|
|
// Fail if not valid offset.
|
|
if (data == NULL) return NULL;
|
|
// Expand stream into array.
|
|
ImageLocation location(data);
|
|
image_expand_location(env, rawAttributes, location);
|
|
return rawAttributes;
|
|
}
|
|
|
|
// Java entry for retrieving location attributes count for attribute offset.
|
|
|
|
static jsize JIMAGE_GetAttributesCount(JNIEnv *env) {
|
|
return ImageLocation::ATTRIBUTE_COUNT;
|
|
}
|
|
|
|
// Java entry for retrieving location attributes for named resource.
|
|
|
|
static jlong* JIMAGE_FindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// Fail if not valid reader.
|
|
if (reader == NULL) return NULL;
|
|
// Convert byte array to a cstring.
|
|
char* path = new char[size + 1];
|
|
if (path == NULL) {
|
|
return NULL;
|
|
}
|
|
memcpy(path, rawBytes, size);
|
|
path[size] = '\0';
|
|
// Locate resource location data.
|
|
ImageLocation location;
|
|
bool found = reader->find_location(path, location);
|
|
delete path;
|
|
// Resource not found.
|
|
if (!found) return NULL;
|
|
// Expand stream into array.
|
|
image_expand_location(env, rawAttributes, location);
|
|
return rawAttributes;
|
|
}
|
|
|
|
// Java entry for retrieving all the attribute stream offsets from an image.
|
|
|
|
static jint* JIMAGE_AttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// Fail if not valid reader.
|
|
if (reader == NULL) return NULL;
|
|
// Determine endian for reader.
|
|
Endian* endian = reader->endian();
|
|
// Get base address of attribute stream offsets table.
|
|
u4* offsets_table = reader->offsets_table();
|
|
// Allocate int array result.
|
|
// Copy values to result (converting endian.)
|
|
for (u4 i = 0; i < length; i++) {
|
|
rawOffsets[i] = endian->get(offsets_table[i]);
|
|
}
|
|
return rawOffsets;
|
|
}
|
|
|
|
// Java entry for retrieving all the attribute stream offsets length from an image.
|
|
|
|
static unsigned int JIMAGE_AttributeOffsetsLength(JNIEnv *env, jlong id) {
|
|
// Convert image ID to image reader structure.
|
|
ImageFileReader* reader = ImageFileReader::idToReader(id);
|
|
// Fail if not valid reader.
|
|
if (reader == NULL) return 0;
|
|
// Get perfect hash table length.
|
|
u4 length = reader->table_length();
|
|
return (jint) length;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
|
|
JNIEnv *env;
|
|
|
|
if (vm->GetEnv((void**) &env, JNI_VERSION_1_2) != JNI_OK) {
|
|
return JNI_EVERSION; /* JNI version not supported */
|
|
}
|
|
|
|
return JNI_VERSION_1_2;
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_openImage(JNIEnv *env,
|
|
jclass cls, jstring path, jboolean big_endian) {
|
|
const char *nativePath;
|
|
jlong ret;
|
|
|
|
nativePath = env->GetStringUTFChars(path, NULL);
|
|
ret = JIMAGE_Open(env, nativePath, big_endian);
|
|
env->ReleaseStringUTFChars(path, nativePath);
|
|
return ret;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_closeImage(JNIEnv *env,
|
|
jclass cls, jlong id) {
|
|
JIMAGE_Close(env, id);
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_getIndexAddress(JNIEnv *env,
|
|
jclass cls, jlong id) {
|
|
return JIMAGE_GetIndexAddress(env, id);
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_getDataAddress(JNIEnv *env,
|
|
jclass cls, jlong id) {
|
|
return JIMAGE_GetDataAddress(env, id);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_read(JNIEnv *env,
|
|
jclass cls, jlong id, jlong offset,
|
|
jobject uncompressedBuffer, jlong uncompressed_size) {
|
|
unsigned char* uncompressedAddress;
|
|
|
|
uncompressedAddress = (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer);
|
|
if (uncompressedAddress == NULL) {
|
|
return JNI_FALSE;
|
|
}
|
|
return JIMAGE_Read(env, id, offset, uncompressedAddress, uncompressed_size);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_readCompressed(JNIEnv *env,
|
|
jclass cls, jlong id, jlong offset,
|
|
jobject compressedBuffer, jlong compressed_size,
|
|
jobject uncompressedBuffer, jlong uncompressed_size) {
|
|
// Get address of read direct buffer.
|
|
unsigned char* compressedAddress;
|
|
unsigned char* uncompressedAddress;
|
|
|
|
compressedAddress = (unsigned char*) env->GetDirectBufferAddress(compressedBuffer);
|
|
// Get address of decompression direct buffer.
|
|
uncompressedAddress = (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer);
|
|
if (compressedAddress == NULL || uncompressedAddress == NULL) {
|
|
return JNI_FALSE;
|
|
}
|
|
return JIMAGE_ReadCompressed(env, id, offset, compressedAddress, compressed_size,
|
|
uncompressedAddress, uncompressed_size);
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_getStringBytes(JNIEnv *env,
|
|
jclass cls, jlong id, jint offset) {
|
|
const char* data;
|
|
size_t size;
|
|
jbyteArray byteArray;
|
|
jbyte* rawBytes;
|
|
|
|
data = JIMAGE_GetStringBytes(env, id, offset);
|
|
// Determine String length.
|
|
size = strlen(data);
|
|
// Allocate byte array.
|
|
byteArray = env->NewByteArray((jsize) size);
|
|
if (byteArray == NULL) {
|
|
return NULL;
|
|
}
|
|
// Get array base address.
|
|
rawBytes = env->GetByteArrayElements(byteArray, NULL);
|
|
// Copy bytes from image string table.
|
|
memcpy(rawBytes, data, size);
|
|
// Release byte array base address.
|
|
env->ReleaseByteArrayElements(byteArray, rawBytes, 0);
|
|
return byteArray;
|
|
}
|
|
|
|
JNIEXPORT jlongArray JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_getAttributes(JNIEnv *env,
|
|
jclass cls, jlong id, jint offset) {
|
|
// Allocate a jlong large enough for all location attributes.
|
|
jlongArray attributes;
|
|
jlong* rawAttributes;
|
|
jlong* ret;
|
|
|
|
attributes = env->NewLongArray(JIMAGE_GetAttributesCount(env));
|
|
if (attributes == NULL) {
|
|
return NULL;
|
|
}
|
|
// Get base address for jlong array.
|
|
rawAttributes = env->GetLongArrayElements(attributes, NULL);
|
|
ret = JIMAGE_GetAttributes(env, rawAttributes, id, offset);
|
|
// Release jlong array base address.
|
|
env->ReleaseLongArrayElements(attributes, rawAttributes, 0);
|
|
return ret == NULL ? NULL : attributes;
|
|
}
|
|
|
|
JNIEXPORT jlongArray JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_findAttributes(JNIEnv *env,
|
|
jclass cls, jlong id, jbyteArray utf8) {
|
|
// Allocate a jlong large enough for all location attributes.
|
|
jsize count;
|
|
jlongArray attributes;
|
|
jlong* rawAttributes;
|
|
jsize size;
|
|
jbyte* rawBytes;
|
|
jlong* ret;
|
|
|
|
count = JIMAGE_GetAttributesCount(env);
|
|
attributes = env->NewLongArray(JIMAGE_GetAttributesCount(env));
|
|
if (attributes == NULL) {
|
|
return NULL;
|
|
}
|
|
// Get base address for jlong array.
|
|
rawAttributes = env->GetLongArrayElements(attributes, NULL);
|
|
size = env->GetArrayLength(utf8);
|
|
rawBytes = env->GetByteArrayElements(utf8, NULL);
|
|
ret = JIMAGE_FindAttributes(env, rawAttributes, rawBytes, size, id);
|
|
env->ReleaseByteArrayElements(utf8, rawBytes, 0);
|
|
// Release jlong array base address.
|
|
env->ReleaseLongArrayElements(attributes, rawAttributes, 0);
|
|
return ret == NULL ? NULL : attributes;
|
|
|
|
}
|
|
|
|
JNIEXPORT jintArray JNICALL
|
|
Java_jdk_internal_jimage_ImageNativeSubstrate_attributeOffsets(JNIEnv *env,
|
|
jclass cls, jlong id) {
|
|
unsigned int length;
|
|
jintArray offsets;
|
|
jint* rawOffsets;
|
|
jint* ret;
|
|
|
|
length = JIMAGE_AttributeOffsetsLength(env, id);
|
|
offsets = env->NewIntArray(length);
|
|
if (offsets == NULL) {
|
|
return NULL;
|
|
}
|
|
// Get base address of result.
|
|
rawOffsets = env->GetIntArrayElements(offsets, NULL);
|
|
ret = JIMAGE_AttributeOffsets(env, rawOffsets, length, id);
|
|
if (length == 0) {
|
|
return NULL;
|
|
}
|
|
// Release result base address.
|
|
env->ReleaseIntArrayElements(offsets, rawOffsets, 0);
|
|
return ret == NULL ? NULL : offsets;
|
|
}
|
|
|
|
/*
|
|
* Class: jdk_internal_jimage_ImageNativeSubstrate
|
|
* Method: JIMAGE_open
|
|
* Signature: (Ljava/lang/String;)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Open
|
|
(JNIEnv *env, jclass, jstring path) {
|
|
const char *nativePath = env->GetStringUTFChars(path, NULL);
|
|
if (nativePath == NULL)
|
|
return 0; // Exception already thrown
|
|
jint error;
|
|
jlong ret = (jlong) JIMAGE_Open(nativePath, &error);
|
|
env->ReleaseStringUTFChars(path, nativePath);
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Class: jdk_internal_jimage_ImageNativeSubstrate
|
|
* Method: JIMAGE_Close
|
|
* Signature: (J)J
|
|
*/
|
|
JNIEXPORT void JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Close
|
|
(JNIEnv *env, jclass, jlong jimageHandle) {
|
|
JIMAGE_Close((JImageFile*) jimageHandle);
|
|
}
|
|
|
|
/*
|
|
* Class: jdk_internal_jimage_ImageNativeSubstrate
|
|
* Method: JIMAGE_FindResource
|
|
* Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[J)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1FindResource
|
|
(JNIEnv *env, jclass, jlong jimageHandle, jstring moduleName,
|
|
jstring version, jstring path, jlongArray output_size) {
|
|
const char *native_module = NULL;
|
|
const char *native_version = NULL;
|
|
const char *native_path = NULL;
|
|
jlong * native_array = NULL;
|
|
jlong size = 0;
|
|
jlong ret = 0;
|
|
|
|
if (moduleName == NULL) {
|
|
ThrowByName(env, "java/lang/NullPointerException", "moduleName");
|
|
return 0;
|
|
}
|
|
if (version == NULL) {
|
|
ThrowByName(env, "java/lang/NullPointerException", "version");
|
|
return 0;
|
|
}
|
|
if (path == NULL) {
|
|
ThrowByName(env, "java/lang/NullPointerException", "path");
|
|
return 0;
|
|
}
|
|
if (output_size == NULL) {
|
|
ThrowByName(env, "java/lang/NullPointerException", "size");
|
|
return 0;
|
|
}
|
|
|
|
do {
|
|
native_module = env->GetStringUTFChars(moduleName, NULL);
|
|
if (native_module == NULL)
|
|
break;
|
|
native_version = env->GetStringUTFChars(version, NULL);
|
|
if (native_version == NULL)
|
|
break;
|
|
native_path = env->GetStringUTFChars(path, NULL);
|
|
if (native_path == NULL)
|
|
break;
|
|
if (env->GetArrayLength(output_size) < 1)
|
|
break;
|
|
// Get base address for jlong array.
|
|
native_array = env->GetLongArrayElements(output_size, NULL);
|
|
if (native_array == NULL)
|
|
break;
|
|
|
|
ret = (jlong) JIMAGE_FindResource((JImageFile *) jimageHandle,
|
|
native_module, native_version, native_path, &size);
|
|
if (ret != 0)
|
|
*native_array = size;
|
|
} while (0);
|
|
|
|
if (native_array != NULL)
|
|
env->ReleaseLongArrayElements(output_size, native_array, 0);
|
|
if (native_path != NULL)
|
|
env->ReleaseStringUTFChars(path, native_path);
|
|
if (native_version != NULL)
|
|
env->ReleaseStringUTFChars(path, native_version);
|
|
if (native_module != NULL)
|
|
env->ReleaseStringUTFChars(path, native_module);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Class: jdk_internal_jimage_ImageNativeSubstrate
|
|
* Method: JIMAGE_GetResource
|
|
* Signature: (JJ[BJ)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1GetResource
|
|
(JNIEnv *env, jclass, jlong jimageHandle, jlong jlocationHandle, jbyteArray buffer, jlong size) {
|
|
jbyte * native_buffer = NULL;
|
|
jlong actual_size = 0;
|
|
do {
|
|
if (env->GetArrayLength(buffer) < size)
|
|
break;
|
|
|
|
native_buffer = env->GetByteArrayElements(buffer, NULL);
|
|
if (native_buffer == NULL)
|
|
break;
|
|
|
|
actual_size = JIMAGE_GetResource((JImageFile*) jimageHandle,
|
|
(JImageLocationRef) jlocationHandle,
|
|
(char *) native_buffer, size);
|
|
} while (0);
|
|
// Release byte array
|
|
if (native_buffer != NULL)
|
|
env->ReleaseByteArrayElements(buffer, native_buffer, 0);
|
|
|
|
return actual_size;
|
|
}
|
|
|
|
// Structure passed from iterator to a visitor to accumulate the results
|
|
|
|
struct VisitorData {
|
|
JNIEnv *env;
|
|
int size; // current number of strings
|
|
int max; // Maximum number of strings
|
|
jobjectArray array; // String array to store the strings
|
|
};
|
|
|
|
// Visitor to accumulate fully qualified resource names
|
|
|
|
static bool resourceVisitor(JImageFile* image,
|
|
const char* module, const char* version, const char* package,
|
|
const char* name, const char* extension, void* arg) {
|
|
struct VisitorData *vdata = (struct VisitorData *) arg;
|
|
JNIEnv* env = vdata->env;
|
|
if (vdata->size < vdata->max) {
|
|
// Store if there is room in the array
|
|
// Concatenate to get full path
|
|
char fullpath[IMAGE_MAX_PATH];
|
|
size_t moduleLen = strlen(module);
|
|
size_t packageLen = strlen(package);
|
|
size_t nameLen = strlen(name);
|
|
size_t extLen = strlen(extension);
|
|
size_t index;
|
|
|
|
if (1 + moduleLen + 1 + packageLen + 1 + nameLen + 1 + extLen + 1 > IMAGE_MAX_PATH) {
|
|
ThrowByName(env, "java/lang/InternalError", "concatenated name too long");
|
|
return true;
|
|
}
|
|
|
|
index = 0;
|
|
if (moduleLen > 0) {
|
|
fullpath[index++] = '/';
|
|
memcpy(&fullpath[index], module, moduleLen);
|
|
index += moduleLen;
|
|
fullpath[index++] = '/';
|
|
}
|
|
if (packageLen > 0) {
|
|
memcpy(&fullpath[index], package, packageLen);
|
|
index += packageLen;
|
|
fullpath[index++] = '/';
|
|
}
|
|
memcpy(&fullpath[index], name, nameLen);
|
|
index += nameLen;
|
|
if (extLen > 0) {
|
|
fullpath[index++] = '.';
|
|
memcpy(&fullpath[index], extension, extLen);
|
|
index += extLen;
|
|
}
|
|
fullpath[index++] = '\0';
|
|
|
|
jobject str = env->NewStringUTF(fullpath);
|
|
if (env->ExceptionCheck()) {
|
|
return true;
|
|
}
|
|
|
|
env->SetObjectArrayElement(vdata->array, vdata->size, str);
|
|
if (env->ExceptionCheck()) {
|
|
return true;
|
|
}
|
|
}
|
|
vdata->size++; // always count so the total size is returned
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Class: jdk_internal_jimage_ImageNativeSubstrate
|
|
* Method: JIMAGE_Resources
|
|
* Signature: (J)V
|
|
*/
|
|
JNIEXPORT jint JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Resources
|
|
(JNIEnv *env, jclass, jlong jimageHandle,
|
|
jobjectArray outputNames) {
|
|
struct VisitorData vdata;
|
|
vdata.env = env;
|
|
vdata.max = 0;
|
|
vdata.size = 0;
|
|
vdata.array = outputNames;
|
|
|
|
vdata.max = (outputNames != NULL) ? env->GetArrayLength(outputNames) : 0;
|
|
JIMAGE_ResourceIterator((JImageFile*) jimageHandle, &resourceVisitor, &vdata);
|
|
return vdata.size;
|
|
}
|
|
|
|
/*
|
|
* Class: jdk_internal_jimage_ImageNativeSubstrate
|
|
* Method: JIMAGE_PackageToModule
|
|
* Signature: (JLjava/lang/String;)Ljava/lang/String;
|
|
*/
|
|
JNIEXPORT jstring JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1PackageToModule
|
|
(JNIEnv *env, jclass, jlong jimageHandle, jstring package_name) {
|
|
const char *native_package = NULL;
|
|
const char *native_module = NULL;
|
|
jstring module = NULL;
|
|
|
|
native_package = env->GetStringUTFChars(package_name, NULL);
|
|
if (env->ExceptionCheck()) {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
native_module = JIMAGE_PackageToModule((JImageFile*) jimageHandle, native_package);
|
|
if (native_module != NULL) {
|
|
module = env->NewStringUTF(native_module);
|
|
}
|
|
env->ReleaseStringUTFChars(package_name, native_package);
|
|
return module;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved) {
|
|
ImageDecompressor::image_decompressor_close();
|
|
}
|