Skip to content

Commit bdb055f

Browse files
committed
Fix APK Resources archive file reading
1 parent 1e0608a commit bdb055f

File tree

1 file changed

+113
-80
lines changed

1 file changed

+113
-80
lines changed
Lines changed: 113 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,114 @@
1-
#ifndef _NBL_SYSTEM_C_APK_RESOURCES_ARCHIVE_LOADER_H_INCLUDED_
2-
#define _NBL_SYSTEM_C_APK_RESOURCES_ARCHIVE_LOADER_H_INCLUDED_
3-
#ifdef _NBL_PLATFORM_ANDROID_
4-
#include "nbl/system/IFileArchive.h"
5-
#include <jni.h>
6-
7-
namespace nbl::system
8-
{
9-
class CAPKResourcesArchive : public IFileArchive
10-
{
11-
using base_t = IFileArchive;
12-
AAssetManager* mgr;
13-
JNIEnv* env;
14-
ANativeActivity* activity;
15-
public:
16-
CAPKResourcesArchive(core::smart_refctd_ptr<ISystem>&& system, system::logger_opt_smart_ptr&& logger, AAssetManager* _mgr, ANativeActivity* act, JNIEnv* jni) :
17-
base_t(nullptr, std::move(system), std::move(logger)), mgr(_mgr), activity(act), env(jni)
18-
{
19-
auto assets = listAssets("");
20-
uint32_t index = 0;
21-
for (auto& a : assets)
22-
{
23-
addItem(a, index, 0, EAT_VIRTUAL_ALLOC);
24-
index++;
25-
}
26-
setFlagsVectorSize(m_files.size());
27-
}
28-
core::smart_refctd_ptr<IFile> readFile_impl(const SOpenFileParams& params) override
29-
{
30-
auto filename = params.filename;
31-
AAsset* asset = AAssetManager_open(mgr, filename.c_str(), AASSET_MODE_BUFFER);
32-
if (asset == nullptr) return nullptr;
33-
const void* buffer = AAsset_getBuffer(asset);
34-
size_t assetSize = AAsset_getLength(asset);
35-
auto fileView = make_smart_refctd_ptr <CFileView<VirtualAllocator>>(core::smart_refctd_ptr(m_system), params.absolutePath, IFile::ECF_READ, assetSize);
36-
37-
fileView->write_impl(buffer, 0, assetSize);
38-
AAsset_close(asset);
39-
return fileView;
40-
}
41-
std::vector<std::string> listAssets(const char* asset_path)
42-
{
43-
std::vector<std::string> result;
44-
45-
auto context_object = activity->clazz;
46-
auto getAssets_method = env->GetMethodID(env->GetObjectClass(context_object), "getAssets", "()Landroid/content/res/AssetManager;");
47-
auto assetManager_object = env->CallObjectMethod(context_object, getAssets_method);
48-
auto list_method = env->GetMethodID(env->GetObjectClass(assetManager_object), "list", "(Ljava/lang/String;)[Ljava/lang/String;");
49-
50-
jstring path_object = env->NewStringUTF(asset_path);
51-
52-
auto files_object = (jobjectArray)env->CallObjectMethod(assetManager_object, list_method, path_object);
53-
54-
env->DeleteLocalRef(path_object);
55-
56-
auto length = env->GetArrayLength(files_object);
57-
58-
for (int i = 0; i < length; i++)
59-
{
60-
jstring jstr = (jstring)env->GetObjectArrayElement(files_object, i);
61-
62-
const char* filename = env->GetStringUTFChars(jstr, nullptr);
63-
64-
if (filename != nullptr)
65-
{
66-
result.push_back(filename);
67-
env->ReleaseStringUTFChars(jstr, filename);
68-
}
69-
70-
env->DeleteLocalRef(jstr);
71-
}
72-
73-
return result;
74-
}
75-
76-
};
77-
}
78-
79-
80-
#endif
1+
#ifndef _NBL_SYSTEM_C_APK_RESOURCES_ARCHIVE_LOADER_H_INCLUDED_
2+
#define _NBL_SYSTEM_C_APK_RESOURCES_ARCHIVE_LOADER_H_INCLUDED_
3+
#ifdef _NBL_PLATFORM_ANDROID_
4+
#include "nbl/system/IFileArchive.h"
5+
#include <jni.h>
6+
7+
namespace nbl::system
8+
{
9+
class CAPKResourcesArchive : public IFileArchive
10+
{
11+
using base_t = IFileArchive;
12+
AAssetManager* mgr;
13+
JNIEnv* env;
14+
ANativeActivity* activity;
15+
jobject context_object;
16+
jmethodID getAssets_method;
17+
jobject assetManager_object;
18+
jmethodID list_method;
19+
public:
20+
CAPKResourcesArchive(core::smart_refctd_ptr<ISystem>&& system, system::logger_opt_smart_ptr&& logger, AAssetManager* _mgr, ANativeActivity* act, JNIEnv* jni) :
21+
base_t(nullptr, std::move(system), std::move(logger)), mgr(_mgr), activity(act), env(jni)
22+
{
23+
context_object = activity->clazz;
24+
getAssets_method = env->GetMethodID(env->GetObjectClass(context_object), "getAssets", "()Landroid/content/res/AssetManager;");
25+
assetManager_object = env->CallObjectMethod(context_object, getAssets_method);
26+
list_method = env->GetMethodID(env->GetObjectClass(assetManager_object), "list", "(Ljava/lang/String;)[Ljava/lang/String;");
27+
28+
auto assets = listAssetsRecursively("");
29+
uint32_t index = 0;
30+
for (auto& a : assets)
31+
{
32+
addItem(a, index, 0, EAT_VIRTUAL_ALLOC);
33+
index++;
34+
}
35+
setFlagsVectorSize(m_files.size());
36+
}
37+
core::smart_refctd_ptr<IFile> readFile_impl(const SOpenFileParams& params) override
38+
{
39+
auto filename = params.filename;
40+
AAsset* asset = AAssetManager_open(mgr, filename.c_str(), AASSET_MODE_BUFFER);
41+
if (asset == nullptr) return nullptr;
42+
const void* buffer = AAsset_getBuffer(asset);
43+
size_t assetSize = AAsset_getLength(asset);
44+
auto fileView = make_smart_refctd_ptr <CFileView<VirtualAllocator>>(core::smart_refctd_ptr(m_system), params.absolutePath, IFile::ECF_READ, assetSize);
45+
46+
fileView->write_impl(buffer, 0, assetSize);
47+
AAsset_close(asset);
48+
return fileView;
49+
}
50+
std::vector<std::string> listAssetsRecursively(const char* asset_path)
51+
{
52+
std::vector<std::string> curDirFiles = listAssets(asset_path), res;
53+
for (auto& p : curDirFiles)
54+
{
55+
if (std::filesystem::path(p).extension() == "" && std::filesystem::path(p) != "")
56+
{
57+
std::vector<std::string> recRes;
58+
if (std::string(asset_path) == "")
59+
{
60+
recRes = listAssetsRecursively(std::filesystem::path(p).string().c_str());
61+
}
62+
else
63+
{
64+
recRes = listAssetsRecursively((std::filesystem::path(asset_path) / p).string().c_str());
65+
}
66+
res.insert(res.end(), recRes.begin(), recRes.end());
67+
}
68+
}
69+
res.insert(res.end(), curDirFiles.begin(), curDirFiles.end());
70+
return res;
71+
}
72+
std::vector<std::string> listAssets(const char* asset_path)
73+
{
74+
std::vector<std::string> result;
75+
76+
jstring path_object = env->NewStringUTF(asset_path);
77+
78+
auto files_object = (jobjectArray)env->CallObjectMethod(assetManager_object, list_method, path_object);
79+
80+
env->DeleteLocalRef(path_object);
81+
82+
auto length = env->GetArrayLength(files_object);
83+
84+
for (int i = 0; i < length; i++)
85+
{
86+
jstring jstr = (jstring)env->GetObjectArrayElement(files_object, i);
87+
88+
const char* filename = env->GetStringUTFChars(jstr, nullptr);
89+
90+
if (filename != nullptr)
91+
{
92+
if (std::string(asset_path) == "")
93+
{
94+
result.push_back(filename);
95+
}
96+
else
97+
{
98+
result.push_back((std::filesystem::path(asset_path) / filename).generic_string());
99+
}
100+
env->ReleaseStringUTFChars(jstr, filename);
101+
}
102+
103+
env->DeleteLocalRef(jstr);
104+
}
105+
106+
return result;
107+
}
108+
109+
};
110+
}
111+
112+
113+
#endif
81114
#endif

0 commit comments

Comments
 (0)