blob: 823b72f7ef0b34df83f76cfc96542efe7b4e3616 [file] [log] [blame]
/*
* 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<char*>(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;
}