summaryrefslogtreecommitdiff
path: root/libjava/gnu/java/nio/channels/natFileChannelWin32.cc
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/gnu/java/nio/channels/natFileChannelWin32.cc
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/gnu/java/nio/channels/natFileChannelWin32.cc')
-rw-r--r--libjava/gnu/java/nio/channels/natFileChannelWin32.cc466
1 files changed, 466 insertions, 0 deletions
diff --git a/libjava/gnu/java/nio/channels/natFileChannelWin32.cc b/libjava/gnu/java/nio/channels/natFileChannelWin32.cc
new file mode 100644
index 000000000..ab238e623
--- /dev/null
+++ b/libjava/gnu/java/nio/channels/natFileChannelWin32.cc
@@ -0,0 +1,466 @@
+// natFileChannelImplWin32.cc - Native part of FileChannelImpl class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// FIXME: In order to support interrupting of IO operations, we
+// need to change to use the windows asynchronous IO functions
+
+#include <config.h>
+#include <platform.h>
+
+#include <gcj/cni.h>
+#include <gcj/javaprims.h>
+#include <jvm.h>
+
+#include <stdio.h>
+
+#include <gnu/gcj/RawData.h>
+#include <gnu/java/nio/FileLockImpl.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+#include <java/io/FileNotFoundException.h>
+#include <java/io/IOException.h>
+#include <java/io/SyncFailedException.h>
+#include <java/io/InterruptedIOException.h>
+#include <java/io/EOFException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/System.h>
+#include <java/lang/String.h>
+#include <java/lang/Thread.h>
+#include <java/nio/ByteBuffer.h>
+#include <java/nio/MappedByteBufferImpl.h>
+#include <java/nio/channels/FileChannel.h>
+#include <java/nio/channels/FileLock.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+
+using gnu::gcj::RawData;
+using java::io::IOException;
+using java::nio::MappedByteBufferImpl;
+using java::io::InterruptedIOException;
+using java::io::FileNotFoundException;
+using java::lang::ArrayIndexOutOfBoundsException;
+using gnu::java::nio::channels::FileChannelImpl;
+
+#undef STRICT
+
+static bool testCanUseGetHandleInfo()
+{
+ /* Test to see whether GetHandleInformation can be used
+ for console input or screen buffers. This is better
+ a kludgy OS version check. */
+ DWORD dwFlags;
+ return GetHandleInformation (GetStdHandle (STD_INPUT_HANDLE),
+ &dwFlags) != 0;
+}
+
+// FIXME: casting a FILE (pointer) to a jint will not work on Win64 --
+// we should be using gnu.gcj.RawData's.
+
+void
+FileChannelImpl::init(void)
+{
+ in = new FileChannelImpl((jint)(GetStdHandle (STD_INPUT_HANDLE)),
+ FileChannelImpl::READ);
+ out = new FileChannelImpl((jint)(GetStdHandle (STD_OUTPUT_HANDLE)),
+ FileChannelImpl::WRITE);
+ err = new FileChannelImpl((jint)(GetStdHandle (STD_ERROR_HANDLE)),
+ FileChannelImpl::WRITE);
+}
+
+#if 0
+FileChannelImpl::sync (void) {
+ if (! FlushFileBuffers ((HANDLE)fd))
+ {
+ DWORD dwErrorCode = GetLastError ();
+ throw new SyncFailedException (_Jv_WinStrError (dwErrorCode));
+ }
+}
+#endif
+
+jint
+FileChannelImpl::open (jstring path, jint jflags) {
+
+ HANDLE handle = NULL;
+ DWORD access = 0;
+ DWORD create = OPEN_EXISTING;
+
+ JV_TEMP_STRING_WIN32(cpath, path)
+
+ JvAssert((jflags & READ) || (jflags & WRITE));
+
+ if ((jflags & READ) && (jflags & WRITE))
+ {
+ access = GENERIC_READ | GENERIC_WRITE;
+ if (jflags & EXCL)
+ create = CREATE_NEW; // this will raise error if file exists.
+ else
+ create = OPEN_ALWAYS; // equivalent to O_CREAT
+ }
+ else if (jflags & READ)
+ {
+ access = GENERIC_READ;
+ create = OPEN_EXISTING; // ignore EXCL
+ }
+ else
+ {
+ access = GENERIC_WRITE;
+ if (jflags & EXCL)
+ create = CREATE_NEW;
+ else if (jflags & APPEND)
+ create = OPEN_ALWAYS;
+ else
+ create = CREATE_ALWAYS;
+ }
+
+ handle = CreateFile(cpath, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, create, 0, NULL);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ DWORD dwErrorCode = GetLastError ();
+ throw new FileNotFoundException (_Jv_WinStrError (cpath, dwErrorCode));
+ }
+
+ // For APPEND mode, move the file pointer to the end of the file.
+ if (jflags & APPEND)
+ {
+ DWORD low = SetFilePointer (handle, 0, NULL, FILE_END);
+ if ((low == (DWORD) 0xffffffff) && (GetLastError () != NO_ERROR))
+ {
+ DWORD dwErrorCode = GetLastError ();
+ throw new FileNotFoundException (_Jv_WinStrError (cpath, dwErrorCode));
+ }
+ }
+
+ // Make this handle non-inheritable so that child
+ // processes don't inadvertently prevent us from
+ // closing this file.
+ _Jv_platform_close_on_exec (handle);
+
+ return (jint) handle;
+}
+
+void
+FileChannelImpl::write (jint b)
+{
+ DWORD bytesWritten;
+ jbyte buf = (jbyte)b;
+
+ if (WriteFile ((HANDLE)fd, &buf, 1, &bytesWritten, NULL))
+ {
+ if (::java::lang::Thread::interrupted())
+ {
+ InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
+ iioe->bytesTransferred = bytesWritten;
+ throw iioe;
+ }
+ if (bytesWritten != 1)
+ _Jv_ThrowIOException ();
+ }
+ else
+ _Jv_ThrowIOException ();
+ // FIXME: loop until bytesWritten == 1
+}
+
+void
+FileChannelImpl::write(jbyteArray b, jint offset, jint len)
+{
+ if (! b)
+ throw new ::java::lang::NullPointerException;
+ if(offset < 0 || len < 0 || offset + len > JvGetArrayLength (b))
+ throw new ArrayIndexOutOfBoundsException;
+
+ jbyte *buf = elements (b) + offset;
+ DWORD bytesWritten;
+
+ if (WriteFile ((HANDLE)fd, buf, len, &bytesWritten, NULL))
+ {
+ if (::java::lang::Thread::interrupted())
+ {
+ InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
+ iioe->bytesTransferred = bytesWritten;
+ throw iioe;
+ }
+ }
+ else
+ _Jv_ThrowIOException ();
+ // FIXME: loop until bytesWritten == len
+}
+
+void
+FileChannelImpl::implCloseChannel (void)
+{
+ HANDLE save = (HANDLE)fd;
+ fd = (jint)INVALID_HANDLE_VALUE;
+ if (! CloseHandle (save))
+ _Jv_ThrowIOException ();
+}
+
+void
+FileChannelImpl::implTruncate (jlong size)
+{
+ LONG liOrigFilePointer;
+ LONG liNewFilePointer;
+ LONG liEndFilePointer;
+
+ // Get the original file pointer.
+ if (SetFilePointer((HANDLE) fd, (LONG) 0, &liOrigFilePointer,
+ FILE_CURRENT) != (BOOL) 0
+ && (GetLastError() != NO_ERROR))
+ _Jv_ThrowIOException ();
+
+ // Get the length of the file.
+ if (SetFilePointer((HANDLE) fd, (LONG) 0, &liEndFilePointer,
+ FILE_END) != (BOOL) 0
+ && (GetLastError() != NO_ERROR))
+ _Jv_ThrowIOException ();
+
+ if ((jlong)liEndFilePointer == size)
+ {
+ // Restore the file pointer.
+ if (liOrigFilePointer != liEndFilePointer)
+ {
+ if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer,
+ FILE_BEGIN) != (BOOL) 0
+ && (GetLastError() != NO_ERROR))
+ _Jv_ThrowIOException ();
+ }
+ return;
+ }
+
+ // Seek to the new end of file.
+ if (SetFilePointer((HANDLE) fd, (LONG) size, &liNewFilePointer,
+ FILE_BEGIN) != (BOOL) 0
+ && (GetLastError() != NO_ERROR))
+ _Jv_ThrowIOException ();
+
+ // Truncate the file at this point.
+ if (SetEndOfFile((HANDLE) fd) != (BOOL) 0 && (GetLastError() != NO_ERROR))
+ _Jv_ThrowIOException ();
+
+ if (liOrigFilePointer < liNewFilePointer)
+ {
+ // Restore the file pointer.
+ if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer,
+ FILE_BEGIN) != (BOOL) 0
+ && (GetLastError() != NO_ERROR))
+ _Jv_ThrowIOException ();
+ }
+}
+
+void
+FileChannelImpl::seek (jlong newPos)
+{
+ LONG high = pos >> 32;
+ DWORD low = SetFilePointer ((HANDLE)fd, (DWORD)(0xffffffff & newPos), &high, FILE_BEGIN);
+ if ((low == 0xffffffff) && (GetLastError () != NO_ERROR))
+ _Jv_ThrowIOException ();
+}
+
+jlong
+FileChannelImpl::implPosition (void)
+{
+ LONG high = 0;
+ DWORD low = SetFilePointer ((HANDLE)fd, 0, &high, FILE_CURRENT);
+ if ((low == 0xffffffff) && (GetLastError() != NO_ERROR))
+ _Jv_ThrowIOException ();
+ return (((jlong)high) << 32L) | (jlong)low;
+}
+
+jlong
+FileChannelImpl::size (void)
+{
+ DWORD high;
+ DWORD low;
+
+ low = GetFileSize ((HANDLE)fd, &high);
+ // FIXME: Error checking
+ return (((jlong)high) << 32L) | (jlong)low;
+}
+
+jint
+FileChannelImpl::read (void)
+{
+ CHAR buf;
+ DWORD read;
+
+ if (! ReadFile ((HANDLE)fd, &buf, 1, &read, NULL))
+ {
+ if (GetLastError () == ERROR_BROKEN_PIPE)
+ return -1;
+ else
+ _Jv_ThrowIOException ();
+ }
+
+ if (! read)
+ return -1;
+ else
+ return (jint)(buf & 0xff);
+}
+
+jint
+FileChannelImpl::read (jbyteArray buffer, jint offset, jint count)
+{
+ if (! buffer)
+ throw new ::java::lang::NullPointerException;
+
+ jsize bsize = JvGetArrayLength (buffer);
+ if (offset < 0 || count < 0 || offset + count > bsize)
+ throw new ArrayIndexOutOfBoundsException;
+
+ // Must return 0 if an attempt is made to read 0 bytes.
+ if (count == 0)
+ return 0;
+
+ jbyte *bytes = elements (buffer) + offset;
+
+ DWORD read;
+ if (! ReadFile((HANDLE)fd, bytes, count, &read, NULL))
+ {
+ if (GetLastError () == ERROR_BROKEN_PIPE)
+ return -1;
+ else
+ _Jv_ThrowIOException ();
+ }
+
+ if (read == 0) return -1;
+
+ return (jint)read;
+}
+
+jint
+FileChannelImpl::available (void)
+{
+ // FIXME:
+ return size() - position();
+}
+
+jboolean
+FileChannelImpl::lock (jlong pos, jlong len, jboolean shared, jboolean wait)
+{
+ DWORD flags = 0;
+ OVERLAPPED ovlpd;
+
+ ZeroMemory(&ovlpd,sizeof(OVERLAPPED));
+
+ if(!shared)
+ flags |= LOCKFILE_EXCLUSIVE_LOCK;
+ if(!wait)
+ flags |= LOCKFILE_FAIL_IMMEDIATELY;
+
+ ovlpd.Offset = (DWORD)pos;
+ ovlpd.OffsetHigh = pos>>32;
+
+ DWORD lenlow = (DWORD)len;
+ DWORD lenhigh = len>>32;
+
+ BOOL ret = LockFileEx((HANDLE)fd,flags,0,lenlow,lenhigh,&ovlpd);
+
+ if(ret==ERROR_IO_PENDING && !shared && wait)
+ ret = GetOverlappedResult((HANDLE)fd,&ovlpd,NULL,wait);
+
+ if(!ret)
+ _Jv_ThrowIOException(GetLastError());
+
+ return true;
+}
+
+void
+FileChannelImpl::unlock (jlong pos, jlong len)
+{
+ OVERLAPPED ovlpd;
+
+ ZeroMemory(&ovlpd,sizeof(OVERLAPPED));
+
+ ovlpd.Offset = (DWORD)pos;
+ ovlpd.OffsetHigh = pos>>32;
+
+ DWORD lenlow = (DWORD)len;
+ DWORD lenhigh = len>>32;
+
+ BOOL ret = UnlockFileEx((HANDLE)fd,0,lenlow,lenhigh,&ovlpd);
+
+ if(!ret)
+ _Jv_ThrowIOException(GetLastError());
+}
+
+java::nio::MappedByteBuffer *
+FileChannelImpl::mapImpl (jchar mmode, jlong position, jint size)
+{
+ SYSTEM_INFO siSysInfo;
+ GetSystemInfo(&siSysInfo);
+ DWORD page_size = siSysInfo.dwPageSize;
+ jlong offset = position & ~(page_size-1);
+ jint align = position - offset;
+ jlong high = position + size;
+ jlong max_size;
+ if (mmode == '+')
+ max_size = high - offset;
+ else
+ max_size = 0;
+ DWORD access, protect;
+ if (mmode == 'r')
+ {
+ access = FILE_MAP_READ;
+ protect = PAGE_READONLY;
+ }
+ else if (mmode == '+')
+ {
+ access = FILE_MAP_WRITE;
+ protect = PAGE_READWRITE;
+ }
+ else
+ {
+ access = FILE_MAP_COPY;
+ protect = PAGE_WRITECOPY;
+ }
+ HANDLE hFileMapping = CreateFileMapping((HANDLE) fd,
+ (LPSECURITY_ATTRIBUTES) NULL,
+ protect,
+ (DWORD) (max_size >> 32),
+ (DWORD) max_size,
+ (LPCTSTR) NULL);
+ if (hFileMapping == NULL)
+ throw new IOException();
+ void *ptr = MapViewOfFile(hFileMapping, access,
+ (DWORD) (offset >> 32), (DWORD) offset,
+ (SIZE_T) (high - offset));
+ if (ptr == NULL)
+ throw new IOException();
+ MappedByteBufferImpl *buf
+ = new MappedByteBufferImpl((RawData *) ((char *) ptr + align),
+ size, mode == 'r');
+ buf->implPtr = reinterpret_cast<RawData*> (ptr);
+ buf->implLen = (jlong) (size_t) hFileMapping;
+ return buf;
+}
+
+void
+MappedByteBufferImpl::unmapImpl ()
+{
+ UnmapViewOfFile((void*)implPtr);
+ CloseHandle((HANDLE) (size_t) implLen);
+}
+
+void
+MappedByteBufferImpl::loadImpl ()
+{
+}
+
+jboolean
+MappedByteBufferImpl::isLoadedImpl ()
+{
+ return true;
+}
+
+void
+MappedByteBufferImpl::forceImpl ()
+{
+}