Skip to content

Commit

Permalink
native: FileOutputStream.writeBytes()
Browse files Browse the repository at this point in the history
Signed-off-by: imkiva <[email protected]>
  • Loading branch information
imkiva committed May 29, 2018
1 parent 6e36c8c commit 6cebf65
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/kivm/native/java_io_FileOutputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,56 @@
//

#include <kivm/kivm.h>
#include <kivm/oop/primitiveOop.h>
#include <kivm/oop/arrayOop.h>
#include <kivm/native/classNames.h>
#include <kivm/bytecode/execution.h>
#include <unistd.h>
#include <cstring>
#include <kivm/memory/universe.h>

using namespace kivm;

JAVA_NATIVE void Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass java_io_FileOutputStream) {
D("java/io/FileOutputStream.initIDs()V");
}

JAVA_NATIVE void Java_java_io_FileOutputStream_writeBytes(JNIEnv *env, jobject javaOutputStream,
jbyteArray b, jint off, jint len, jboolean append) {
static auto CLASS = (InstanceKlass *) BootstrapClassLoader::get()
->loadClass(L"java/io/FileOutputStream");
static auto FD_CLASS = (InstanceKlass *) BootstrapClassLoader::get()
->loadClass(L"java/io/FileDescriptor");
static auto FD_FIELD = CLASS->getInstanceFieldInfo(CLASS->getName(), L"fd", L"Ljava/io/FileDescriptor;");
static auto FD_INT_FIELD = FD_CLASS->getInstanceFieldInfo(FD_CLASS->getName(), L"fd", L"I");

auto byteArray = Resolver::typeArray(b);
if (byteArray == nullptr) {
SHOULD_NOT_REACH_HERE();
}

if (byteArray->getLength() <= off && byteArray->getLength() < (off + len)) {
PANIC("java.lang.ArrayIndexOutOfBoundsException");
}

auto streamOop = Resolver::instance(javaOutputStream);
instanceOop fdOop = nullptr;
if (!streamOop->getFieldValue(FD_FIELD, (oop *) &fdOop)) {
SHOULD_NOT_REACH_HERE();
}

intOop fdInt = nullptr;
if (!fdOop->getFieldValue(FD_INT_FIELD, (oop *) &fdInt)) {
SHOULD_NOT_REACH_HERE();
}

int fd = fdInt->getValue();
auto *buf = (char *) Universe::allocCObject(sizeof(char) * len);
for (int i = off, j = 0; i < off + len; i++, j++) {
buf[j] = (char) ((intOop) byteArray->getElementAt(i))->getValue();
}
if (write(fd, buf, (size_t) len) == -1) {
PANIC("java.lang.IOException");
}
Universe::deallocCObject(buf);
}

0 comments on commit 6cebf65

Please sign in to comment.