|
1 /* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include <jni.h> |
|
7 |
|
8 #include <stdlib.h> |
|
9 #include <fcntl.h> |
|
10 #include "APKOpen.h" |
|
11 #include "Zip.h" |
|
12 #include "mozilla/RefPtr.h" |
|
13 |
|
14 extern "C" |
|
15 __attribute__ ((visibility("default"))) |
|
16 void JNICALL |
|
17 Java_org_mozilla_gecko_mozglue_GeckoLoader_putenv(JNIEnv *jenv, jclass, jstring map) |
|
18 { |
|
19 const char* str; |
|
20 // XXX: java doesn't give us true UTF8, we should figure out something |
|
21 // better to do here |
|
22 str = jenv->GetStringUTFChars(map, nullptr); |
|
23 if (str == nullptr) |
|
24 return; |
|
25 putenv(strdup(str)); |
|
26 jenv->ReleaseStringUTFChars(map, str); |
|
27 } |
|
28 |
|
29 extern "C" |
|
30 __attribute__ ((visibility("default"))) |
|
31 jobject JNICALL |
|
32 Java_org_mozilla_gecko_mozglue_DirectBufferAllocator_nativeAllocateDirectBuffer(JNIEnv *jenv, jclass, jlong size) |
|
33 { |
|
34 jobject buffer = nullptr; |
|
35 void* mem = malloc(size); |
|
36 if (mem) { |
|
37 buffer = jenv->NewDirectByteBuffer(mem, size); |
|
38 if (!buffer) |
|
39 free(mem); |
|
40 } |
|
41 return buffer; |
|
42 } |
|
43 |
|
44 extern "C" |
|
45 __attribute__ ((visibility("default"))) |
|
46 void JNICALL |
|
47 Java_org_mozilla_gecko_mozglue_DirectBufferAllocator_nativeFreeDirectBuffer(JNIEnv *jenv, jclass, jobject buf) |
|
48 { |
|
49 free(jenv->GetDirectBufferAddress(buf)); |
|
50 } |
|
51 |
|
52 extern "C" |
|
53 __attribute__ ((visibility("default"))) |
|
54 jlong JNICALL |
|
55 Java_org_mozilla_gecko_mozglue_NativeZip_getZip(JNIEnv *jenv, jclass, jstring path) |
|
56 { |
|
57 const char* str; |
|
58 str = jenv->GetStringUTFChars(path, nullptr); |
|
59 if (!str || !*str) { |
|
60 if (str) |
|
61 jenv->ReleaseStringUTFChars(path, str); |
|
62 JNI_Throw(jenv, "java/lang/IllegalArgumentException", "Invalid path"); |
|
63 return 0; |
|
64 } |
|
65 mozilla::RefPtr<Zip> zip = ZipCollection::GetZip(str); |
|
66 jenv->ReleaseStringUTFChars(path, str); |
|
67 if (!zip) { |
|
68 JNI_Throw(jenv, "java/lang/IllegalArgumentException", "Invalid path or invalid zip"); |
|
69 return 0; |
|
70 } |
|
71 zip->AddRef(); |
|
72 return (jlong) zip.get(); |
|
73 } |
|
74 |
|
75 extern "C" |
|
76 __attribute__ ((visibility("default"))) |
|
77 jlong JNICALL |
|
78 Java_org_mozilla_gecko_mozglue_NativeZip_getZipFromByteBuffer(JNIEnv *jenv, jclass, jobject buffer) |
|
79 { |
|
80 void *buf = jenv->GetDirectBufferAddress(buffer); |
|
81 size_t size = jenv->GetDirectBufferCapacity(buffer); |
|
82 mozilla::RefPtr<Zip> zip = Zip::Create(buf, size); |
|
83 if (!zip) { |
|
84 JNI_Throw(jenv, "java/lang/IllegalArgumentException", "Invalid zip"); |
|
85 return 0; |
|
86 } |
|
87 zip->AddRef(); |
|
88 return (jlong) zip.get(); |
|
89 } |
|
90 |
|
91 extern "C" |
|
92 __attribute__ ((visibility("default"))) |
|
93 void JNICALL |
|
94 Java_org_mozilla_gecko_mozglue_NativeZip__1release(JNIEnv *jenv, jclass, jlong obj) |
|
95 { |
|
96 Zip *zip = (Zip *)obj; |
|
97 zip->Release(); |
|
98 } |
|
99 |
|
100 extern "C" |
|
101 __attribute__ ((visibility("default"))) |
|
102 jobject JNICALL |
|
103 Java_org_mozilla_gecko_mozglue_NativeZip__1getInputStream(JNIEnv *jenv, jobject jzip, jlong obj, jstring path) |
|
104 { |
|
105 Zip *zip = (Zip *)obj; |
|
106 const char* str; |
|
107 str = jenv->GetStringUTFChars(path, nullptr); |
|
108 |
|
109 Zip::Stream stream; |
|
110 bool res = zip->GetStream(str, &stream); |
|
111 jenv->ReleaseStringUTFChars(path, str); |
|
112 if (!res) { |
|
113 return nullptr; |
|
114 } |
|
115 jobject buf = jenv->NewDirectByteBuffer(const_cast<void *>(stream.GetBuffer()), stream.GetSize()); |
|
116 if (!buf) { |
|
117 JNI_Throw(jenv, "java/lang/RuntimeException", "Failed to create ByteBuffer"); |
|
118 return nullptr; |
|
119 } |
|
120 jclass nativeZip = jenv->GetObjectClass(jzip); |
|
121 jmethodID method = jenv->GetMethodID(nativeZip, "createInputStream", "(Ljava/nio/ByteBuffer;I)Ljava/io/InputStream;"); |
|
122 // Since this function is only expected to be called from Java, it is safe |
|
123 // to skip exception checking for the method call below, as long as no |
|
124 // other Native -> Java call doesn't happen before returning to Java. |
|
125 return jenv->CallObjectMethod(jzip, method, buf, (jint) stream.GetType()); |
|
126 } |