1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
// Copyright 2023 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#ifdef ANDROID
#include <string>
#include <vector>
#include <fcntl.h>
#include <jni.h>
#define ANDROID_STORAGE_FUNCTIONS(V) \
V(CreateFile, bool, (const std::string& directory, const std::string& filename), create_file, \
"createFile", "(Ljava/lang/String;Ljava/lang/String;)Z") \
V(CreateDir, bool, (const std::string& directory, const std::string& filename), create_dir, \
"createDir", "(Ljava/lang/String;Ljava/lang/String;)Z") \
V(OpenContentUri, int, (const std::string& filepath, AndroidOpenMode openmode), \
open_content_uri, "openContentUri", "(Ljava/lang/String;Ljava/lang/String;)I") \
V(GetFilesName, std::vector<std::string>, (const std::string& filepath), get_files_name, \
"getFilesName", "(Ljava/lang/String;)[Ljava/lang/String;") \
V(CopyFile, bool, \
(const std::string& source, const std::string& destination_path, \
const std::string& destination_filename), \
copy_file, "copyFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z") \
V(RenameFile, bool, (const std::string& source, const std::string& filename), rename_file, \
"renameFile", "(Ljava/lang/String;Ljava/lang/String;)Z")
#define ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(V) \
V(IsDirectory, bool, is_directory, CallStaticBooleanMethod, "isDirectory", \
"(Ljava/lang/String;)Z") \
V(FileExists, bool, file_exists, CallStaticBooleanMethod, "fileExists", \
"(Ljava/lang/String;)Z") \
V(GetSize, std::uint64_t, get_size, CallStaticLongMethod, "getSize", "(Ljava/lang/String;)J") \
V(DeleteDocument, bool, delete_document, CallStaticBooleanMethod, "deleteDocument", \
"(Ljava/lang/String;)Z")
namespace AndroidStorage {
static JavaVM* g_jvm = nullptr;
static jclass native_library = nullptr;
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID)
#define F(JMethodID) static jmethodID JMethodID = nullptr;
ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
ANDROID_STORAGE_FUNCTIONS(FS)
#undef F
#undef FS
#undef FR
// Reference:
// https://developer.android.com/reference/android/os/ParcelFileDescriptor#parseMode(java.lang.String)
enum class AndroidOpenMode {
READ = O_RDONLY, // "r"
WRITE = O_WRONLY, // "w"
READ_WRITE = O_RDWR, // "rw"
WRITE_APPEND = O_WRONLY | O_APPEND, // "wa"
WRITE_TRUNCATE = O_WRONLY | O_TRUNC, // "wt
READ_WRITE_APPEND = O_RDWR | O_APPEND, // "rwa"
READ_WRITE_TRUNCATE = O_RDWR | O_TRUNC, // "rwt"
NEVER = EINVAL,
};
inline AndroidOpenMode operator|(AndroidOpenMode a, int b) {
return static_cast<AndroidOpenMode>(static_cast<int>(a) | b);
}
AndroidOpenMode ParseOpenmode(const std::string_view openmode);
void InitJNI(JNIEnv* env, jclass clazz);
void CleanupJNI();
#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) \
F(FunctionName, Parameters, ReturnValue)
#define F(FunctionName, Parameters, ReturnValue) ReturnValue FunctionName Parameters;
ANDROID_STORAGE_FUNCTIONS(FS)
#undef F
#undef FS
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
F(FunctionName, ReturnValue)
#define F(FunctionName, ReturnValue) ReturnValue FunctionName(const std::string& filepath);
ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
#undef F
#undef FR
} // namespace AndroidStorage
#endif
|