static void * read_file_to_jni_array_impl(const char *filename) { char *buffer = NULL; size_t size = 0; if (apk_read_file(global.apklib_handle, filename, &buffer, &size) == APK_OK) { if(!global.use_dvm) { struct dummy_array *array = NULL; array = malloc(sizeof(*array)); if (array == NULL) return NULL; array->data = buffer; array->length = size; array->element_size = 1; return array; } else { const struct JNINativeInterface *env = global._env->functions; jarray *array = env->NewByteArray(ENV((&global)), size); jbyte *elements = env->GetByteArrayElements(ENV((&global)), array, 0); memcpy(elements, buffer, size); free(buffer); env->ReleaseByteArrayElements(ENV((&global)), array, elements, JNI_ABORT); return array; } } return NULL; }
static void * read_file_to_jni_array_impl(const char *filename) { struct dummy_array *array = NULL; char *buffer = NULL; size_t size = 0; if (apk_read_file(global.apklib_handle, filename, &buffer, &size) == APK_OK) { array = malloc(sizeof(*array)); if (array == NULL) return NULL; array->data = buffer; array->length = size; array->element_size = 1; } return array; }
static int read_file_impl(const char *filename, char **buffer, size_t *size) { return (apk_read_file(global.apklib_handle, filename, buffer, size) == APK_OK); }
enum ApkResult apk_read_resources(AndroidApk *apk, struct ResourceStrings *rstrings) { char *buf, *p, *p2, *p_end; char *values, *keys; struct ResTable_header *res_table_h; struct ResTable_package *res_table_package; struct ResChunk_header *chunk; struct ResStringPool_header *value_pool, *key_pool; struct ResTable_type *res_table; struct ResTable_entry *entry; struct Res_value *value; int *value_index, *key_index; size_t rstr_i, rstr_alloc; enum ApkResult ret; size_t size; assert(apk != NULL && rstrings != NULL); ret = apk_read_file(apk, "resources.arsc", &buf, &size); if (ret != APK_OK) { fprintf(stderr, "missing/bad resources.arsc\n"); return ret; } rstrings->count = rstr_i = 0; rstrings->app_name = NULL; rstrings->game_name = NULL; rstr_alloc = 32; rstrings->entries = malloc(rstr_alloc * sizeof(rstrings->entries[0])); if (rstrings->entries == NULL) { ret = APK_ERROR; goto out; } p = buf; res_table_h = (void *)p; assert(res_table_h->header.type == RES_TABLE_TYPE); p += res_table_h->header.headerSize; value_pool = (void *)p; assert(value_pool->header.type == RES_STRING_POOL_TYPE); value_index = (int *)(p + value_pool->header.headerSize); values = p + value_pool->stringsStart; p += value_pool->header.size; res_table_package = (void *)p; assert(res_table_package->header.type == RES_TABLE_PACKAGE_TYPE); key_pool = (void *)(p + res_table_package->keyStrings); p = (void *)key_pool; assert(key_pool->header.type == RES_STRING_POOL_TYPE); key_index = (int *)(p + key_pool->header.headerSize); keys = p + key_pool->stringsStart; p += key_pool->header.size; /* handle all ResTable chunks */ for (; p < buf + size; p += chunk->size) { chunk = (void *)p; if (chunk->type != RES_TABLE_TYPE_TYPE) continue; res_table = (void *)p; p2 = p + res_table->entriesStart; /* res_table->entryCount is unreliable? */ p_end = p + chunk->size; for (; p2 < p_end; p2 += entry->size + value->size) { entry = (void *)p2; value = (void *)(p2 + entry->size); if (entry->flags & ~FLAG_PUBLIC) { // printf("flags %x\n", entry->flags); break; } if (value->dataType != TYPE_STRING) { //printf(" type %x\n", value->dataType); // TODO: at least TYPE_INT_BOOLEAN might be useful continue; } if (entry->key.index >= key_pool->stringCount) { fprintf(stderr, "key index out of range: %u >= %u\n", entry->key.index, key_pool->stringCount); break; } if (value->data >= value_pool->stringCount) { fprintf(stderr, "value index out of range: %u >= %u\n", value->data, value_pool->stringCount); break; } rstrings->entries[rstr_i].key = apk_get_res_string( keys + key_index[entry->key.index], key_pool->flags & UTF8_FLAG); rstrings->entries[rstr_i].value = apk_get_res_string( values + value_index[value->data], value_pool->flags & UTF8_FLAG); if (rstrings->app_name==NULL && strcmp(rstrings->entries[rstr_i].key, "app_name") == 0) rstrings->app_name = rstrings->entries[rstr_i].value; if (rstrings->game_name==NULL && strcmp(rstrings->entries[rstr_i].key, "game_name") == 0) rstrings->game_name = rstrings->entries[rstr_i].value; rstr_i++; if (rstr_i >= rstr_alloc) { rstr_alloc *= 2; rstrings->entries = realloc(rstrings->entries, rstr_alloc * sizeof(rstrings->entries[0])); if (rstrings->entries == NULL) goto out; } } } rstrings->count = rstr_i; out: free(buf); return ret; }