7142921: (fs) Files.probeContentType reports a MIME type of "text/plain" on Ubuntu 11.04
7144997: (fs) Files.probeContentType returns null on Solaris 64-bit
Reviewed-by: alanb, mduigou
--- a/jdk/make/java/nio/Makefile Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/make/java/nio/Makefile Tue Dec 04 14:07:30 2012 +0000
@@ -69,6 +69,7 @@
sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
\
sun/nio/fs/GnomeFileTypeDetector.java \
+ sun/nio/fs/MimeTypesFileTypeDetector.java \
sun/nio/fs/PollingWatchService.java \
sun/nio/fs/SolarisAclFileAttributeView.java \
sun/nio/fs/SolarisFileStore.java \
@@ -202,6 +203,8 @@
sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
\
sun/nio/fs/GnomeFileTypeDetector.java \
+ sun/nio/fs/MagicFileTypeDetector.java \
+ sun/nio/fs/MimeTypesFileTypeDetector.java \
sun/nio/fs/LinuxDosFileAttributeView.java \
sun/nio/fs/LinuxFileStore.java \
sun/nio/fs/LinuxFileSystem.java \
@@ -239,6 +242,7 @@
UnixAsynchronousSocketChannelImpl.c \
\
GnomeFileTypeDetector.c \
+ MagicFileTypeDetector.c \
LinuxNativeDispatcher.c \
LinuxWatchService.c \
UnixCopyFile.c \
@@ -254,6 +258,7 @@
sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
\
sun/nio/fs/GnomeFileTypeDetector.java \
+ sun/nio/fs/MagicFileTypeDetector.java \
sun/nio/fs/LinuxNativeDispatcher.java \
sun/nio/fs/LinuxWatchService.java \
sun/nio/fs/UnixCopyFile.java \
@@ -277,6 +282,7 @@
sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java \
sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
\
+ sun/nio/fs/MimeTypesFileTypeDetector.java \
sun/nio/fs/BsdFileStore.java \
sun/nio/fs/BsdFileSystem.java \
sun/nio/fs/BsdFileSystemProvider.java \
--- a/jdk/make/java/nio/mapfile-linux Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/make/java/nio/mapfile-linux Tue Dec 04 14:07:30 2012 +0000
@@ -130,6 +130,8 @@
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
+ Java_sun_nio_fs_MagicFileTypeDetector_initialize0;
+ Java_sun_nio_fs_MagicFileTypeDetector_probe0;
Java_sun_nio_fs_LinuxWatchService_eventSize;
Java_sun_nio_fs_LinuxWatchService_eventOffsets;
Java_sun_nio_fs_LinuxWatchService_inotifyInit;
--- a/jdk/makefiles/CompileJavaClasses.gmk Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/makefiles/CompileJavaClasses.gmk Tue Dec 04 14:07:30 2012 +0000
@@ -121,6 +121,7 @@
sun/nio/fs/LinuxFileStore.java \
sun/nio/fs/LinuxFileSystem.java \
sun/nio/fs/LinuxFileSystemProvider.java \
+ sun/nio/fs/MagicFileTypeDetector.java \
sun/nio/fs/LinuxNativeDispatcher.java \
sun/nio/fs/LinuxUserDefinedFileAttributeView.java \
sun/nio/fs/LinuxWatchService.java
--- a/jdk/makefiles/CompileNativeLibraries.gmk Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/makefiles/CompileNativeLibraries.gmk Tue Dec 04 14:07:30 2012 +0000
@@ -1897,6 +1897,7 @@
UnixAsynchronousServerSocketChannelImpl.c \
UnixAsynchronousSocketChannelImpl.c \
GnomeFileTypeDetector.c \
+ MagicFileTypeDetector.c \
LinuxNativeDispatcher.c \
LinuxWatchService.c \
UnixCopyFile.c \
--- a/jdk/makefiles/mapfiles/libnio/mapfile-linux Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/makefiles/mapfiles/libnio/mapfile-linux Tue Dec 04 14:07:30 2012 +0000
@@ -130,6 +130,8 @@
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
+ Java_sun_nio_fs_MagicFileTypeDetector_initialize0;
+ Java_sun_nio_fs_MagicFileTypeDetector_probe0;
Java_sun_nio_fs_LinuxWatchService_eventSize;
Java_sun_nio_fs_LinuxWatchService_eventOffsets;
Java_sun_nio_fs_LinuxWatchService_inotifyInit;
--- a/jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Tue Dec 04 14:07:30 2012 +0000
@@ -25,8 +25,6 @@
package sun.nio.fs;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.io.IOException;
/**
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Tue Dec 04 14:07:30 2012 +0000
@@ -29,6 +29,8 @@
import java.nio.file.attribute.*;
import java.nio.file.spi.FileTypeDetector;
import java.io.IOException;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
/**
* Linux implementation of FileSystemProvider
@@ -100,6 +102,13 @@
@Override
FileTypeDetector getFileTypeDetector() {
- return new GnomeFileTypeDetector();
+ Path userMimeTypes = Paths.get(AccessController.doPrivileged(
+ new GetPropertyAction("user.home")), ".mime.types");
+ Path etcMimeTypes = Paths.get("/etc/mime.types");
+
+ return chain(new GnomeFileTypeDetector(),
+ new MimeTypesFileTypeDetector(userMimeTypes),
+ new MimeTypesFileTypeDetector(etcMimeTypes),
+ new MagicFileTypeDetector());
}
}
--- a/jdk/src/solaris/classes/sun/nio/fs/MacOSXFileSystemProvider.java Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/src/solaris/classes/sun/nio/fs/MacOSXFileSystemProvider.java Tue Dec 04 14:07:30 2012 +0000
@@ -25,9 +25,11 @@
package sun.nio.fs;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.spi.FileTypeDetector;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
/**
* MacOSX implementation of FileSystemProvider
@@ -42,4 +44,11 @@
MacOSXFileSystem newFileSystem(String dir) {
return new MacOSXFileSystem(this, dir);
}
+
+ @Override
+ FileTypeDetector getFileTypeDetector() {
+ Path userMimeTypes = Paths.get(AccessController.doPrivileged(
+ new GetPropertyAction("user.home")), ".mime.types");
+ return new MimeTypesFileTypeDetector(userMimeTypes);
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/fs/MagicFileTypeDetector.java Tue Dec 04 14:07:30 2012 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 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 sun.nio.fs;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * File type detector that uses the libmagic to guess the MIME type of a file.
+ */
+
+class MagicFileTypeDetector extends AbstractFileTypeDetector {
+
+ private static final String UNKNOW_MIME_TYPE = "application/octet-stream";
+
+ // true if libmagic is available and successfully loaded
+ private final boolean libmagicAvailable;
+
+ public MagicFileTypeDetector() {
+ libmagicAvailable = initialize0();
+ }
+
+ @Override
+ protected String implProbeContentType(Path obj) throws IOException {
+ if (!libmagicAvailable || !(obj instanceof UnixPath))
+ return null;
+
+ UnixPath path = (UnixPath) obj;
+ path.checkRead();
+
+ NativeBuffer buffer = NativeBuffers.asNativeBuffer(path.getByteArrayForSysCalls());
+ try {
+ byte[] type = probe0(buffer.address());
+ String mimeType = (type == null) ? null : new String(type);
+ return UNKNOW_MIME_TYPE.equals(mimeType) ? null : mimeType;
+ } finally {
+ buffer.release();
+ }
+ }
+
+ private static native boolean initialize0();
+
+ private static native byte[] probe0(long pathAddress);
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ System.loadLibrary("nio");
+ return null;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/fs/MimeTypesFileTypeDetector.java Tue Dec 04 14:07:30 2012 +0000
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2012, 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 sun.nio.fs;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * File type detector that uses a file extension to look up its MIME type
+ * based on a mime.types file.
+ */
+
+class MimeTypesFileTypeDetector extends AbstractFileTypeDetector {
+
+ // path to mime.types file
+ private final Path mimeTypesFile;
+
+ // map of extension to MIME type
+ private Map<String,String> mimeTypeMap;
+
+ // set to true when file loaded
+ private volatile boolean loaded = false;
+
+ public MimeTypesFileTypeDetector(Path filePath) {
+ mimeTypesFile = filePath;
+ }
+
+ @Override
+ protected String implProbeContentType(Path path) {
+ Path fn = path.getFileName();
+ if (fn == null)
+ return null; // no file name
+
+ String ext = getExtension(fn.toString());
+ if (ext.isEmpty())
+ return null; // no extension
+
+ loadMimeTypes();
+ if (mimeTypeMap == null || mimeTypeMap.isEmpty())
+ return null;
+
+ // Case-sensitive search
+ String mimeType;
+ do {
+ mimeType = mimeTypeMap.get(ext);
+ if (mimeType == null)
+ ext = getExtension(ext);
+ } while (mimeType == null && !ext.isEmpty());
+
+ return mimeType;
+ }
+
+ // Get the extension of a file name.
+ private static String getExtension(String name) {
+ String ext = "";
+ if (name != null && !name.isEmpty()) {
+ int dot = name.indexOf('.');
+ if ((dot >= 0) && (dot < name.length() - 1)) {
+ ext = name.substring(dot + 1);
+ }
+ }
+ return ext;
+ }
+
+ /**
+ * Parse the mime types file, and store the type-extension mappings into
+ * mimeTypeMap. The mime types file is not loaded until the first probe
+ * to achieve the lazy initialization. It adopts double-checked locking
+ * optimization to reduce the locking overhead.
+ */
+ private void loadMimeTypes() {
+ if (!loaded) {
+ synchronized (this) {
+ if (!loaded) {
+ List<String> lines = AccessController.doPrivileged(
+ new PrivilegedAction<List<String>>() {
+ @Override
+ public List<String> run() {
+ try {
+ return Files.readAllLines(mimeTypesFile,
+ Charset.defaultCharset());
+ } catch (IOException ignore) {
+ return Collections.emptyList();
+ }
+ }
+ });
+
+ mimeTypeMap = new HashMap<>(lines.size());
+ String entry = "";
+ for (String line : lines) {
+ entry += line;
+ if (entry.endsWith("\\")) {
+ entry = entry.substring(0, entry.length() - 1);
+ continue;
+ }
+ parseMimeEntry(entry);
+ entry = "";
+ }
+ if (!entry.isEmpty()) {
+ parseMimeEntry(entry);
+ }
+ loaded = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Parse a mime-types entry, which can have the following formats.
+ * 1) Simple space-delimited format
+ * image/jpeg jpeg jpg jpe JPG
+ *
+ * 2) Netscape key-value pair format
+ * type=application/x-java-jnlp-file desc="Java Web Start" exts="jnlp"
+ * or
+ * type=text/html exts=htm,html
+ */
+ private void parseMimeEntry(String entry) {
+ entry = entry.trim();
+ if (entry.isEmpty() || entry.charAt(0) == '#')
+ return;
+
+ entry = entry.replaceAll("\\s*#.*", "");
+ int equalIdx = entry.indexOf('=');
+ if (equalIdx > 0) {
+ // Parse a mime-types command having the key-value pair format
+ final String TYPEEQUAL = "type=";
+ String typeRegex = "\\b" + TYPEEQUAL +
+ "(\"\\p{Graph}+?/\\p{Graph}+?\"|\\p{Graph}+/\\p{Graph}+\\b)";
+ Pattern typePattern = Pattern.compile(typeRegex);
+ Matcher typeMatcher = typePattern.matcher(entry);
+
+ if (typeMatcher.find()) {
+ String type = typeMatcher.group().substring(TYPEEQUAL.length());
+ if (type.charAt(0) == '"') {
+ type = type.substring(1, type.length() - 1);
+ }
+
+ final String EXTEQUAL = "exts=";
+ String extRegex = "\\b" + EXTEQUAL +
+ "(\"[\\p{Graph}|\\p{Blank}]+?\"|\\p{Graph}+\\b)";
+ Pattern extPattern = Pattern.compile(extRegex);
+ Matcher extMatcher = extPattern.matcher(entry);
+
+ if (extMatcher.find()) {
+ String exts =
+ extMatcher.group().substring(EXTEQUAL.length());
+ if (exts.charAt(0) == '"') {
+ exts = exts.substring(1, exts.length() - 1);
+ }
+ String[] extList = exts.split("[\\p{Blank}|\\p{Punct}]+");
+ for (String ext : extList) {
+ putIfAbsent(ext, type);
+ }
+ }
+ }
+ } else {
+ // Parse a mime-types command having the space-delimited format
+ String[] elements = entry.split("\\s+");
+ int i = 1;
+ while (i < elements.length) {
+ putIfAbsent(elements[i++], elements[0]);
+ }
+ }
+ }
+
+ private void putIfAbsent(String key, String value) {
+ if (key != null && !key.isEmpty() &&
+ value != null && !value.isEmpty() &&
+ !mimeTypeMap.containsKey(key))
+ {
+ mimeTypeMap.put(key, value);
+ }
+ }
+}
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Tue Dec 04 14:07:30 2012 +0000
@@ -29,6 +29,8 @@
import java.nio.file.attribute.*;
import java.nio.file.spi.FileTypeDetector;
import java.io.IOException;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
/**
* Solaris implementation of FileSystemProvider
@@ -83,6 +85,12 @@
@Override
FileTypeDetector getFileTypeDetector() {
- return new GnomeFileTypeDetector();
+ Path userMimeTypes = Paths.get(AccessController.doPrivileged(
+ new GetPropertyAction("user.home")), ".mime.types");
+ Path etcMimeTypes = Paths.get("/etc/mime.types");
+
+ return chain(new GnomeFileTypeDetector(),
+ new MimeTypesFileTypeDetector(userMimeTypes),
+ new MimeTypesFileTypeDetector(etcMimeTypes));
}
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Mon Dec 03 11:07:20 2012 -0500
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Tue Dec 04 14:07:30 2012 +0000
@@ -509,4 +509,24 @@
};
}
+ /**
+ * Returns a {@code FileTypeDetector} that chains the given array of file
+ * type detectors. When the {@code implProbeContentType} method is invoked
+ * then each of the detectors is invoked in turn, the result from the
+ * first to detect the file type is returned.
+ */
+ final FileTypeDetector chain(final AbstractFileTypeDetector... detectors) {
+ return new AbstractFileTypeDetector() {
+ @Override
+ protected String implProbeContentType(Path file) throws IOException {
+ for (AbstractFileTypeDetector detector : detectors) {
+ String result = detector.implProbeContentType(file);
+ if (result != null && !result.isEmpty()) {
+ return result;
+ }
+ }
+ return null;
+ }
+ };
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Tue Dec 04 14:07:30 2012 +0000
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, 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 "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+
+#include <dlfcn.h>
+#include <string.h>
+
+#define MAGIC_MIME_TYPE 0x000010 /* Return the MIME type */
+
+typedef struct magic_set magic_t;
+
+typedef magic_t* (*magic_open_func)(int flags);
+typedef int (*magic_load_func)(magic_t* cookie, const char* filename);
+typedef const char* (*magic_file_func)(magic_t* cookie, const char* filename);
+typedef void (*magic_close_func)(magic_t* cookie);
+
+static void* magic_handle;
+static magic_open_func magic_open;
+static magic_load_func magic_load;
+static magic_file_func magic_file;
+static magic_close_func magic_close;
+
+#include "sun_nio_fs_MagicFileTypeDetector.h"
+
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_fs_MagicFileTypeDetector_initialize0
+ (JNIEnv* env, jclass this)
+{
+ magic_handle = dlopen("libmagic.so", RTLD_LAZY);
+ if (magic_handle == NULL) {
+ magic_handle = dlopen("libmagic.so.1", RTLD_LAZY);
+ if (magic_handle == NULL) {
+ return JNI_FALSE;
+ }
+ }
+
+ magic_open = (magic_open_func)dlsym(magic_handle, "magic_open");
+
+ magic_load = (magic_load_func)dlsym(magic_handle, "magic_load");
+
+ magic_file = (magic_file_func)dlsym(magic_handle, "magic_file");
+
+ magic_close = (magic_close_func)dlsym(magic_handle, "magic_close");
+
+ if (magic_open == NULL ||
+ magic_load == NULL ||
+ magic_file == NULL ||
+ magic_close == NULL)
+ {
+ dlclose(magic_handle);
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_MagicFileTypeDetector_probe0
+ (JNIEnv* env, jclass this, jlong pathAddress)
+{
+ char* path = (char*)jlong_to_ptr(pathAddress);
+ magic_t* cookie;
+ jbyteArray result = NULL;
+
+ cookie = (*magic_open)(MAGIC_MIME_TYPE);
+
+ if (cookie != NULL) {
+ if ((*magic_load)(cookie, NULL) != -1) {
+ const char* type = (*magic_file)(cookie, path);
+ if (type != NULL) {
+ jsize len = strlen(type);
+ result = (*env)->NewByteArray(env, len);
+ if (result != NULL) {
+ (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)type);
+ }
+ }
+ }
+ (*magic_close)(cookie);
+ }
+
+ return result;
+}