summaryrefslogtreecommitdiffstats
path: root/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit54b6cfa9a9e5b861a9930af873580d6dc20f773c (patch)
tree35051494d2af230dce54d6b31c6af8fc24091316 /core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
downloadframeworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.zip
frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.gz
frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.bz2
Initial Contribution
Diffstat (limited to 'core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp')
-rw-r--r--core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
new file mode 100644
index 0000000..002fdf9
--- /dev/null
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -0,0 +1,212 @@
+#include "CreateJavaOutputStreamAdaptor.h"
+
+#define RETURN_NULL_IF_NULL(value) \
+ do { if (!(value)) { SkASSERT(0); return NULL; } } while (false)
+
+static jclass gInputStream_Clazz;
+static jmethodID gInputStream_resetMethodID;
+static jmethodID gInputStream_availableMethodID;
+static jmethodID gInputStream_readMethodID;
+static jmethodID gInputStream_skipMethodID;
+
+class JavaInputStreamAdaptor : public SkStream {
+public:
+ JavaInputStreamAdaptor(JNIEnv* env, jobject js, jbyteArray ar)
+ : fEnv(env), fJavaInputStream(js), fJavaByteArray(ar) {
+ SkASSERT(ar);
+ fCapacity = env->GetArrayLength(ar);
+ SkASSERT(fCapacity > 0);
+ fBytesRead = 0;
+ }
+
+ virtual bool rewind() {
+ JNIEnv* env = fEnv;
+
+ fBytesRead = 0;
+
+ env->CallVoidMethod(fJavaInputStream, gInputStream_resetMethodID);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ printf("------- reset threw an exception\n");
+ return false;
+ }
+ return true;
+ }
+
+ virtual size_t read(void* buffer, size_t size) {
+ JNIEnv* env = fEnv;
+
+ if (buffer == NULL && size == 0) {
+ jint avail = env->CallIntMethod(fJavaInputStream,
+ gInputStream_availableMethodID);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ printf("------- available threw an exception\n");
+ avail = 0;
+ }
+ return avail;
+ }
+
+ size_t bytesRead = 0;
+
+ if (buffer == NULL) { // skip
+ jlong skipped = env->CallLongMethod(fJavaInputStream,
+ gInputStream_skipMethodID, (jlong)size);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ printf("------- available threw an exception\n");
+ return 0;
+ }
+ if (skipped < 0) {
+ return 0;
+ }
+ return (size_t)skipped;
+ }
+
+ // read the bytes
+ do {
+ size_t requested = size;
+ if (requested > fCapacity)
+ requested = fCapacity;
+
+ jint n = env->CallIntMethod(fJavaInputStream,
+ gInputStream_readMethodID, fJavaByteArray, 0, requested);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ printf("---- read threw an exception\n");
+ return 0;
+ }
+
+ if (n <= 0) {
+ break; // eof
+ }
+
+ jbyte* array = env->GetByteArrayElements(fJavaByteArray, NULL);
+ memcpy(buffer, array, n);
+ env->ReleaseByteArrayElements(fJavaByteArray, array, 0);
+
+ buffer = (void*)((char*)buffer + n);
+ bytesRead += n;
+ size -= n;
+ fBytesRead += n;
+ } while (size != 0);
+
+ return bytesRead;
+ }
+
+private:
+ JNIEnv* fEnv;
+ jobject fJavaInputStream; // the caller owns this object
+ jbyteArray fJavaByteArray; // the caller owns this object
+ size_t fCapacity;
+ size_t fBytesRead;
+};
+
+SkStream* CreateJavaInputStreamAdaptor(JNIEnv* env, jobject stream,
+ jbyteArray storage) {
+ static bool gInited;
+
+ if (!gInited) {
+ gInputStream_Clazz = env->FindClass("java/io/InputStream");
+ RETURN_NULL_IF_NULL(gInputStream_Clazz);
+ gInputStream_Clazz = (jclass)env->NewGlobalRef(gInputStream_Clazz);
+
+ gInputStream_resetMethodID = env->GetMethodID(gInputStream_Clazz,
+ "reset", "()V");
+ gInputStream_availableMethodID = env->GetMethodID(gInputStream_Clazz,
+ "available", "()I");
+ gInputStream_readMethodID = env->GetMethodID(gInputStream_Clazz,
+ "read", "([BII)I");
+ gInputStream_skipMethodID = env->GetMethodID(gInputStream_Clazz,
+ "skip", "(J)J");
+
+ RETURN_NULL_IF_NULL(gInputStream_resetMethodID);
+ RETURN_NULL_IF_NULL(gInputStream_availableMethodID);
+ RETURN_NULL_IF_NULL(gInputStream_availableMethodID);
+ RETURN_NULL_IF_NULL(gInputStream_skipMethodID);
+
+ gInited = true;
+ }
+
+ return new JavaInputStreamAdaptor(env, stream, storage);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static jclass gOutputStream_Clazz;
+static jmethodID gOutputStream_writeMethodID;
+static jmethodID gOutputStream_flushMethodID;
+
+class SkJavaOutputStream : public SkWStream {
+public:
+ SkJavaOutputStream(JNIEnv* env, jobject stream, jbyteArray storage)
+ : fEnv(env), fJavaOutputStream(stream), fJavaByteArray(storage) {
+ fCapacity = env->GetArrayLength(storage);
+ }
+
+ virtual bool write(const void* buffer, size_t size) {
+ JNIEnv* env = fEnv;
+ jbyteArray storage = fJavaByteArray;
+
+ while (size > 0) {
+ size_t requested = size;
+ if (requested > fCapacity) {
+ requested = fCapacity;
+ }
+
+ jbyte* array = env->GetByteArrayElements(storage, NULL);
+ memcpy(array, buffer, requested);
+ env->ReleaseByteArrayElements(storage, array, 0);
+
+ fEnv->CallVoidMethod(fJavaOutputStream, gOutputStream_writeMethodID,
+ storage, 0, requested);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ printf("------- write threw an exception\n");
+ return false;
+ }
+
+ buffer = (void*)((char*)buffer + requested);
+ size -= requested;
+ }
+ return true;
+ }
+
+ virtual void flush() {
+ fEnv->CallVoidMethod(fJavaOutputStream, gOutputStream_flushMethodID);
+ }
+
+private:
+ JNIEnv* fEnv;
+ jobject fJavaOutputStream; // the caller owns this object
+ jbyteArray fJavaByteArray; // the caller owns this object
+ size_t fCapacity;
+};
+
+SkWStream* CreateJavaOutputStreamAdaptor(JNIEnv* env, jobject stream,
+ jbyteArray storage) {
+ static bool gInited;
+
+ if (!gInited) {
+ gOutputStream_Clazz = env->FindClass("java/io/OutputStream");
+ RETURN_NULL_IF_NULL(gOutputStream_Clazz);
+ gOutputStream_Clazz = (jclass)env->NewGlobalRef(gOutputStream_Clazz);
+
+ gOutputStream_writeMethodID = env->GetMethodID(gOutputStream_Clazz,
+ "write", "([BII)V");
+ RETURN_NULL_IF_NULL(gOutputStream_writeMethodID);
+ gOutputStream_flushMethodID = env->GetMethodID(gOutputStream_Clazz,
+ "flush", "()V");
+ RETURN_NULL_IF_NULL(gOutputStream_flushMethodID);
+
+ gInited = true;
+ }
+
+ return new SkJavaOutputStream(env, stream, storage);
+}
+