From 57f4463c4c7a8e602f069ed27b2e6a6fcc5455b3 Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Tue, 22 Jan 2013 21:10:16 +0200 Subject: [PATCH] RandomAccessFile --- classpath/java-io.cpp | 153 ++++++------------------ classpath/java/io/RandomAccessFile.java | 73 ++++++++--- 2 files changed, 90 insertions(+), 136 deletions(-) diff --git a/classpath/java-io.cpp b/classpath/java-io.cpp index 86020f57c8..b016c5c17a 100644 --- a/classpath/java-io.cpp +++ b/classpath/java-io.cpp @@ -155,69 +155,9 @@ doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length) } } + #ifdef PLATFORM_WINDOWS -class Mapping { - public: - Mapping(uint8_t* start, size_t length, HANDLE mapping, HANDLE file): - start(start), - length(length), - mapping(mapping), - file(file) - { } - - uint8_t* start; - size_t length; - HANDLE mapping; - HANDLE file; -}; - -inline Mapping* -map(JNIEnv* e, string_t path) -{ - Mapping* result = 0; - HANDLE file = CreateFileW(path, FILE_READ_DATA, - FILE_SHARE_READ | FILE_SHARE_WRITE, 0, - OPEN_EXISTING, 0, 0); - if (file != INVALID_HANDLE_VALUE) { - unsigned size = GetFileSize(file, 0); - if (size != INVALID_FILE_SIZE) { - HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, size, 0); - if (mapping) { - void* data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); - if (data) { - void* p = allocate(e, sizeof(Mapping)); - if (not e->ExceptionCheck()) { - result = new (p) - Mapping(static_cast(data), size, file, mapping); - } - } - - if (result == 0) { - CloseHandle(mapping); - } - } - } - - if (result == 0) { - CloseHandle(file); - } - } - if (result == 0 and not e->ExceptionCheck()) { - throwNew(e, "java/io/IOException", "%d", GetLastError()); - } - return result; -} - -inline void -unmap(JNIEnv*, Mapping* mapping) -{ - UnmapViewOfFile(mapping->start); - CloseHandle(mapping->mapping); - CloseHandle(mapping->file); - free(mapping); -} - class Directory { public: Directory(): handle(0), findNext(false) { } @@ -250,51 +190,9 @@ class Directory { #else // not PLATFORM_WINDOWS -class Mapping { - public: - Mapping(uint8_t* start, size_t length): - start(start), - length(length) - { } - - uint8_t* start; - size_t length; -}; - -inline Mapping* -map(JNIEnv* e, string_t path) -{ - Mapping* result = 0; - int fd = open(path, O_RDONLY); - if (fd != -1) { - struct stat s; - int r = fstat(fd, &s); - if (r != -1) { - void* data = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (data) { - void* p = allocate(e, sizeof(Mapping)); - if (not e->ExceptionCheck()) { - result = new (p) Mapping(static_cast(data), s.st_size); - } - } - } - close(fd); - } - if (result == 0 and not e->ExceptionCheck()) { - throwNewErrno(e, "java/io/IOException"); - } - return result; -} - -inline void -unmap(JNIEnv*, Mapping* mapping) -{ - munmap(mapping->start, mapping->length); - free(mapping); -} - #endif // not PLATFORM_WINDOWS + } // namespace inline string_t getChars(JNIEnv* e, jstring path) { @@ -785,35 +683,54 @@ Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path, { string_t chars = getChars(e, path); if (chars) { - Mapping* mapping = map(e, chars); + int fd = ::open((const char*)chars, O_RDONLY); + releaseChars(e, path, chars); + if (fd == -1) { + throwNewErrno(e, "java/io/IOException"); + return; + } + struct ::stat fileStats; + if(::fstat(fd, &fileStats) == -1) { + ::close(fd); + throwNewErrno(e, "java/io/IOException"); + return; + } - jlong peer = reinterpret_cast(mapping); + jlong peer = fd; e->SetLongArrayRegion(result, 0, 1, &peer); - jlong length = (mapping ? mapping->length : 0); + jlong length = fileStats.st_size; e->SetLongArrayRegion(result, 1, 1, &length); - - releaseChars(e, path, chars); } } -extern "C" JNIEXPORT void JNICALL -Java_java_io_RandomAccessFile_copy(JNIEnv* e, jclass, jlong peer, +extern "C" JNIEXPORT jint JNICALL +Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer, jlong position, jbyteArray buffer, int offset, int length) { + int fd = (int)peer; + if(::lseek(fd, position, SEEK_SET) == -1) { + throwNewErrno(e, "java/io/IOException"); + return -1; + } + uint8_t* dst = reinterpret_cast (e->GetPrimitiveArrayCritical(buffer, 0)); - - memcpy(dst + offset, - reinterpret_cast(peer)->start + position, - length); - + ssize_t bytesRead = ::read(fd, dst + offset, length); e->ReleasePrimitiveArrayCritical(buffer, dst, 0); + + if(bytesRead == -1) { + throwNewErrno(e, "java/io/IOException"); + return -1; + } + + return (jint)bytesRead; } extern "C" JNIEXPORT void JNICALL -Java_java_io_RandomAccessFile_close(JNIEnv* e, jclass, jlong peer) +Java_java_io_RandomAccessFile_close(JNIEnv*/* e*/, jclass, jlong peer) { - unmap(e, reinterpret_cast(peer)); + int fd = (int)peer; + ::close(fd); } diff --git a/classpath/java/io/RandomAccessFile.java b/classpath/java/io/RandomAccessFile.java index 6ed7eeaceb..18bacb99f3 100644 --- a/classpath/java/io/RandomAccessFile.java +++ b/classpath/java/io/RandomAccessFile.java @@ -10,6 +10,8 @@ package java.io; +import java.lang.IllegalArgumentException; + public class RandomAccessFile { private long peer; private File file; @@ -61,27 +63,62 @@ public class RandomAccessFile { this.position = position + count; return count; } - - public void readFully(byte[] buffer, int offset, int length) - throws IOException - { - if (peer == 0) throw new IOException(); - - if (length == 0) return; - - if (position + length > this.length) { - if (position + length > length()) throw new EOFException(); - } - - if (offset < 0 || offset + length > buffer.length) + + public int read(byte b[], int off, int len) throws IOException { + if(b == null) + throw new IllegalArgumentException(); + if (peer == 0) + throw new IOException(); + if(len == 0) + return 0; + if (position + len > this.length) + throw new EOFException(); + if (off < 0 || off + len > b.length) throw new ArrayIndexOutOfBoundsException(); - - copy(peer, position, buffer, offset, length); - - position += length; + int bytesRead = readBytes(peer, position, b, off, len); + position += bytesRead; + return bytesRead; + } + + public int read(byte b[]) throws IOException { + if(b == null) + throw new IllegalArgumentException(); + if (peer == 0) + throw new IOException(); + if(b.length == 0) + return 0; + if (position + b.length > this.length) + throw new EOFException(); + int bytesRead = readBytes(peer, position, b, 0, b.length); + position += bytesRead; + return bytesRead; } - private static native void copy(long peer, long position, byte[] buffer, + public void readFully(byte b[], int off, int len) throws IOException { + if(b == null) + throw new IllegalArgumentException(); + if (peer == 0) + throw new IOException(); + if(len == 0) + return; + if (position + len > this.length) + throw new EOFException(); + if (off < 0 || off + len > b.length) + throw new ArrayIndexOutOfBoundsException(); + int n = 0; + do { + int count = readBytes(peer, position, b, off + n, len - n); + if (count < 0) + throw new EOFException(); + n += count; + } while (n < len); + } + + public void readFully(byte b[]) throws IOException { + readFully(b, 0, b.length); + } + + private static native int readBytes(long peer, long position, byte[] buffer, int offset, int length); public void close() throws IOException {