/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "JavaInputStream.h" JavaInputStream::JavaInputStream( JNIEnv* env, jbyteArray javaBuffer, jobject inputStream) : fEnv(env) , fStartIndex(0) , fEndIndex(0) { SkASSERT(inputStream); SkASSERT(javaBuffer); fInputStream = inputStream; fJavaBuffer = javaBuffer; fInputStreamClass = env->FindClass("java/io/InputStream"); SkASSERT(fInputStreamClass); fReadMethodID = env->GetMethodID(fInputStreamClass, "read", "([B)I"); SkASSERT(fReadMethodID); } bool JavaInputStream::isAtEnd() const { return fStartIndex == fEndIndex; } size_t JavaInputStream::read(void* voidBuffer, size_t size) { size_t totalRead = 0; char* buffer = static_cast(voidBuffer); // may be NULL; while (size) { // make sure the cache has at least one byte or is done. if (fStartIndex == fEndIndex) { jint count = fEnv->CallIntMethod(fInputStream, fReadMethodID, fJavaBuffer); if (fEnv->ExceptionCheck()) { fEnv->ExceptionDescribe(); fEnv->ExceptionClear(); SkDebugf("---- java.io.InputStream::read() threw an exception\n"); return 0; } fStartIndex = 0; fEndIndex = count; if (this->isAtEnd()) { return totalRead; // No more to read. } } SkASSERT(fEndIndex > fStartIndex); size_t length = SkTMin(SkToSizeT(fEndIndex - fStartIndex), size); if (buffer && length) { jbyte* bufferElements = fEnv->GetByteArrayElements(fJavaBuffer, NULL); memcpy(buffer, &bufferElements[fStartIndex], length); buffer += length; fEnv->ReleaseByteArrayElements(fJavaBuffer, bufferElements, 0); } totalRead += length; size -= length; fStartIndex += length; } return totalRead; }