1/* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "JavaInputStream.h" 9 10JavaInputStream::JavaInputStream( 11 JNIEnv* env, jbyteArray javaBuffer, jobject inputStream) 12 : fEnv(env) 13 , fStartIndex(0) 14 , fEndIndex(0) { 15 SkASSERT(inputStream); 16 SkASSERT(javaBuffer); 17 fInputStream = inputStream; 18 fJavaBuffer = javaBuffer; 19 fInputStreamClass = env->FindClass("java/io/InputStream"); 20 SkASSERT(fInputStreamClass); 21 fReadMethodID = env->GetMethodID(fInputStreamClass, "read", "([B)I"); 22 SkASSERT(fReadMethodID); 23} 24 25bool JavaInputStream::isAtEnd() const { return fStartIndex == fEndIndex; } 26 27size_t JavaInputStream::read(void* voidBuffer, size_t size) { 28 size_t totalRead = 0; 29 char* buffer = static_cast<char*>(voidBuffer); // may be NULL; 30 while (size) { 31 // make sure the cache has at least one byte or is done. 32 if (fStartIndex == fEndIndex) { 33 jint count = 34 fEnv->CallIntMethod(fInputStream, fReadMethodID, fJavaBuffer); 35 if (fEnv->ExceptionCheck()) { 36 fEnv->ExceptionDescribe(); 37 fEnv->ExceptionClear(); 38 SkDebugf("---- java.io.InputStream::read() threw an exception\n"); 39 return 0; 40 } 41 fStartIndex = 0; 42 fEndIndex = count; 43 if (this->isAtEnd()) { 44 return totalRead; // No more to read. 45 } 46 } 47 SkASSERT(fEndIndex > fStartIndex); 48 size_t length = SkTMin(SkToSizeT(fEndIndex - fStartIndex), size); 49 if (buffer && length) { 50 jbyte* bufferElements 51 = fEnv->GetByteArrayElements(fJavaBuffer, NULL); 52 memcpy(buffer, &bufferElements[fStartIndex], length); 53 buffer += length; 54 fEnv->ReleaseByteArrayElements(fJavaBuffer, bufferElements, 0); 55 } 56 totalRead += length; 57 size -= length; 58 fStartIndex += length; 59 } 60 return totalRead; 61} 62