コード例 #1
0
ファイル: SDL_android.cpp プロジェクト: orionpax/socoolpal
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;
}
コード例 #2
0
ファイル: SDL_android.cpp プロジェクト: orionpax/socoolpal
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;
}
コード例 #3
0
ファイル: SDL_android.cpp プロジェクト: IronYan/kudou-player
static int Android_JNI_FileClose(SDL_RWops* ctx, bool release)
{
    int result = 0;

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

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

        // 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;
}
コード例 #4
0
static int Android_JNI_FileClose(SDL_RWops* ctx, bool release)
{
    JNIEnv *env = 0;
    int result = 0;

    if (mJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("Failed to get the environment using GetEnv(); assuming main thread");
        env = mEnv;
    }

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

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

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

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

    return result;
}
コード例 #5
0
ファイル: SDL_android.cpp プロジェクト: mozeal/SDL2
extern "C" size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
        size_t size, size_t maxnum)
{
    LocalReferenceHolder refs(__FUNCTION__);

    if (ctx->hidden.androidio.assetFileDescriptorRef) {
        size_t bytesMax = size * maxnum;
        if (ctx->hidden.androidio.size != -1 /*UNKNOWN_LENGTH*/ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) {
            bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position;
        }
        size_t result = read(ctx->hidden.androidio.fd, buffer, bytesMax );
        if (result > 0) {
            ctx->hidden.androidio.position += result;
            return result / size;
        }
        return 0;
    } else {
        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;
    }
}
コード例 #6
0
extern "C" size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
        size_t size, size_t maxnum)
{
    JNIEnv *env = 0;
    int bytesRemaining = size * maxnum;
    int bytesRead = 0;

    if (mJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("Failed to get the environment using GetEnv(); assuming main thread");
        env = mEnv;
    }

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

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

        if (Android_JNI_ExceptionOccurred(env)) {
            env->DeleteLocalRef(byteBuffer);
            return 0;
        }

        if (result < 0) {
            break;
        }

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

    env->DeleteLocalRef(byteBuffer);

    return bytesRead / size;
}
コード例 #7
0
ファイル: SDL_android.cpp プロジェクト: orionpax/socoolpal
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;
}
コード例 #8
0
ファイル: SDL_android.cpp プロジェクト: mozeal/SDL2
static int Android_JNI_FileOpen(SDL_RWops* ctx)
{
    LocalReferenceHolder refs(__FUNCTION__);
    int result = 0;

    jmethodID mid;
    jobject context;
    jobject assetManager;
    jobject inputStream;
    jclass channels;
    jobject readableByteChannel;
    jstring fileNameJString;
    jobject fd;
    jclass fdCls;
    jfieldID descriptor;

    JNIEnv *mEnv = Android_JNI_GetEnv();
    if (!refs.init(mEnv)) {
        goto failure;
    }

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

    // 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);

    /* First let's try opening the file to obtain an AssetFileDescriptor.
    * This method reads the files directly from the APKs using standard *nix calls
    */
    mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
    inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString);
    if (Android_JNI_ExceptionOccurred(true)) {
        goto fallback;
    }

    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getStartOffset", "()J");
    ctx->hidden.androidio.offset = mEnv->CallLongMethod(inputStream, mid);
    if (Android_JNI_ExceptionOccurred(true)) {
        goto fallback;
    }

    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getDeclaredLength", "()J");
    ctx->hidden.androidio.size = mEnv->CallLongMethod(inputStream, mid);
    if (Android_JNI_ExceptionOccurred(true)) {
        goto fallback;
    }

    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getFileDescriptor", "()Ljava/io/FileDescriptor;");
    fd = mEnv->CallObjectMethod(inputStream, mid);
    fdCls = mEnv->GetObjectClass(fd);
    descriptor = mEnv->GetFieldID(fdCls, "descriptor", "I");
    ctx->hidden.androidio.fd = mEnv->GetIntField(fd, descriptor);
    ctx->hidden.androidio.assetFileDescriptorRef = mEnv->NewGlobalRef(inputStream);

    // Seek to the correct offset in the file.
    lseek(ctx->hidden.androidio.fd, (off_t)ctx->hidden.androidio.offset, SEEK_SET);

    if (false) {
fallback:
        //__android_log_print(ANDROID_LOG_DEBUG, "SDL", "Falling back to legacy InputStream method for opening file");
        /* Try the old method using InputStream */
        ctx->hidden.androidio.assetFileDescriptorRef = NULL;

        // inputStream = assetManager.open(<filename>);
        mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager),
                "open", "(Ljava/lang/String;I)Ljava/io/InputStream;");
        inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString, 1 /*ACCESS_RANDOM*/);
        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 = (long)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;
    }

    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);
        }

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

    }

    return result;
}
コード例 #9
0
static int Android_JNI_FileOpen(SDL_RWops* ctx)
{
    JNIEnv *env = 0;
    int result = 0;

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

    bool allocatedLocalFrame = false;

    if (mJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("Failed to get the environment using GetEnv(); assuming main thread");
        env = mEnv;
    }

    if (env->PushLocalFrame(16) < 0) {
        SDL_SetError("Failed to allocate enough JVM local references");
        goto failure;
    } else {
        allocatedLocalFrame = true;
    }

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

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

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

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

    ctx->hidden.androidio.inputStream = inputStream;
    ctx->hidden.androidio.inputStreamRef = env->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 = env->GetMethodID(env->GetObjectClass(inputStream),
            "available", "()I");
    ctx->hidden.androidio.size = env->CallIntMethod(inputStream, mid);
    if (Android_JNI_ExceptionOccurred(env)) {
        goto failure;
    }

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

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

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

    ctx->hidden.androidio.position = 0;

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

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

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

    if (allocatedLocalFrame) {
        env->PopLocalFrame(NULL);
    }

    return result;
}