Esempio n. 1
0
static int Android_JNI_FileClose(SDL_RWops* ctx, bool release)
{
    LocalReferenceHolder refs;
    int result = 0;

    if (!refs.init(mEnv)) {
        SDL_SetError("Failed to allocate enough JVM local references");
        return -1;
    }

    if (ctx) {
        if (release) {
            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.fileNameRef);
        }

        jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef;

        // inputStream.close();
        jmethodID mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream),
                "close", "()V");
        mEnv->CallVoidMethod(inputStream, mid);
        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.inputStreamRef);
        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.readableByteChannelRef);
        if (Android_JNI_ExceptionOccurred()) {
            result = -1;
        }

        if (release) {
            SDL_FreeRW(ctx);
        }
    }

    return result;
}
Esempio n. 2
0
extern "C" size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
        size_t size, size_t maxnum)
{
    LocalReferenceHolder refs;
    int bytesRemaining = size * maxnum;
    int bytesRead = 0;

    if (!refs.init(mEnv)) {
        return -1;
    }

    jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
    jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
    jobject byteBuffer = mEnv->NewDirectByteBuffer(buffer, bytesRemaining);

    while (bytesRemaining > 0) {
        // result = readableByteChannel.read(...);
        int result = mEnv->CallIntMethod(readableByteChannel, readMethod, byteBuffer);

        if (Android_JNI_ExceptionOccurred()) {
            return 0;
        }

        if (result < 0) {
            break;
        }

        bytesRemaining -= result;
        bytesRead += result;
        ctx->hidden.androidio.position += result;
    }

    return bytesRead / size;
}
Esempio n. 3
0
extern "C" int Android_JNI_FileOpen(SDL_RWops* ctx,
        const char* fileName, const char*)
{
    LocalReferenceHolder refs;

    if (!refs.init(mEnv)) {
        return -1;
    }

    if (!ctx) {
        return -1;
    }

    jstring fileNameJString = mEnv->NewStringUTF(fileName);
    ctx->hidden.androidio.fileNameRef = mEnv->NewGlobalRef(fileNameJString);
    ctx->hidden.androidio.inputStreamRef = NULL;

    return Android_JNI_FileOpen(ctx);
}
Esempio n. 4
0
extern "C" size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
        size_t size, size_t maxnum)
{
    LocalReferenceHolder refs;
    jlong bytesRemaining = (jlong) (size * maxnum);
    jlong bytesMax = (jlong) (ctx->hidden.androidio.size -  ctx->hidden.androidio.position);
    int bytesRead = 0;

    /* Don't read more bytes than those that remain in the file, otherwise we get an exception */
    if (bytesRemaining >  bytesMax) bytesRemaining = bytesMax;

    JNIEnv *mEnv = Android_JNI_GetEnv();
    if (!refs.init(mEnv)) {
        return -1;
    }

    jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
    jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
    jobject byteBuffer = mEnv->NewDirectByteBuffer(buffer, bytesRemaining);

    while (bytesRemaining > 0) {
        // result = readableByteChannel.read(...);
        int result = mEnv->CallIntMethod(readableByteChannel, readMethod, byteBuffer);

        if (Android_JNI_ExceptionOccurred()) {
            return 0;
        }

        if (result < 0) {
            break;
        }

        bytesRemaining -= result;
        bytesRead += result;
        ctx->hidden.androidio.position += result;
    }

    return bytesRead / size;
}
Esempio n. 5
0
static int Android_JNI_FileOpen(SDL_RWops* ctx)
{
    LocalReferenceHolder refs;
    int result = 0;

    jmethodID mid;
    jobject context;
    jobject assetManager;
    jobject inputStream;
    jclass channels;
    jobject readableByteChannel;
    jstring fileNameJString;

    if (!refs.init(mEnv)) {
        goto failure;
    }

    fileNameJString = (jstring)ctx->hidden.androidio.fileNameRef;

    // context = SDLActivity.getContext();
    mid = mEnv->GetStaticMethodID(mActivityClass,
            "getContext","()Landroid/content/Context;");
    context = mEnv->CallStaticObjectMethod(mActivityClass, mid);

    // assetManager = context.getAssets();
    mid = mEnv->GetMethodID(mEnv->GetObjectClass(context),
            "getAssets", "()Landroid/content/res/AssetManager;");
    assetManager = mEnv->CallObjectMethod(context, mid);

    // inputStream = assetManager.open(<filename>);
    mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager),
            "open", "(Ljava/lang/String;)Ljava/io/InputStream;");
    inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString);
    if (Android_JNI_ExceptionOccurred()) {
        goto failure;
    }

    ctx->hidden.androidio.inputStreamRef = mEnv->NewGlobalRef(inputStream);

    // Despite all the visible documentation on [Asset]InputStream claiming
    // that the .available() method is not guaranteed to return the entire file
    // size, comments in <sdk>/samples/<ver>/ApiDemos/src/com/example/ ...
    // android/apis/content/ReadAsset.java imply that Android's
    // AssetInputStream.available() /will/ always return the total file size

    // size = inputStream.available();
    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream),
            "available", "()I");
    ctx->hidden.androidio.size = mEnv->CallIntMethod(inputStream, mid);
    if (Android_JNI_ExceptionOccurred()) {
        goto failure;
    }

    // readableByteChannel = Channels.newChannel(inputStream);
    channels = mEnv->FindClass("java/nio/channels/Channels");
    mid = mEnv->GetStaticMethodID(channels,
            "newChannel",
            "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;");
    readableByteChannel = mEnv->CallStaticObjectMethod(
            channels, mid, inputStream);
    if (Android_JNI_ExceptionOccurred()) {
        goto failure;
    }

    ctx->hidden.androidio.readableByteChannelRef =
        mEnv->NewGlobalRef(readableByteChannel);

    // Store .read id for reading purposes
    mid = mEnv->GetMethodID(mEnv->GetObjectClass(readableByteChannel),
            "read", "(Ljava/nio/ByteBuffer;)I");
    ctx->hidden.androidio.readMethod = mid;

    ctx->hidden.androidio.position = 0;

    if (false) {
failure:
        result = -1;

        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.fileNameRef);

        if(ctx->hidden.androidio.inputStreamRef != NULL) {
            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.inputStreamRef);
        }

        if(ctx->hidden.androidio.readableByteChannelRef != NULL) {
            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.readableByteChannelRef);
        }

    }

    return result;
}