@papyrus-sdk/engine-native 0.2.9 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -38
- package/android/build.gradle +41 -40
- package/android/consumer-rules.pro +1 -1
- package/android/src/main/cpp/CMakeLists.txt +42 -21
- package/android/src/main/cpp/papyrus_outline.cpp +108 -74
- package/android/src/main/cpp/papyrus_outline_loader.cpp +125 -0
- package/android/src/main/cpp/papyrus_outline_loader.h +48 -0
- package/android/src/main/cpp/papyrus_outline_loader_test.cpp +240 -0
- package/android/src/main/cpp/papyrus_text_search.cpp +408 -408
- package/android/src/main/java/android/support/v4/util/ArrayMap.java +18 -18
- package/android/src/main/java/com/papyrus/engine/PapyrusNativeEngineModule.java +37 -37
- package/android/src/main/java/com/papyrus/engine/PapyrusNativeEngineModule.kt +34 -34
- package/android/src/main/java/com/papyrus/engine/PapyrusOutline.java +33 -19
- package/android/src/test/java/com/papyrus/engine/PapyrusOutlineTest.java +40 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/ios/PapyrusEngineStore.h +16 -16
- package/ios/PapyrusEngineStore.m +48 -48
- package/package.json +60 -60
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#include "papyrus_outline_loader.h"
|
|
2
|
+
|
|
3
|
+
#include <cstdlib>
|
|
4
|
+
#include <cstring>
|
|
5
|
+
#include <iostream>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <unordered_map>
|
|
8
|
+
|
|
9
|
+
namespace {
|
|
10
|
+
|
|
11
|
+
using PdfiumSymbol = OutlineLoaderDeps::PdfiumSymbol;
|
|
12
|
+
|
|
13
|
+
struct FakeLoaderEnv {
|
|
14
|
+
void *library_handle = reinterpret_cast<void *>(0x1);
|
|
15
|
+
int dlopen_calls = 0;
|
|
16
|
+
int dlsym_calls = 0;
|
|
17
|
+
int dlclose_calls = 0;
|
|
18
|
+
std::unordered_map<std::string, PdfiumSymbol> symbols;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
FPDF_DOCUMENT FakeLoadDocument(const char *, const char *) {
|
|
22
|
+
return nullptr;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
void FakeCloseDocument(FPDF_DOCUMENT) {}
|
|
26
|
+
|
|
27
|
+
FPDF_BOOKMARK FakeBookmarkGetFirstChild(FPDF_DOCUMENT, FPDF_BOOKMARK) {
|
|
28
|
+
return nullptr;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
FPDF_BOOKMARK FakeBookmarkGetNextSibling(FPDF_DOCUMENT, FPDF_BOOKMARK) {
|
|
32
|
+
return nullptr;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
unsigned long FakeBookmarkGetTitle(FPDF_BOOKMARK, void *, unsigned long) {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
FPDF_DEST FakeBookmarkGetDest(FPDF_DOCUMENT, FPDF_BOOKMARK) {
|
|
40
|
+
return nullptr;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
int FakeDestGetPageIndex(FPDF_DOCUMENT, FPDF_DEST) {
|
|
44
|
+
return -1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
template <typename FnType>
|
|
48
|
+
PdfiumSymbol ToPdfiumSymbol(FnType fn) {
|
|
49
|
+
PdfiumSymbol symbol = nullptr;
|
|
50
|
+
static_assert(sizeof(symbol) == sizeof(fn),
|
|
51
|
+
"Expected function pointers to share the same size");
|
|
52
|
+
std::memcpy(&symbol, &fn, sizeof(symbol));
|
|
53
|
+
return symbol;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
PdfiumOutlineFns MakeCompleteOutlineFns() {
|
|
57
|
+
PdfiumOutlineFns fns = {};
|
|
58
|
+
fns.loadDocument = &FakeLoadDocument;
|
|
59
|
+
fns.closeDocument = &FakeCloseDocument;
|
|
60
|
+
fns.bookmarkGetFirstChild = &FakeBookmarkGetFirstChild;
|
|
61
|
+
fns.bookmarkGetNextSibling = &FakeBookmarkGetNextSibling;
|
|
62
|
+
fns.bookmarkGetTitle = &FakeBookmarkGetTitle;
|
|
63
|
+
fns.bookmarkGetDest = &FakeBookmarkGetDest;
|
|
64
|
+
fns.destGetPageIndex = &FakeDestGetPageIndex;
|
|
65
|
+
return fns;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
FakeLoaderEnv *GetEnv(void *user_data) {
|
|
69
|
+
return static_cast<FakeLoaderEnv *>(user_data);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void *FakeDlopen(void *user_data, const char *, int) {
|
|
73
|
+
FakeLoaderEnv *env = GetEnv(user_data);
|
|
74
|
+
env->dlopen_calls += 1;
|
|
75
|
+
return env->library_handle;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
PdfiumSymbol FakeDlsym(void *user_data, void *, const char *symbol_name) {
|
|
79
|
+
FakeLoaderEnv *env = GetEnv(user_data);
|
|
80
|
+
env->dlsym_calls += 1;
|
|
81
|
+
|
|
82
|
+
const auto it = env->symbols.find(symbol_name);
|
|
83
|
+
if (it == env->symbols.end()) {
|
|
84
|
+
return nullptr;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return it->second;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
int FakeDlclose(void *user_data, void *) {
|
|
91
|
+
FakeLoaderEnv *env = GetEnv(user_data);
|
|
92
|
+
env->dlclose_calls += 1;
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
OutlineLoaderDeps MakeDeps(FakeLoaderEnv *env) {
|
|
97
|
+
OutlineLoaderDeps deps = {};
|
|
98
|
+
deps.user_data = env;
|
|
99
|
+
deps.dlopen_fn = &FakeDlopen;
|
|
100
|
+
deps.dlsym_fn = &FakeDlsym;
|
|
101
|
+
deps.dlclose_fn = &FakeDlclose;
|
|
102
|
+
deps.library_name = "libmodpdfium.so";
|
|
103
|
+
deps.dlopen_flags = 0;
|
|
104
|
+
return deps;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void InstallSymbols(FakeLoaderEnv *env, const PdfiumOutlineFns &fns) {
|
|
108
|
+
env->symbols["FPDF_LoadDocument"] = ToPdfiumSymbol(fns.loadDocument);
|
|
109
|
+
env->symbols["FPDF_CloseDocument"] = ToPdfiumSymbol(fns.closeDocument);
|
|
110
|
+
env->symbols["FPDFBookmark_GetFirstChild"] = ToPdfiumSymbol(fns.bookmarkGetFirstChild);
|
|
111
|
+
env->symbols["FPDFBookmark_GetNextSibling"] = ToPdfiumSymbol(fns.bookmarkGetNextSibling);
|
|
112
|
+
env->symbols["FPDFBookmark_GetTitle"] = ToPdfiumSymbol(fns.bookmarkGetTitle);
|
|
113
|
+
env->symbols["FPDFBookmark_GetDest"] = ToPdfiumSymbol(fns.bookmarkGetDest);
|
|
114
|
+
env->symbols["FPDFDest_GetPageIndex"] = ToPdfiumSymbol(fns.destGetPageIndex);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
[[noreturn]] void Fail(const char *expression, const char *file, int line) {
|
|
118
|
+
std::cerr << file << ":" << line << ": assertion failed: " << expression << std::endl;
|
|
119
|
+
std::exit(1);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#define EXPECT_TRUE(condition) \
|
|
123
|
+
do { \
|
|
124
|
+
if (!(condition)) { \
|
|
125
|
+
Fail(#condition, __FILE__, __LINE__); \
|
|
126
|
+
} \
|
|
127
|
+
} while (false)
|
|
128
|
+
|
|
129
|
+
#define EXPECT_FALSE(condition) EXPECT_TRUE(!(condition))
|
|
130
|
+
|
|
131
|
+
#define EXPECT_EQ(expected, actual) \
|
|
132
|
+
do { \
|
|
133
|
+
const auto expected_value = (expected); \
|
|
134
|
+
const auto actual_value = (actual); \
|
|
135
|
+
if (!(expected_value == actual_value)) { \
|
|
136
|
+
std::cerr << __FILE__ << ":" << __LINE__ \
|
|
137
|
+
<< ": expected equality for " << #expected << " and " << #actual << std::endl; \
|
|
138
|
+
std::exit(1); \
|
|
139
|
+
} \
|
|
140
|
+
} while (false)
|
|
141
|
+
|
|
142
|
+
void TestFullSymbolTableReturnsSupported() {
|
|
143
|
+
FakeLoaderEnv env = {};
|
|
144
|
+
const PdfiumOutlineFns complete_fns = MakeCompleteOutlineFns();
|
|
145
|
+
InstallSymbols(&env, complete_fns);
|
|
146
|
+
|
|
147
|
+
OutlineLoaderState state = {};
|
|
148
|
+
const OutlineLoaderDeps deps = MakeDeps(&env);
|
|
149
|
+
|
|
150
|
+
const OutlineLoadAttemptResult result = EnsureOutlinePdfiumLoaded(&state, &deps);
|
|
151
|
+
|
|
152
|
+
EXPECT_TRUE(result.loaded);
|
|
153
|
+
EXPECT_FALSE(result.transitioned_to_unsupported);
|
|
154
|
+
EXPECT_EQ(OutlineLoadState::kSupported, state.load_state);
|
|
155
|
+
EXPECT_TRUE(state.handle != nullptr);
|
|
156
|
+
EXPECT_TRUE(HasCompleteOutlineFns(state.fns));
|
|
157
|
+
EXPECT_EQ(1, env.dlopen_calls);
|
|
158
|
+
EXPECT_EQ(7, env.dlsym_calls);
|
|
159
|
+
EXPECT_EQ(0, env.dlclose_calls);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
void TestMissingLibraryReturnsUnsupported() {
|
|
163
|
+
FakeLoaderEnv env = {};
|
|
164
|
+
env.library_handle = nullptr;
|
|
165
|
+
|
|
166
|
+
OutlineLoaderState state = {};
|
|
167
|
+
const OutlineLoaderDeps deps = MakeDeps(&env);
|
|
168
|
+
|
|
169
|
+
const OutlineLoadAttemptResult result = EnsureOutlinePdfiumLoaded(&state, &deps);
|
|
170
|
+
|
|
171
|
+
EXPECT_FALSE(result.loaded);
|
|
172
|
+
EXPECT_TRUE(result.transitioned_to_unsupported);
|
|
173
|
+
EXPECT_EQ(OutlineLoadState::kUnsupported, state.load_state);
|
|
174
|
+
EXPECT_TRUE(state.handle == nullptr);
|
|
175
|
+
EXPECT_FALSE(HasCompleteOutlineFns(state.fns));
|
|
176
|
+
EXPECT_EQ(1, env.dlopen_calls);
|
|
177
|
+
EXPECT_EQ(0, env.dlsym_calls);
|
|
178
|
+
EXPECT_EQ(0, env.dlclose_calls);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
void TestMissingSymbolReturnsUnsupportedAndClosesHandle() {
|
|
182
|
+
FakeLoaderEnv env = {};
|
|
183
|
+
const PdfiumOutlineFns partial_fns = MakeCompleteOutlineFns();
|
|
184
|
+
InstallSymbols(&env, partial_fns);
|
|
185
|
+
env.symbols.erase("FPDFBookmark_GetDest");
|
|
186
|
+
|
|
187
|
+
OutlineLoaderState state = {};
|
|
188
|
+
const OutlineLoaderDeps deps = MakeDeps(&env);
|
|
189
|
+
|
|
190
|
+
const OutlineLoadAttemptResult result = EnsureOutlinePdfiumLoaded(&state, &deps);
|
|
191
|
+
|
|
192
|
+
EXPECT_FALSE(result.loaded);
|
|
193
|
+
EXPECT_TRUE(result.transitioned_to_unsupported);
|
|
194
|
+
EXPECT_EQ(OutlineLoadState::kUnsupported, state.load_state);
|
|
195
|
+
EXPECT_TRUE(state.handle == nullptr);
|
|
196
|
+
EXPECT_FALSE(HasCompleteOutlineFns(state.fns));
|
|
197
|
+
EXPECT_EQ(1, env.dlopen_calls);
|
|
198
|
+
EXPECT_EQ(7, env.dlsym_calls);
|
|
199
|
+
EXPECT_EQ(1, env.dlclose_calls);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
void TestRepeatedCallsAfterFailureStayUnsupported() {
|
|
203
|
+
FakeLoaderEnv env = {};
|
|
204
|
+
const PdfiumOutlineFns partial_fns = MakeCompleteOutlineFns();
|
|
205
|
+
InstallSymbols(&env, partial_fns);
|
|
206
|
+
env.symbols.erase("FPDFDest_GetPageIndex");
|
|
207
|
+
|
|
208
|
+
OutlineLoaderState state = {};
|
|
209
|
+
const OutlineLoaderDeps deps = MakeDeps(&env);
|
|
210
|
+
|
|
211
|
+
const OutlineLoadAttemptResult first = EnsureOutlinePdfiumLoaded(&state, &deps);
|
|
212
|
+
EXPECT_FALSE(first.loaded);
|
|
213
|
+
EXPECT_TRUE(first.transitioned_to_unsupported);
|
|
214
|
+
EXPECT_EQ(OutlineLoadState::kUnsupported, state.load_state);
|
|
215
|
+
EXPECT_TRUE(state.handle == nullptr);
|
|
216
|
+
EXPECT_FALSE(HasCompleteOutlineFns(state.fns));
|
|
217
|
+
EXPECT_EQ(1, env.dlopen_calls);
|
|
218
|
+
EXPECT_EQ(7, env.dlsym_calls);
|
|
219
|
+
EXPECT_EQ(1, env.dlclose_calls);
|
|
220
|
+
|
|
221
|
+
const OutlineLoadAttemptResult second = EnsureOutlinePdfiumLoaded(&state, &deps);
|
|
222
|
+
EXPECT_FALSE(second.loaded);
|
|
223
|
+
EXPECT_FALSE(second.transitioned_to_unsupported);
|
|
224
|
+
EXPECT_EQ(OutlineLoadState::kUnsupported, state.load_state);
|
|
225
|
+
EXPECT_TRUE(state.handle == nullptr);
|
|
226
|
+
EXPECT_FALSE(HasCompleteOutlineFns(state.fns));
|
|
227
|
+
EXPECT_EQ(1, env.dlopen_calls);
|
|
228
|
+
EXPECT_EQ(7, env.dlsym_calls);
|
|
229
|
+
EXPECT_EQ(1, env.dlclose_calls);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
} // namespace
|
|
233
|
+
|
|
234
|
+
int main() {
|
|
235
|
+
TestFullSymbolTableReturnsSupported();
|
|
236
|
+
TestMissingLibraryReturnsUnsupported();
|
|
237
|
+
TestMissingSymbolReturnsUnsupportedAndClosesHandle();
|
|
238
|
+
TestRepeatedCallsAfterFailureStayUnsupported();
|
|
239
|
+
return 0;
|
|
240
|
+
}
|