diff options
| author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-16 00:30:23 +0000 |
|---|---|---|
| committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-16 00:30:23 +0000 |
| commit | c8875fb97fc03779a5bba09872227b1d08e5d52a (patch) | |
| tree | a0b991cf5866ae1d616639b906ac001811d74508 /libjava/classpath/native/jni/java-nio | |
| parent | c40c1730800ed292b6db39a83d592476fa59623c (diff) | |
| download | ppe42-gcc-c8875fb97fc03779a5bba09872227b1d08e5d52a.tar.gz ppe42-gcc-c8875fb97fc03779a5bba09872227b1d08e5d52a.zip | |
Initial revision
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102074 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/native/jni/java-nio')
10 files changed, 2234 insertions, 0 deletions
diff --git a/libjava/classpath/native/jni/java-nio/.cvsignore b/libjava/classpath/native/jni/java-nio/.cvsignore new file mode 100644 index 00000000000..e9f2658a694 --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/.cvsignore @@ -0,0 +1,8 @@ +*.o +*.a +*.lo +*.la +.libs +.deps +Makefile +Makefile.in diff --git a/libjava/classpath/native/jni/java-nio/Makefile.am b/libjava/classpath/native/jni/java-nio/Makefile.am new file mode 100644 index 00000000000..9785fee6d9b --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/Makefile.am @@ -0,0 +1,16 @@ +pkglib_LTLIBRARIES = libjavanio.la + +libjavanio_la_SOURCES = gnu_java_nio_VMPipe.c \ + gnu_java_nio_VMSelector.c \ + gnu_java_nio_channels_FileChannelImpl.c \ + gnu_java_nio_charset_iconv_IconvDecoder.c \ + gnu_java_nio_charset_iconv_IconvEncoder.c \ + java_nio_MappedByteBufferImpl.c \ + java_nio_VMDirectByteBuffer.c + +libjavanio_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \ + $(LTLIBICONV) + +AM_LDFLAGS = @CLASSPATH_MODULE@ +AM_CPPFLAGS = @CLASSPATH_INCLUDES@ +AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@ diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c new file mode 100644 index 00000000000..369c5a3d650 --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c @@ -0,0 +1,56 @@ +/* gnu_java_nio_VMPipe.c - Native methods for PipeImpl class + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include <config.h> +#include <errno.h> + +#include <jni.h> +#include <jcl.h> + +#include "gnu_java_nio_VMPipe.h" + +#define IO_EXCEPTION "java/io/IOException" + +JNIEXPORT void JNICALL +Java_gnu_java_nio_VMPipe_init (JNIEnv * env, + jclass cls __attribute__ ((__unused__)), + jobject self __attribute__ ((__unused__)), + jobject provider __attribute__ ((__unused__))) +{ + JCL_ThrowException (env, IO_EXCEPTION, + "gnu.java.nio.VMPipe.init(): not implemented"); +} diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c new file mode 100644 index 00000000000..f8a40aa7a15 --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c @@ -0,0 +1,296 @@ +/* gnu_java_nio_VMSelector.c - Native methods for SelectorImpl class + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include "config.h" + +/* <sys/types.h> needs to be included on OSX before <sys/select.h> */ +#if defined(HAVE_SYS_TYPES_H) +#include <sys/types.h> +#endif + +#include <sys/select.h> +#include <sys/time.h> + +#include <string.h> + +#include <errno.h> + +#include <jni.h> +#include <jcl.h> + +#include "gnu_java_nio_VMSelector.h" + +/* Amount of characters in the error message buffer for strerror_r. */ +#define BUF_SIZE 250 + +void helper_put_filedescriptors (JNIEnv *, jintArray, fd_set *, int *); + +void helper_get_filedescriptors (JNIEnv *, jintArray *, fd_set *); + +void helper_reset (JNIEnv *, jintArray *); + +int +helper_select (JNIEnv *, jclass, jmethodID, + int, fd_set *, fd_set *, fd_set *, struct timeval *); + +void +helper_put_filedescriptors (JNIEnv * env, jintArray fdArray, fd_set * fds, + int *max_fd) +{ + jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0); + int size = (*env)->GetArrayLength (env, fdArray); + int index, fd; + + for (index = 0; index < size; index++) + { + fd = tmpFDArray[index]; + + if (fd > 0) + { + FD_SET (tmpFDArray[index], fds); + + if (tmpFDArray[index] > (*max_fd)) + (*max_fd) = tmpFDArray[index]; + } + } +} + +void +helper_get_filedescriptors (JNIEnv * env, jintArray * fdArray, fd_set * fds) +{ + jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0); + int size = (*env)->GetArrayLength (env, fdArray); + int index, fd; + + for (index = 0; index < size; index++) + { + fd = tmpFDArray[index]; + if (fd < 0 || !FD_ISSET (fd, fds)) + tmpFDArray[index] = 0; + } +} + +void +helper_reset (JNIEnv * env, jintArray * fdArray) +{ + jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0); + int size = (*env)->GetArrayLength (env, fdArray); + int index; + + for (index = 0; index < size; index++) + tmpFDArray[index] = 0; +} + +/* A wrapper for select() which ignores EINTR. + * Taken from gclib's posix.cc + */ +int +helper_select (JNIEnv * env, jclass thread_class, + jmethodID thread_interrupted, int n, fd_set * readfds, + fd_set * writefds, fd_set * exceptfds, struct timeval *timeout) +{ +#ifdef HAVE_SYS_SELECT_H + /* If we have a timeout, compute the absolute ending time. */ + struct timeval end, delay, after; + int r; + + if (timeout) + { + gettimeofday (&end, NULL); + + end.tv_usec += timeout->tv_usec; + + if (end.tv_usec >= 1000000) + { + ++end.tv_sec; + end.tv_usec -= 1000000; + } + + end.tv_sec += timeout->tv_sec; + delay = *timeout; + } + else + { + /* Placate compiler. */ + delay.tv_sec = delay.tv_usec = 0; + } + + while (1) + { + r = select (n, readfds, writefds, exceptfds, timeout ? &delay : NULL); + + if (r < 0 && errno != EINTR) + return -errno; + else if (r >= 0) + return r; + + /* Here we know we got EINTR. */ + if ((*env)-> + CallStaticBooleanMethod (env, thread_class, thread_interrupted)) + { + return -EINTR; + } + + if (timeout) + { + gettimeofday (&after, NULL); + + /* Now compute new timeout argument. */ + delay.tv_usec = end.tv_usec - after.tv_usec; + delay.tv_sec = end.tv_sec - after.tv_sec; + + if (delay.tv_usec < 0) + { + --delay.tv_sec; + delay.tv_usec += 1000000; + } + + if (delay.tv_sec < 0) + { + /* We assume that the user wants a valid select() call + * more than precise timing. So if we get a series of + * EINTR we just keep trying with delay 0 until we get a + * valid result. + */ + delay.tv_sec = 0; + } + } + } +#else /* HAVE_SYS_SELECT_H */ + return 0; +#endif + +} + +JNIEXPORT jint JNICALL +Java_gnu_java_nio_VMSelector_select (JNIEnv * env, + jclass obj __attribute__ ((__unused__)), + jintArray read, + jintArray write, + jintArray except, jlong timeout) +{ + jint result; + jclass thread_class = (*env)->FindClass (env, "java/lang/Thread"); + jmethodID thread_current_thread = + (*env)->GetStaticMethodID (env, thread_class, "currentThread", + "()Ljava/lang/Thread;"); + jmethodID thread_interrupt = + (*env)->GetMethodID (env, thread_class, "interrupt", "()V"); + jmethodID thread_interrupted = + (*env)->GetStaticMethodID (env, thread_class, "interrupted", "()Z"); + jobject current_thread; + int max_fd = 0; + fd_set read_fds; + fd_set write_fds; + fd_set except_fds; + struct timeval real_time_data; + struct timeval *time_data = NULL; + char message_buf[BUF_SIZE + 1]; + + /* If a legal timeout value isn't given, use NULL. + * This means an infinite timeout. The specification + * also says that a zero timeout should be treated + * as infinite. Otherwise (if the timeout value is legal), + * fill our timeval struct and use it for the select. + */ + if (timeout > 0) + { + real_time_data.tv_sec = timeout / 1000; + real_time_data.tv_usec = (timeout % 1000) * 1000; + time_data = &real_time_data; + } + + /* Reset all fd_set structures */ + FD_ZERO (&read_fds); + FD_ZERO (&write_fds); + FD_ZERO (&except_fds); + + /* Fill the fd_set data structures for the _Jv_select() call. */ + helper_put_filedescriptors (env, read, &read_fds, &max_fd); + helper_put_filedescriptors (env, write, &write_fds, &max_fd); + helper_put_filedescriptors (env, except, &except_fds, &max_fd); + + /* Actually do the select */ + result = + helper_select (env, thread_class, thread_interrupted, max_fd + 1, + &read_fds, &write_fds, &except_fds, time_data); + + if (result == -EINTR) + { + /* The behavior of JRE 1.4.1 is that no exception is thrown + * when the thread is interrupted, but the thread's interrupt + * status is set. Clear all of our select sets and return 0, + * indicating that nothing was selected. + */ + current_thread = + (*env)->CallStaticObjectMethod (env, thread_class, + thread_current_thread); + (*env)->CallVoidMethod (env, current_thread, thread_interrupt); + + helper_reset (env, read); + helper_reset (env, write); + helper_reset (env, except); + + return 0; + } + + if (result < 0) + { + + int errorcode = -result; + + if (strerror_r (errorcode, message_buf, BUF_SIZE)) + { + /* This would mean that message_buf was to small + * to hold the error message. + */ + JCL_ThrowException (env, "java/lang/InternalError", + "Not enough space in message buffer."); + return 0; + } + + JCL_ThrowException (env, "java/io/IOException", message_buf); + return 0; + } + + /* Set the file descriptors according to the values returned from select(). */ + helper_get_filedescriptors (env, read, &read_fds); + helper_get_filedescriptors (env, write, &write_fds); + helper_get_filedescriptors (env, except, &except_fds); + + return result; +} diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c new file mode 100644 index 00000000000..743e12a8f30 --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c @@ -0,0 +1,793 @@ +/* gnu_java_nio_channels_FileChannelImpl.c - + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* do not move; needed here because of some macro definitions */ +#include <config.h> + +#include <stdlib.h> +#include <errno.h> + +#include <jni.h> +#include <jcl.h> + +#include "target_native.h" +#ifndef WITHOUT_FILESYSTEM +#include "target_native_file.h" +#endif +#include "target_native_math_int.h" + +#include "gnu_java_nio_channels_FileChannelImpl.h" + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif /* HAVE_FCNTL_H */ + +/* These values must be kept in sync with FileChannelImpl.java. */ +#define FILECHANNELIMPL_READ 1 +#define FILECHANNELIMPL_WRITE 2 +#define FILECHANNELIMPL_APPEND 4 + +/* These values must be kept in sync with FileChannelImpl.java. */ +/* #define FILECHANNELIMPL_FILESEEK_SET 0 */ +/* #define FILECHANNELIMPL_FILESEEK_CUR 1 */ +/* #define FILECHANNELIMPL_FILESEEK_END 2 */ + +#define FILECHANNELIMPL_FILEOPEN_FLAG_READ 1 +#define FILECHANNELIMPL_FILEOPEN_FLAG_WRITE 2 +#define FILECHANNELIMPL_FILEOPEN_FLAG_APPEND 4 +#define FILECHANNELIMPL_FILEOPEN_FLAG_EXCL 8 +#define FILECHANNELIMPL_FILEOPEN_FLAG_SYNC 16 +#define FILECHANNELIMPL_FILEOPEN_FLAG_DSYNC 32 + +#define IO_EXCEPTION "java/io/IOException" + +/* FIXME: This can't be right. Need converter macros. */ +#define CONVERT_JLONG_TO_INT(x) TARGET_NATIVE_MATH_INT_INT64_TO_INT32(x) +#define CONVERT_INT_TO_JLONG(x) TARGET_NATIVE_MATH_INT_INT32_TO_INT64(x) + +/* FIXME: This can't be right. Need converter macros. */ +#define CONVERT_JLONG_TO_OFF_T(x) TARGET_NATIVE_MATH_INT_INT64_TO_INT32(x) +#define CONVERT_OFF_T_TO_JLONG(x) TARGET_NATIVE_MATH_INT_INT32_TO_INT64(x) + +/* FIXME: This can't be right. Need converter macros */ +#define CONVERT_JINT_TO_INT(x) ((int)(x & 0xFFFFFFFF)) +#define CONVERT_INT_TO_JINT(x) ((int)(x & 0xFFFFFFFF)) + +/* FIXME: This can't be right. Need converter macros. */ +#define CONVERT_SSIZE_T_TO_JINT(x) ((jint)(x & 0xFFFFFFFF)) +#define CONVERT_JINT_TO_SSIZE_T(x) (x) + +/* cached fieldID of gnu.java.nio.channels.FileChannelImpl.fd */ +static jfieldID native_fd_fieldID; + +static jint +get_native_fd (JNIEnv * env, jobject obj) +{ + return (*env)->GetIntField (env, obj, native_fd_fieldID); +} + +/* + * Library initialization routine. Called as part of java.io.FileDescriptor + * static initialization. + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_init (JNIEnv * env, jclass clazz) +{ + jclass clazz_fc; + jfieldID field; + jmethodID constructor; + jobject obj; + + /* Initialize native_fd_fieldID so we only compute it once! */ + clazz_fc = (*env)->FindClass (env, "gnu/java/nio/channels/FileChannelImpl"); + if (!clazz_fc) + { + JCL_ThrowException (env, IO_EXCEPTION, "Internal error"); + return; + } + + field = (*env)->GetFieldID (env, clazz_fc, "fd", "I"); + if (!field) + { + JCL_ThrowException (env, IO_EXCEPTION, "Internal error"); + return; + } + + native_fd_fieldID = field; + + constructor = (*env)->GetMethodID (env, clazz, "<init>", "(II)V"); + if (!constructor) + return; + +#define INIT_FIELD(FIELDNAME, FDVALUE, MODE) \ + field = (*env)->GetStaticFieldID (env, clazz, FIELDNAME, \ + "Lgnu/java/nio/channels/FileChannelImpl;"); \ + if (! field) \ + return; \ + obj = (*env)->NewObject (env, clazz, constructor, FDVALUE, MODE); \ + if (! obj) \ + return; \ + (*env)->SetStaticObjectField (env, clazz, field, obj); \ + if ((*env)->ExceptionOccurred (env)) \ + return; + + INIT_FIELD ("in", 0, FILECHANNELIMPL_READ); + INIT_FIELD ("out", 1, FILECHANNELIMPL_WRITE); + INIT_FIELD ("err", 2, FILECHANNELIMPL_WRITE); + +#undef INIT_FIELD +} + +/* + * Open the specified file and return a native file descriptor + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_open (JNIEnv * env, + jobject obj + __attribute__ ((__unused__)), + jstring name, jint mode) +{ + const char *filename; + int flags; + int permissions; + int native_fd; + int result; + + filename = JCL_jstring_to_cstring (env, name); + if (filename == NULL) + return (-1); /* Exception will already have been thrown */ + + /* get file/permission flags for open() */ + if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_READ) + && (mode & FILECHANNELIMPL_FILEOPEN_FLAG_WRITE)) + { + /* read/write */ + flags = + TARGET_NATIVE_FILE_FILEFLAG_CREATE | + TARGET_NATIVE_FILE_FILEFLAG_READWRITE; + permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL; + } + else if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_READ)) + { + /* read */ + flags = TARGET_NATIVE_FILE_FILEFLAG_READ; + permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL; + } + else + { + /* write */ + flags = + TARGET_NATIVE_FILE_FILEFLAG_CREATE | + TARGET_NATIVE_FILE_FILEFLAG_WRITE; + if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_APPEND)) + { + flags |= TARGET_NATIVE_FILE_FILEFLAG_APPEND; + } + else + { + flags |= TARGET_NATIVE_FILE_FILEFLAG_TRUNCATE; + } + permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL; + } + + if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_SYNC)) + { + flags |= TARGET_NATIVE_FILE_FILEFLAG_SYNC; + } + + if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_DSYNC)) + { + flags |= TARGET_NATIVE_FILE_FILEFLAG_DSYNC; + } +#ifdef O_BINARY + flags |= TARGET_NATIVE_FILE_FILEFLAG_BINARY; +#endif + + TARGET_NATIVE_FILE_OPEN (filename, native_fd, flags, permissions, result); + JCL_free_cstring (env, name, filename); + + if (result != TARGET_NATIVE_OK) + { + /* We can only throw FileNotFoundException. */ + JCL_ThrowException (env, + "java/io/FileNotFoundException", + TARGET_NATIVE_LAST_ERROR_STRING ()); + return TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1; + } + + return native_fd; +} + +/* + * Closes the specified file descriptor and return status code. + * Exception on error + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_implCloseChannel (JNIEnv * env, + jobject obj) +{ + int native_fd; + int result; + + native_fd = get_native_fd (env, obj); + + TARGET_NATIVE_FILE_CLOSE (native_fd, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + } +} + +/* + * Return number of bytes that can be read from the file w/o blocking. + * Exception on error + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_available (JNIEnv * env, + jobject obj) +{ + int native_fd; + jlong bytes_available; + int result; + + native_fd = get_native_fd (env, obj); + + TARGET_NATIVE_FILE_AVAILABLE (native_fd, bytes_available, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return 0; + } + + /* FIXME NYI ??? why only jint and not jlong? */ + return TARGET_NATIVE_MATH_INT_INT64_TO_INT32 (bytes_available); +} + +JNIEXPORT jlong JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_size (JNIEnv * env, jobject obj) +{ + int native_fd; + jlong file_size; + int result; + + native_fd = get_native_fd (env, obj); + + TARGET_NATIVE_FILE_SIZE (native_fd, file_size, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1; + } + + return file_size; +} + +/* + * Return the current position of the file pointer + * Exception on error + */ +JNIEXPORT jlong JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_implPosition (JNIEnv * env, + jobject obj) +{ + int native_fd; + jlong current_offset; + int result; + + native_fd = get_native_fd (env, obj); + + TARGET_NATIVE_FILE_TELL (native_fd, current_offset, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1; + } + + return current_offset; +} + +/* + * Wrapper around lseek call. Return new file position + * Exception on error + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_seek (JNIEnv * env, jobject obj, + jlong offset) +{ + int native_fd; + jlong new_offset; + int result; + + native_fd = get_native_fd (env, obj); + +#if 0 + /* Should there be such an exception? All native layer macros should + be accepting 64bit-values if needed. It some target is not able + to handle such values it should simply operate with 32bit-values + and convert 64bit-values appriopated. In this case I assume + problems should not occurre: if some specific target is not able + to handle 64bit-values the system is limited to 32bit at all, thus + the application can not do a seek() or something else beyond the + 32bit limit. It this true? + */ + + /* FIXME: What do we do if offset > the max value of off_t on this 32bit + * system? How do we detect that and what do we do? */ + if (CONVERT_OFF_T_TO_JLONG (native_offset) != offset) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Cannot represent position correctly on this system"); + } +#endif /* 0 */ + + result = TARGET_NATIVE_ERROR; + new_offset = TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1; + TARGET_NATIVE_FILE_SEEK_BEGIN (native_fd, offset, new_offset, result); + + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + } +} + +/* + * Set the length of the file + * Exception on error + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_implTruncate (JNIEnv * env, + jobject obj, + jlong len) +{ + int native_fd; + jlong file_size; + int bytes_written; + jlong save_offset, new_offset; + char data; + int result; + + native_fd = get_native_fd (env, obj); + +#if 0 + /* Should there be such an exception? All native layer macros should + be accepting 64bit-values if needed. It some target is not able + to handle such values it should simply operate with 32bit-values + and convert 64bit-values appriopated. In this case I assume + problems should not occurre: if some specific target is not able + to handle 64bit-values the system is limited to 32bit at all, thus + the application can not do a seek() or something else beyond the + 32bit limit. It this true? + */ + + /* FIXME: What do we do if len > the max value of off_t on this 32bit + * system? How do we detect that and what do we do? */ + if (CONVERT_OFF_T_TO_JLONG (native_len) != len) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Cannot represent position correctly on this system"); + return; + } +#endif /* 0 */ + + /* get file size */ + TARGET_NATIVE_FILE_SIZE (native_fd, file_size, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } + + /* Save off current position */ + TARGET_NATIVE_FILE_TELL (native_fd, save_offset, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } + + if (TARGET_NATIVE_MATH_INT_INT64_LT (file_size, len)) + { + /* File is too short -- seek to one byte short of where we want, + * then write a byte */ + + /* move to position n-1 */ + TARGET_NATIVE_FILE_SEEK_BEGIN (native_fd, + TARGET_NATIVE_MATH_INT_INT64_SUB (len, + 1), + new_offset, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } + + /* write a byte + Note: This will fail if we somehow get here in read only mode + * That shouldn't happen */ + data = '\0'; + TARGET_NATIVE_FILE_WRITE (native_fd, &data, 1, bytes_written, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } + + /* Reposition file pointer to where we started if not beyond new len. */ + if (TARGET_NATIVE_MATH_INT_INT64_LT (save_offset, len)) + { + TARGET_NATIVE_FILE_SEEK_BEGIN (native_fd, save_offset, + new_offset, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } + } + } + else if (TARGET_NATIVE_MATH_INT_INT64_GT (file_size, len)) + { + /* File is too long - use ftruncate if available */ +#ifdef HAVE_FTRUNCATE + TARGET_NATIVE_FILE_TRUNCATE (native_fd, len, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } +#else /* HAVE_FTRUNCATE */ + /* FIXME: Probably operation isn't supported, but this exception + * is too harsh as it will probably crash the program without need + JCL_ThrowException(env, "java/lang/UnsupportedOperationException", + "not implemented - can't shorten files on this platform"); + */ + JCL_ThrowException (env, IO_EXCEPTION, "Unable to shorten file length"); +#endif /* HAVE_FTRUNCATE */ + + /* Reposition file pointer when it now is beyond the end of file. */ + if (TARGET_NATIVE_MATH_INT_INT64_GT (save_offset, len)) + { + TARGET_NATIVE_FILE_SEEK_BEGIN (native_fd, len, new_offset, result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } + } + } +} + +JNIEXPORT jobject JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_mapImpl (JNIEnv * env, + jobject obj + __attribute__ ((__unused__)), jchar mode __attribute__ ((__unused__)), jlong position __attribute__ ((__unused__)), jint size __attribute__ ((__unused__))) +{ + JCL_ThrowException (env, IO_EXCEPTION, + "java.nio.FileChannelImpl.nio_mmap_file(): not implemented"); + return 0; +} + +/* + * Read a single byte from the file descriptor + * Return byte read or -1 on eof, exception on error + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_read__ (JNIEnv * env, jobject obj) +{ + int native_fd; + char data; + ssize_t bytes_read; + int result; + + native_fd = get_native_fd (env, obj); + + bytes_read = 0; + do + { + TARGET_NATIVE_FILE_READ (native_fd, &data, 1, bytes_read, result); + if ((result == TARGET_NATIVE_OK) && (bytes_read == 0)) + { + return (-1); + } + if ((result != TARGET_NATIVE_OK) + && (TARGET_NATIVE_LAST_ERROR () != + TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return (-1); + } + } + while (result != TARGET_NATIVE_OK); + + return ((jint) (data & 0xFF)); +} + +/* + * Reads to a byte buffer from the specified file descriptor + * Return number of bytes read or -1 on eof, exception on error + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_read___3BII (JNIEnv * env, + jobject obj, + jbyteArray buffer, + jint offset, + jint length) +{ + int native_fd; + jbyte *bufptr; + ssize_t bytes_read; + ssize_t n; + int result; + + native_fd = get_native_fd (env, obj); + + /* Must return 0 if an attempt is made to read 0 bytes. */ + if (length == 0) + return 0; + + if (offset < 0) + { + JCL_ThrowException (env, IO_EXCEPTION, "negative offset"); + return -1; + } + + bufptr = (*env)->GetByteArrayElements (env, buffer, 0); + if (!bufptr) + { + JCL_ThrowException (env, IO_EXCEPTION, "Unexpected JNI error"); + return (-1); + } + + if (length + offset > (*env)->GetArrayLength (env, buffer)) + { + JCL_ThrowException (env, IO_EXCEPTION, + "length + offset > buffer.length"); + return -1; + } + + bytes_read = 0; + do + { + TARGET_NATIVE_FILE_READ (native_fd, (bufptr + offset + bytes_read), + (length - bytes_read), n, result); + if ((result == TARGET_NATIVE_OK) && (n == 0)) + { + (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0); + if (bytes_read == 0) + return -1; /* Signal end of file to Java */ + else + return CONVERT_SSIZE_T_TO_JINT (bytes_read); + } + if ((result != TARGET_NATIVE_OK) + && (TARGET_NATIVE_LAST_ERROR () != + TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0); + return -1; + } + if (result == TARGET_NATIVE_OK) + bytes_read += n; + } + while (bytes_read < 1); + + (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0); + return CONVERT_SSIZE_T_TO_JINT (bytes_read); +} + +/* + * Writes a single byte to the specified file descriptor + * Return status code, exception on error + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_write__I (JNIEnv * env, + jobject obj, jint b) +{ + int native_fd; + char native_data; + ssize_t bytes_written; + int result; + + native_fd = get_native_fd (env, obj); + native_data = (char) (CONVERT_JINT_TO_INT (b) & 0xFF); + + do + { + TARGET_NATIVE_FILE_WRITE (native_fd, &native_data, 1, bytes_written, + result); + if ((result != TARGET_NATIVE_OK) + && (TARGET_NATIVE_LAST_ERROR () != + TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } + } + while (result != TARGET_NATIVE_OK); +} + +/* + * Copies all parts of a file to disk. + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_force (JNIEnv * env, + jobject obj) +{ + int native_fd; + int result; + native_fd = get_native_fd (env, obj); + TARGET_NATIVE_FILE_FSYNC (native_fd, result); + if (result != TARGET_NATIVE_OK) + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); +} + +/* + * Writes a byte buffer to the specified file descriptor + * Return status code, exception on error + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_write___3BII (JNIEnv * env, + jobject obj, + jbyteArray buffer, + jint offset, + jint length) +{ + int native_fd; + jbyte *bufptr; + ssize_t bytes_written; + ssize_t n; + int result; + + native_fd = get_native_fd (env, obj); + + /* Just return if an attempt is made to write 0 bytes. */ + if (length == 0) + return; + + bufptr = (*env)->GetByteArrayElements (env, buffer, 0); + if (!bufptr) + { + JCL_ThrowException (env, IO_EXCEPTION, "Unexpected JNI error"); + return; + } + + bytes_written = 0; + while (bytes_written < CONVERT_JINT_TO_SSIZE_T (length)) + { + TARGET_NATIVE_FILE_WRITE (native_fd, (bufptr + offset + bytes_written), + (length - bytes_written), n, result); + if ((result != TARGET_NATIVE_OK) + && (TARGET_NATIVE_LAST_ERROR () != + TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0); + return; + } + if (result == TARGET_NATIVE_OK) + bytes_written += n; + } + + (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0); +} + +JNIEXPORT jboolean JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_lock (JNIEnv *env, jobject obj, + jlong position, jlong size, + jboolean shared, jboolean wait) +{ +#ifdef HAVE_FCNTL + int fd = get_native_fd (env, obj); + int cmd = wait ? F_SETLKW : F_SETLK; + struct flock flock; + int ret; + + flock.l_type = shared ? F_RDLCK : F_WRLCK; + flock.l_whence = SEEK_SET; + flock.l_start = (off_t) position; + flock.l_len = (off_t) size; + + ret = fcntl (fd, cmd, &flock); + if (ret) + { + /* Linux man pages for fcntl state that errno might be either + EACCES or EAGAIN if we try F_SETLK, and another process has + an overlapping lock. */ + if (errno != EACCES && errno != EAGAIN) + { + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + } + return JNI_FALSE; + } + return JNI_TRUE; +#else + (void) obj; + (void) position; + (void) size; + (void) shared; + (void) wait; + JCL_ThrowException (env, "java/lang/UnsupportedOperationException", + "file locks not implemented on this platform"); + return JNI_FALSE; +#endif /* HAVE_FCNTL */ +} + +JNIEXPORT void JNICALL +Java_gnu_java_nio_channels_FileChannelImpl_unlock (JNIEnv *env, + jobject obj, + jlong position, + jlong length) +{ +#ifdef HAVE_FCNTL + int fd = get_native_fd (env, obj); + struct flock flock; + int ret; + + flock.l_type = F_UNLCK; + flock.l_whence = SEEK_SET; + flock.l_start = (off_t) position; + flock.l_len = (off_t) length; + + ret = fcntl (fd, F_SETLK, &flock); + if (ret) + { + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + } +#else + (void) obj; + (void) position; + (void) length; + JCL_ThrowException (env, "java/lang/UnsupportedOperationException", + "file locks not implemented on this platform"); +#endif /* HAVE_FCNTL */ +} diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c new file mode 100644 index 00000000000..8c3f83accff --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c @@ -0,0 +1,219 @@ +/* gnu_java_nio_charset_iconv_IconvDecoder.c -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include <config.h> +#include <jcl.h> + +#include <stdio.h> +#include <assert.h> +#include <errno.h> + +#if defined(HAVE_ICONV) +#include <iconv.h> +#endif + +#include "gnu_java_nio_charset_iconv_IconvDecoder.h" + +static void createRawData (JNIEnv * env, jobject obj, void *ptr); +static void *getData (JNIEnv * env, jobject obj); + +static jfieldID infid = NULL; +static jfieldID outfid = NULL; + +/* Union used for type punning. */ +union char_union +{ + jbyte **jb; + jchar **jc; + char **c; +}; + +JNIEXPORT void JNICALL +Java_gnu_java_nio_charset_iconv_IconvDecoder_openIconv (JNIEnv * env, + jobject obj, + jstring jname) +{ +#if defined(HAVE_ICONV) + iconv_t iconv_object; + jclass cls; + + const char *name = JCL_jstring_to_cstring (env, jname); + if (name == NULL) + return; + + /* Cache fieldIDs for use in decode function. */ + if (infid == NULL || outfid == NULL) + { + cls = (*env)->GetObjectClass (env, obj); + infid = (*env)->GetFieldID (env, cls, "inremaining", "I"); + assert (infid != 0); + outfid = (*env)->GetFieldID (env, cls, "outremaining", "I"); + assert (outfid != 0); + } + + /* to java from "name", native java format depends on endianness */ +#ifdef WORDS_BIGENDIAN + iconv_object = iconv_open ("UTF-16BE", name); +#else + iconv_object = iconv_open ("UTF-16LE", name); +#endif + + JCL_free_cstring (env, jname, name); + if ((long) iconv_object == -1L) + { + JCL_ThrowException (env, "java/lang/IllegalArgumentException", + "Charset not available"); + return; + } + createRawData (env, obj, (void *) iconv_object); +#else + JCL_ThrowException (env, "java/lang/IllegalArgumentException", + "iconv not available"); +#endif +} + +JNIEXPORT jint JNICALL +Java_gnu_java_nio_charset_iconv_IconvDecoder_decode (JNIEnv * env, + jobject obj, + jbyteArray inArr, + jcharArray outArr, + jint posIn, jint remIn, + jint posOut, jint remOut) +{ +#if defined(HAVE_ICONV) + iconv_t iconv_object = getData (env, obj); + size_t retval; + union char_union in, out; + jbyte *input, *inputcopy; + jchar *output, *outputcopy; + size_t lenIn = (size_t) remIn; + size_t lenOut = (size_t) remOut * 2; + + inputcopy = input = (*env)->GetByteArrayElements (env, inArr, 0); + outputcopy = output = (*env)->GetCharArrayElements (env, outArr, 0); + + input += posIn; + output += posOut; + + in.jb = &input; + out.jc = &output; + retval = iconv (iconv_object, (ICONV_CONST char **) in.c, &lenIn, + out.c, &lenOut); + + /* XXX: Do we need to relase the input array? It's not modified. */ + (*env)->ReleaseByteArrayElements (env, inArr, inputcopy, 0); + (*env)->ReleaseCharArrayElements (env, outArr, outputcopy, 0); + + if (retval == (size_t) (-1)) + { + if (errno == EILSEQ || errno == EINVAL) + retval = 1; + else + retval = 0; + } + else + retval = 0; + + (*env)->SetIntField (env, obj, infid, (jint) lenIn); + (*env)->SetIntField (env, obj, outfid, (jint) (lenOut >> 1)); + + return (jint) retval; +#else + return -1; +#endif +} + +JNIEXPORT void JNICALL +Java_gnu_java_nio_charset_iconv_IconvDecoder_closeIconv (JNIEnv * env, + jobject obj) +{ +#if defined(HAVE_ICONV) + iconv_t iconv_object; + iconv_object = getData (env, obj); + iconv_close (iconv_object); +#endif +} + + +static void +createRawData (JNIEnv * env, jobject obj, void *ptr) +{ + jclass cls; + jmethodID method; + jobject data; + jfieldID data_fid; + + cls = (*env)->GetObjectClass (env, obj); + data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/RawData;"); + assert (data_fid != 0); + +#ifdef POINTERS_ARE_64BIT + cls = (*env)->FindClass (env, "gnu/classpath/RawData64"); + method = (*env)->GetMethodID (env, cls, "<init>", "(J)V"); + data = (*env)->NewObject (env, cls, method, (jlong) ptr); +#else + cls = (*env)->FindClass (env, "gnu/classpath/RawData32"); + method = (*env)->GetMethodID (env, cls, "<init>", "(I)V"); + data = (*env)->NewObject (env, cls, method, (jint) ptr); +#endif + + (*env)->SetObjectField (env, obj, data_fid, data); +} + +static void * +getData (JNIEnv * env, jobject obj) +{ + jclass cls; + jfieldID field; + jfieldID data_fid; + jobject data; + + cls = (*env)->GetObjectClass (env, obj); + data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/RawData;"); + assert (data_fid != 0); + data = (*env)->GetObjectField (env, obj, data_fid); + +#if SIZEOF_VOID_P == 8 + cls = (*env)->FindClass (env, "gnu/classpath/RawData64"); + field = (*env)->GetFieldID (env, cls, "data", "J"); + return (void *) (*env)->GetLongField (env, data, field); +#else + cls = (*env)->FindClass (env, "gnu/classpath/RawData32"); + field = (*env)->GetFieldID (env, cls, "data", "I"); + return (void *) (*env)->GetIntField (env, data, field); +#endif +} diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c new file mode 100644 index 00000000000..cd5d48656f7 --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c @@ -0,0 +1,219 @@ +/* gnu_java_nio_charset_iconv_IconvEncoder.c -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include <config.h> +#include <jcl.h> + +#include <stdio.h> +#include <assert.h> +#include <errno.h> + +#if defined(HAVE_ICONV) +#include <iconv.h> +#endif + +#include "gnu_java_nio_charset_iconv_IconvEncoder.h" + +static void createRawData (JNIEnv * env, jobject obj, void *ptr); +static void *getData (JNIEnv * env, jobject obj); + +static jfieldID infid = NULL; +static jfieldID outfid = NULL; + +/* Union used for type punning. */ +union char_union +{ + jbyte **jb; + jchar **jc; + char **c; +}; + +JNIEXPORT void JNICALL +Java_gnu_java_nio_charset_iconv_IconvEncoder_openIconv (JNIEnv * env, + jobject obj, + jstring jname) +{ +#if defined(HAVE_ICONV) + iconv_t iconv_object; + jclass cls; + + const char *name = JCL_jstring_to_cstring (env, jname); + if (name == NULL) + return; + + /* Cache fieldIDs for use in encode function. */ + if (infid == NULL || outfid == NULL) + { + cls = (*env)->GetObjectClass (env, obj); + infid = (*env)->GetFieldID (env, cls, "inremaining", "I"); + assert (infid != 0); + outfid = (*env)->GetFieldID (env, cls, "outremaining", "I"); + assert (outfid != 0); + } + + /* to "name" from java, native java format depends on endianness */ +#ifdef WORDS_BIGENDIAN + iconv_object = iconv_open (name, "UTF-16BE"); +#else + iconv_object = iconv_open (name, "UTF-16LE"); +#endif + + JCL_free_cstring (env, jname, name); + if ((long) iconv_object == -1L) + { + JCL_ThrowException (env, "java/lang/IllegalArgumentException", + "Charset not available"); + return; + } + createRawData (env, obj, (void *) iconv_object); +#else + JCL_ThrowException (env, "java/lang/IllegalArgumentException", + "iconv not available"); +#endif +} + +JNIEXPORT jint JNICALL +Java_gnu_java_nio_charset_iconv_IconvEncoder_encode (JNIEnv * env, + jobject obj, + jcharArray inArr, + jbyteArray outArr, + jint posIn, jint remIn, + jint posOut, jint remOut) +{ +#if defined(HAVE_ICONV) + iconv_t iconv_object = getData (env, obj); + size_t retval; + union char_union in, out; + jchar *input, *inputcopy; + jbyte *output, *outputcopy; + size_t lenIn = (size_t) remIn * 2; + size_t lenOut = (size_t) remOut; + + inputcopy = input = (*env)->GetCharArrayElements (env, inArr, 0); + outputcopy = output = (*env)->GetByteArrayElements (env, outArr, 0); + + input += posIn; + output += posOut; + + in.jc = &input; + out.jb = &output; + retval = iconv (iconv_object, (ICONV_CONST char **) in.c, &lenIn, + out.c, &lenOut); + + /* XXX: Do we need to relase the input array? It's not modified. */ + (*env)->ReleaseCharArrayElements (env, inArr, inputcopy, 0); + (*env)->ReleaseByteArrayElements (env, outArr, outputcopy, 0); + + if (retval == (size_t) (-1)) + { + if (errno == EILSEQ || errno == EINVAL) + retval = 1; + else + retval = 0; + } + else + retval = 0; + + (*env)->SetIntField (env, obj, infid, (jint) (lenIn >> 1)); + (*env)->SetIntField (env, obj, outfid, (jint) lenOut); + + return (jint) retval; +#else + return -1; +#endif +} + +JNIEXPORT void JNICALL +Java_gnu_java_nio_charset_iconv_IconvEncoder_closeIconv (JNIEnv * env, + jobject obj) +{ +#if defined(HAVE_ICONV) + iconv_t iconv_object; + iconv_object = getData (env, obj); + iconv_close (iconv_object); +#endif +} + + +static void +createRawData (JNIEnv * env, jobject obj, void *ptr) +{ + jclass cls; + jmethodID method; + jobject data; + jfieldID data_fid; + + cls = (*env)->GetObjectClass (env, obj); + data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/RawData;"); + assert (data_fid != 0); + +#ifdef POINTERS_ARE_64BIT + cls = (*env)->FindClass (env, "gnu/classpath/RawData64"); + method = (*env)->GetMethodID (env, cls, "<init>", "(J)V"); + data = (*env)->NewObject (env, cls, method, (jlong) ptr); +#else + cls = (*env)->FindClass (env, "gnu/classpath/RawData32"); + method = (*env)->GetMethodID (env, cls, "<init>", "(I)V"); + data = (*env)->NewObject (env, cls, method, (jint) ptr); +#endif + + (*env)->SetObjectField (env, obj, data_fid, data); +} + +static void * +getData (JNIEnv * env, jobject obj) +{ + jclass cls; + jfieldID field; + jfieldID data_fid; + jobject data; + + cls = (*env)->GetObjectClass (env, obj); + data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/RawData;"); + assert (data_fid != 0); + data = (*env)->GetObjectField (env, obj, data_fid); + +#if SIZEOF_VOID_P == 8 + cls = (*env)->FindClass (env, "gnu/classpath/RawData64"); + field = (*env)->GetFieldID (env, cls, "data", "J"); + return (void *) (*env)->GetLongField (env, data, field); +#else + cls = (*env)->FindClass (env, "gnu/classpath/RawData32"); + field = (*env)->GetFieldID (env, cls, "data", "I"); + return (void *) (*env)->GetIntField (env, data, field); +#endif +} diff --git a/libjava/classpath/native/jni/java-nio/java_nio.c b/libjava/classpath/native/jni/java-nio/java_nio.c new file mode 100644 index 00000000000..a25f38a6d2a --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/java_nio.c @@ -0,0 +1,328 @@ +/* java_nio.c - Native methods for gnu.java.nio.FileChannelImpl class + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* do not move; needed here because of some macro definitions */ +#include <config.h> + +#ifdef HAVE_MMAP +#include <sys/mman.h> +#endif + +#include <jni.h> +#include <jcl.h> + +#include "target_native.h" +#ifndef WITHOUT_NETWORK +#include "target_native_network.h" +#endif /* WITHOUT_NETWORK */ + +#include "java_nio_channels_FileChannelImpl.h" + +#include "javaio.h" + +#define NIO_DEBUG(X) /* no debug */ +//#define NIO_DEBUG(X) X + +/*************************************** + * + * File Channel implementation + * + *************/ + + +static char * +compare (int i, int lim, char *buffer) +{ + sprintf (buffer, "(%d >= %d)", i, lim); + return buffer; +} + +static inline int +convert_Int (int X) +{ + unsigned char *a = (unsigned char *) &X; + int res = + (((int) a[0]) << 24) + + (((int) a[1]) << 16) + (((int) a[2]) << 8) + (((int) a[3]) << 0); + return res; +} + +static inline jlong +convert_Long (jlong X) +{ + unsigned char *a = (unsigned char *) &X; + int res1 = + (((int) a[0]) << 24) + + (((int) a[1]) << 16) + (((int) a[2]) << 8) + (((int) a[3]) << 0); + int res2; + a += 4; + res2 = + (((int) a[0]) << 24) + + (((int) a[1]) << 16) + (((int) a[2]) << 8) + (((int) a[3]) << 0); + return ((jlong) res1) | ((jlong) res2) << 32LL; +} + +static inline short +convert_Short (short X) +{ + unsigned char *a = (unsigned char *) &X; + int res = (((int) a[2]) << 8) + (((int) a[3]) << 0); + return res; +} +static inline short +convert_Char (short X) +{ + unsigned char *a = (unsigned char *) &X; + int res = (((int) a[2]) << 8) + (((int) a[3]) << 0); + return res; +} + +static inline unsigned char +convert_Byte (unsigned char X) +{ + return X; +} + +static inline float +convert_Float (float X) +{ + return X; +} + +static inline double +convert_Double (double X) +{ + return X; +} + + +// Note: do to many get()'s on a buffer and you should throw a BufferUnderflowException +// Alas, I only found this out during testing.... + +#define READ_WRITE_MMAPED_FILE(TYPE,ELT) \ + \ +ELT Java_gnu_java_nio_MappedByteFileBuffer_nio_1read_1 ## TYPE ## _1file_1channel(JNIEnv *env, \ + jclass c, jobject b, \ + int index, int limit, jlong jaddress) \ +{ \ + char *address = *(void **) &jaddress; char buffer[128]; \ + if (index >= limit) JCL_ThrowException(env, "java/nio/BufferUnderflowException", compare(index,limit, buffer)); \ + NIO_DEBUG( fprintf(stderr, "READ:index = %d [0]=%c [1]=%c\n", index, address[0],address[1]); ) \ + address += index; \ + return convert_ ## TYPE (*(ELT *) address); \ +} \ + \ +void Java_gnu_java_nio_MappedByteFileBuffer_nio_1write_1 ## TYPE ## _1file_1channel(JNIEnv *env, \ + jclass c, jobject b, \ + int index, int limit, ELT value, jlong jaddress) \ +{ \ + \ + char *address = *(void **) &jaddress; char buffer[128]; \ + if (index >= limit) JCL_ThrowException(env, "java/nio/BufferUnderflowException", compare(index,limit, buffer)); \ +NIO_DEBUG( fprintf(stderr, "WRITE:index = %d [0]=%c [1]=%c\n", index, address[0],address[1]); ) \ + address += index; \ + *(ELT *) address = value; \ +} \ + \ +ELT Java_gnu_java_nio_MappedByteFileBuffer_nio_1get_1 ## TYPE(JNIEnv *env, jclass c, jobject b, \ + int index, int limit, jlong jaddress) \ +{ \ + fprintf(stderr, "unimplemented\n"); return 0; \ +} \ + \ +void Java_gnu_java_nio_MappedByteFileBuffer_nio_1put_1 ## TYPE(JNIEnv *env, jclass c, jobject b, \ + int index, int limit, \ + ELT value, jlong jaddress) \ +{ \ + fprintf(stderr, "unimplemented\n"); \ +} + +READ_WRITE_MMAPED_FILE (Byte, u_int8_t); +READ_WRITE_MMAPED_FILE (Char, u_int16_t); +READ_WRITE_MMAPED_FILE (Short, u_int16_t); +READ_WRITE_MMAPED_FILE (Int, u_int32_t); +READ_WRITE_MMAPED_FILE (Long, u_int64_t); +READ_WRITE_MMAPED_FILE (Float, float); +READ_WRITE_MMAPED_FILE (Double, double); + +u_int64_t +nio_mmap_file (jint fd, jlong pos, jint size, jint jflags) +{ +#ifdef HAVE_MMAP + u_int64_t ret = 0; + void *address; + + int flags = (jflags != 2) ? MAP_SHARED : MAP_PRIVATE; + int prot = PROT_READ; + + if (jflags == 1) + prot |= PROT_WRITE; + + // fprintf(stderr, "mapping file: %d\n", fd); + + address = mmap (0, size, prot, flags, fd, pos); + + if (address == (void *) -1) + { + perror ("mapping file failed"); + return 0; + } + + // fprintf(stderr, "address = %p, fd = %d, pos=%lld, size=%d\n", address, fd, pos, size); + + *(void **) &ret = address; + + return ret; +#else /* not HAVE_MMAP */ + return (TARGET_NATIVE_MATH_INT_INT64_CONST_0); +#endif /* not HAVE_MMAP */ +} + + +void +nio_msync (int fd, jlong jaddress, int size) +{ +#ifdef HAVE_MMAP + int res; + char *address = *(void **) &jaddress; + + // fprintf(stderr, "synchronizing with file (%p -> %d bytes (%s))\n", address, size, address); + + res = msync (address, size, MS_SYNC | MS_INVALIDATE); + + if (res == -1) + { + perror ("synchronize with file failed"); + } +#else /* not HAVE_MMAP */ +#endif /* not HAVE_MMAP */ +} + +void +nio_unmmap_file (int fd, jlong jaddress, int size) +{ +#ifdef HAVE_MMAP + int res = 0; + char *address = *(void **) &jaddress; + + // nio_msync(fd, jaddress, size); + + // fprintf(stderr, "unmapping (%p -> %d bytes)\n", address, size); + + res = munmap (address, size); + if (res == -1) + { + perror ("un-mapping file failed"); + } +#else /* not HAVE_MMAP */ +#endif /* not HAVE_MMAP */ +} + + +/*************************************** + * + * Socket Channel implementation + * + *************/ + +/*************************************************************************/ + +/* + * Returns a 32 bit Internet address for the passed in InetAddress object + * Ronald: This is a verbatim copy from javanet.c. + * It's a copy to avoid a link error in orp. + */ + +static int +socket_channel_get_net_addr (JNIEnv * env, jobject addr) +{ +#ifndef WITHOUT_NETWORK + jclass cls = 0; + jmethodID mid; + jarray arr = 0; + jbyte *octets; + int netaddr, len; + + DBG + ("socket_channel_get_net_addr(): Entered socket_channel_get_net_addr\n"); + + /* Call the getAddress method on the object to retrieve the IP address */ + cls = (*env)->GetObjectClass (env, addr); + if (cls == NULL) + return (0); + + mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B"); + if (mid == NULL) + return (0); + + DBG ("socket_channel_get_net_addr(): Got getAddress method\n"); + + arr = (*env)->CallObjectMethod (env, addr, mid); + if (arr == NULL) + return (0); + + DBG ("socket_channel_get_net_addr(): Got the address\n"); + + /* Turn the IP address into a 32 bit Internet address in network byte order */ + len = (*env)->GetArrayLength (env, arr); + if (len != 4) + { + JCL_ThrowException (env, "java/io/IOException", + "Internal Error: invalid byte array length"); + return (0); + } + DBG ("socket_channel_get_net_addr(): Length ok\n"); + + octets = (*env)->GetByteArrayElements (env, arr, 0); + if (octets == NULL) + return (0); + + DBG ("socket_channel_get_net_addr(): Grabbed bytes\n"); + + TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0], + octets[1], + octets[2], + octets[3], netaddr); + + (*env)->ReleaseByteArrayElements (env, arr, octets, 0); + DBG ("socket_channel_get_net_addr(): Done getting addr\n"); + + return netaddr; +#else /* not WITHOUT_NETWORK */ + return (0); +#endif /* not WITHOUT_NETWORK */ +} diff --git a/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c b/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c new file mode 100644 index 00000000000..e1ba1e454f0 --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c @@ -0,0 +1,83 @@ +/* java_nio_MappedByteBufferImpl.c - Native methods for MappedByteBufferImpl + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include <config.h> +#include <errno.h> + +#include <jni.h> +#include <jcl.h> + +#include "java_nio_MappedByteBufferImpl.h" + +#define IO_EXCEPTION "java/io/IOException" + +JNIEXPORT void JNICALL +Java_java_nio_MappedByteBufferImpl_unmapImpl (JNIEnv * env, + jclass class + __attribute__ ((__unused__))) +{ + JCL_ThrowException (env, IO_EXCEPTION, + "java.nio.MappedByteBufferImpl.unmapImpl(): not implemented"); +} + +JNIEXPORT jboolean JNICALL +Java_java_nio_MappedByteBufferImpl_isLoadedImpl (JNIEnv * env, + jclass class + __attribute__ ((__unused__))) +{ + JCL_ThrowException (env, IO_EXCEPTION, + "java.nio.MappedByteBufferImpl.isLoadedImpl(): not implemented"); + return 0; +} + +JNIEXPORT void JNICALL +Java_java_nio_MappedByteBufferImpl_loadImpl (JNIEnv * env, + jclass clazz + __attribute__ ((__unused__))) +{ + JCL_ThrowException (env, IO_EXCEPTION, + "java.nio.MappedByteBufferImpl.loadImpl(): not implemented"); +} + +JNIEXPORT void JNICALL +Java_java_nio_MappedByteBufferImpl_forceImpl (JNIEnv * env, + jclass class + __attribute__ ((__unused__))) +{ + JCL_ThrowException (env, IO_EXCEPTION, + "java.nio.MappedByteBufferImpl.forceImpl(): not implemented"); +} diff --git a/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c b/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c new file mode 100644 index 00000000000..3eb5677e646 --- /dev/null +++ b/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c @@ -0,0 +1,216 @@ +/* java_nio_VMDirectByteBuffer.c - Native methods for VMDirectByteBuffer + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include <config.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <jni.h> +#include <jcl.h> + +#include "java_nio_VMDirectByteBuffer.h" + +static jclass classRawData; +static jmethodID methodRawDataInit; +static jfieldID fieldNativePointer; + +static void *NIOGetPointer (JNIEnv *, jobject); +static jobject NIOGetRawData (JNIEnv *, void *pointer); + +static void * +NIOGetPointer (JNIEnv * env, jobject rawdata) +{ +#if SIZEOF_VOID_P == 4 + return (void *) (*env)->GetIntField (env, rawdata, fieldNativePointer); +#elif SIZEOF_VOID_P == 8 + return (void *) (*env)->GetLongField (env, rawdata, fieldNativePointer); +#else +#error unsupported pointer size +#endif +} + +static jobject +NIOGetRawData (JNIEnv * env, void *pointer) +{ +#if SIZEOF_VOID_P == 4 + return (*env)->NewObject (env, classRawData, methodRawDataInit, + (jint) pointer); +#elif SIZEOF_VOID_P == 8 + return (*env)->NewObject (env, classRawData, methodRawDataInit, + (jlong) pointer); +#else +#error unsupported pointer size +#endif +} + +JNIEXPORT void JNICALL +Java_java_nio_VMDirectByteBuffer_init + (JNIEnv * env, jclass clazz __attribute__ ((__unused__))) +{ +#if SIZEOF_VOID_P == 4 + classRawData = (*env)->FindClass (env, "gnu/classpath/RawData32"); + if (classRawData == NULL) + { + JCL_ThrowException (env, "java/lang/InternalError", + "unable to find internal class"); + return; + } + + methodRawDataInit = (*env)->GetMethodID (env, classRawData, + "<init>", "(I)V"); + if (methodRawDataInit == NULL) + { + JCL_ThrowException (env, "java/lang/InternalError", + "unable to find internal constructor"); + return; + } + + fieldNativePointer = (*env)->GetFieldID (env, classRawData, "data", "I"); + if (fieldNativePointer == NULL) + { + JCL_ThrowException (env, "java/lang/InternalError", + "unable to find internal field"); + return; + } +#elif SIZEOF_VOID_P == 8 + classRawData = (*env)->FindClass (env, "gnu/classpath/RawData64"); + if (classRawData == NULL) + { + JCL_ThrowException (env, "java/lang/InternalError", + "unable to find internal class"); + return; + } + + methodRawDataInit = (*env)->GetMethodID (env, classRawData, + "<init>", "(J)V"); + if (methodRawDataInit == NULL) + { + JCL_ThrowException (env, "java/lang/InternalError", + "unable to find internal constructor"); + return; + } + + fieldNativePointer = (*env)->GetFieldID (env, classRawData, "data", "J"); + if (fieldNativePointer == NULL) + { + JCL_ThrowException (env, "java/lang/InternalError", + "unable to find internal field"); + return; + } +#else +#error unsupported pointer size +#endif + + /* We need to wrap the jclass in global reference to make it persistent */ + if ((classRawData = (*env)->NewGlobalRef (env, classRawData)) == NULL) + { + JCL_ThrowException (env, "java/lang/InternalError", + "failed to create global reference"); + return; + } +} + +JNIEXPORT jobject JNICALL +Java_java_nio_VMDirectByteBuffer_allocate + (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), jint capacity) +{ + void *buffer; + + buffer = malloc (capacity); + + if (buffer == NULL) + { + JCL_ThrowException (env, "java/lang/OutOfMemoryError", + "unable to allocate memory for direct byte buffer"); + return 0; + } + + return NIOGetRawData (env, buffer); +} + +JNIEXPORT void JNICALL +Java_java_nio_VMDirectByteBuffer_free + (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), jobject address) +{ + free (NIOGetPointer (env, address)); +} + +JNIEXPORT jbyte JNICALL +Java_java_nio_VMDirectByteBuffer_get__Lgnu_classpath_RawData_2I + (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), + jobject address, jint index) +{ + return ((jbyte *) NIOGetPointer (env, address))[index]; +} + +JNIEXPORT void JNICALL +Java_java_nio_VMDirectByteBuffer_put + (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), + jobject address, jint index, jbyte value) +{ + jbyte *pointer = (jbyte *) NIOGetPointer (env, address) + index; + *pointer = value; +} + +JNIEXPORT void JNICALL +Java_java_nio_VMDirectByteBuffer_get__Lgnu_classpath_RawData_2I_3BII + (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), + jobject address, jint index, jbyteArray dst, jint dst_offset, jint dst_len) +{ + jbyte *src = (jbyte *) NIOGetPointer (env, address) + index; + memcpy ((*env)->GetByteArrayElements (env, dst, NULL) + dst_offset, src, + dst_len); +} + +JNIEXPORT void JNICALL +Java_java_nio_VMDirectByteBuffer_shiftDown + (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), + jobject address, jint dst_offset, jint src_offset, jint count) +{ + jbyte *dst = (jbyte *) NIOGetPointer (env, address) + dst_offset; + jbyte *src = (jbyte *) NIOGetPointer (env, address) + src_offset; + memmove (dst, src, count); +} + +JNIEXPORT jobject JNICALL +Java_java_nio_VMDirectByteBuffer_adjustAddress + (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), + jobject address, jint offset) +{ + return NIOGetRawData (env, (jbyte *) NIOGetPointer (env, address) + offset); +} |

