Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: libadblockplus-android/jni/JniFileSystem.cpp

Issue 29424615: Issue 4231 - Fix unstable FilterEngineTest.testSetRemoveFilterChangeCallback (Closed)
Left Patch Set: Created April 28, 2017, 8:24 a.m.
Right Patch Set: changed impl for reading file as bytes array, modified test. AndroidFileSystem now does not resolve… Created May 29, 2017, 11:26 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2017 eyeo GmbH 3 * Copyright (C) 2006-2017 eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include "JniCallbacks.h" 18 #include "JniCallbacks.h"
19 #include "AdblockPlus/FileSystem.h" 19 #include "AdblockPlus/FileSystem.h"
20 #include "Utils.h" 20 #include "Utils.h"
21 #include <sstream> 21 #include <istream>
22 #include <streambuf>
23
24 class RuntimeErrorWithErrno : public std::runtime_error
25 {
26 public:
27 explicit RuntimeErrorWithErrno(const std::string& message)
28 : std::runtime_error(message + " (" + strerror(errno) + ")")
29 {
30 }
31 };
32
33 struct membuf: std::streambuf {
34 membuf(char const* base, size_t size) {
35 char* p(const_cast<char*>(base));
36 this->setg(p, p, p + size);
37 }
38 };
39
40 struct imemstream: virtual membuf, std::istream {
41 imemstream(char const* base, size_t size)
42 : membuf(base, size)
43 , std::istream(static_cast<std::streambuf*>(this)) {
44 }
45 };
sergei 2017/08/07 12:50:00 All these things should be in the anonymous namesp
22 46
23 // precached in JNI_OnLoad and released in JNI_OnUnload 47 // precached in JNI_OnLoad and released in JNI_OnUnload
24 JniGlobalReference<jclass>* statResultClass; 48 JniGlobalReference<jclass>* statResultClass;
25 jmethodID existsMethod; 49 jmethodID existsMethod;
26 jmethodID isDirectoryMethod; 50 jmethodID isDirectoryMethod;
27 jmethodID isFileMethod; 51 jmethodID isFileMethod;
28 jmethodID getLastModifiedMethod; 52 jmethodID getLastModifiedMethod;
29 53
30 void JniFileSystem_OnLoad(JavaVM* vm, JNIEnv* env, void* reserved) 54 void JniFileSystem_OnLoad(JavaVM* vm, JNIEnv* env, void* reserved)
31 { 55 {
32 statResultClass = new JniGlobalReference<jclass>(env, env->FindClass(PKG("File System$StatResult"))); 56 statResultClass = new JniGlobalReference<jclass>(env, env->FindClass(PKG("File System$StatResult")));
33 existsMethod = env->GetMethodID(statResultClass->Get(), "exists", "()Z"); 57 existsMethod = env->GetMethodID(statResultClass->Get(), "exists", "()Z");
34 isDirectoryMethod = env->GetMethodID(statResultClass->Get(), "isDirectory", "( )Z"); 58 isDirectoryMethod = env->GetMethodID(statResultClass->Get(), "isDirectory", "( )Z");
35 isFileMethod = env->GetMethodID(statResultClass->Get(), "isFile", "()Z"); 59 isFileMethod = env->GetMethodID(statResultClass->Get(), "isFile", "()Z");
36 getLastModifiedMethod = env->GetMethodID(statResultClass->Get(), "getLastModif ied", "()J"); 60 getLastModifiedMethod = env->GetMethodID(statResultClass->Get(), "getLastModif ied", "()J");
37 } 61 }
38 62
39 void JniFileSystem_OnUnload(JavaVM* vm, JNIEnv* env, void* reserved) 63 void JniFileSystem_OnUnload(JavaVM* vm, JNIEnv* env, void* reserved)
40 { 64 {
41 if (statResultClass) 65 if (statResultClass)
42 { 66 {
43 delete statResultClass; 67 delete statResultClass;
44 statResultClass = NULL; 68 statResultClass = NULL;
sergei 2017/08/07 12:50:00 nullptr?
45 } 69 }
46 } 70 }
47 71
48 static jlong JNICALL JniCtor(JNIEnv* env, jclass clazz, jobject callbackObject) 72 static jlong JNICALL JniCtor(JNIEnv* env, jclass clazz, jobject callbackObject)
sergei 2017/08/07 12:49:59 I think that it should be done a little bit differ
49 { 73 {
50 try 74 try
51 { 75 {
52 return JniPtrToLong(new JniFileSystemCallback(env, callbackObject)); 76 return JniPtrToLong(new AdblockPlus::FileSystemPtr(new JniFileSystemCallback (env, callbackObject)));
53 } 77 }
54 CATCH_THROW_AND_RETURN(env, 0) 78 CATCH_THROW_AND_RETURN(env, 0)
55 } 79 }
56 80
57 static void JNICALL JniDtor(JNIEnv* env, jclass clazz, jlong ptr) 81 static void JNICALL JniDtor(JNIEnv* env, jclass clazz, jlong ptr)
58 { 82 {
59 delete JniLongToTypePtr<JniFileSystemCallback>(ptr); 83 delete JniLongToTypePtr<AdblockPlus::FileSystemPtr>(ptr);
60 } 84 }
61 85
62 JniFileSystemCallback::JniFileSystemCallback(JNIEnv* env, jobject callbackObject ) 86 JniFileSystemCallback::JniFileSystemCallback(JNIEnv* env, jobject callbackObject )
63 : JniCallbackBase(env, callbackObject), 87 : JniCallbackBase(env, callbackObject)
64 AdblockPlus::FileSystem()
65 { 88 {
66 } 89 }
67 90
68 std::shared_ptr<std::istream> JniFileSystemCallback::Read(const std::string& pat h) const 91 std::shared_ptr<std::istream> JniFileSystemCallback::Read(const std::string& pat h) const
69 { 92 {
70 JNIEnvAcquire env(GetJavaVM()); 93 JNIEnvAcquire env(GetJavaVM());
71 94
72 jmethodID method = env->GetMethodID( 95 jmethodID method = env->GetMethodID(
73 *JniLocalReference<jclass>(*env, env->GetObjectClass(GetCallbackObject())), 96 *JniLocalReference<jclass>(*env, env->GetObjectClass(GetCallbackObject())),
74 "read", 97 "read",
75 "(Ljava/lang/String;)Ljava/lang/String;"); 98 "(Ljava/lang/String;)[B");
76 99
77 JniLocalReference<jstring> jPath(*env, env->NewStringUTF(path.c_str())); 100 JniLocalReference<jstring> jPath(*env, env->NewStringUTF(path.c_str()));
78 jstring jData = (jstring)env->CallObjectMethod(GetCallbackObject(), method, *j Path); 101 jbyteArray jData = (jbyteArray)env->CallObjectMethod(GetCallbackObject(), meth od, *jPath);
79 CheckAndLogJavaException(*env); 102 if (CheckAndLogJavaException(*env))
80 103 throw new RuntimeErrorWithErrno("Failed to open file (File not found)");
81 if (!jData) 104
82 return NULL; 105 int dataLength = env->GetArrayLength(jData);
83 106 char* cData = new char[dataLength];
84 std::string cData = JniJavaToStdString(*env, jData); 107 env->GetByteArrayRegion(jData, 0, dataLength, reinterpret_cast<jbyte*>(cData)) ;
85 std::shared_ptr<std::istream> cSharedStream(new std::istringstream(cData)); 108
109 std::shared_ptr<std::istream> cSharedStream(new imemstream(cData, dataLength)) ;
86 return cSharedStream; 110 return cSharedStream;
87 } 111 }
88 112
89 void JniFileSystemCallback::Write(const std::string& path, std::shared_ptr<std:: istream> data) 113 void JniFileSystemCallback::Write(const std::string& path, std::shared_ptr<std:: istream> dataStreamPtr)
90 { 114 {
91 JNIEnvAcquire env(GetJavaVM()); 115 JNIEnvAcquire env(GetJavaVM());
92 116
93 jmethodID method = env->GetMethodID( 117 jmethodID method = env->GetMethodID(
94 *JniLocalReference<jclass>(*env, env->GetObjectClass(GetCallbackObject())), 118 *JniLocalReference<jclass>(*env, env->GetObjectClass(GetCallbackObject())),
95 "write", 119 "write",
96 "(Ljava/lang/String;Ljava/lang/String;)V"); 120 "(Ljava/lang/String;[B)V");
97 121
98 JniLocalReference<jstring> jPath(*env, env->NewStringUTF(path.c_str())); 122 JniLocalReference<jstring> jPath(*env, env->NewStringUTF(path.c_str()));
99 123
100 // read all the data from the stream into buffer (no appropriate way to pass s treams over JNI) 124 // read all the data from the stream into buffer (no appropriate way to pass s treams over JNI)
101 std::string cData = JniStdStreamToStdString(data.get()); 125 std::istream* dataStream = dataStreamPtr.get();
102 JniLocalReference<jstring> jData(*env, env->NewStringUTF(cData.c_str())); 126 dataStream->seekg(0, std::ios::end);
103 127 int dataLength = dataStream->tellg();
104 env->CallVoidMethod(GetCallbackObject(), method, *jPath, *jData); 128 char* cData = new char[dataLength];
105 CheckAndLogJavaException(*env); 129 dataStream->seekg(0, std::ios::beg);
130 dataStream->read(cData, dataLength);
131
132 jbyteArray jData = env->NewByteArray(dataLength);
133 env->SetByteArrayRegion(jData, 0, dataLength, reinterpret_cast<jbyte*>(cData)) ;
134
135 env->CallVoidMethod(GetCallbackObject(), method, *jPath, jData);
136 CheckAndLogJavaException(*env);
137 delete[] cData;
106 } 138 }
107 139
108 void JniFileSystemCallback::Move(const std::string& fromPath, const std::string& toPath) 140 void JniFileSystemCallback::Move(const std::string& fromPath, const std::string& toPath)
109 { 141 {
110 JNIEnvAcquire env(GetJavaVM()); 142 JNIEnvAcquire env(GetJavaVM());
111 143
112 jmethodID method = env->GetMethodID( 144 jmethodID method = env->GetMethodID(
113 *JniLocalReference<jclass>(*env, env->GetObjectClass(GetCallbackObject())), 145 *JniLocalReference<jclass>(*env, env->GetObjectClass(GetCallbackObject())),
114 "move", 146 "move",
115 "(Ljava/lang/String;Ljava/lang/String;)V"); 147 "(Ljava/lang/String;Ljava/lang/String;)V");
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 static JNINativeMethod methods[] = 219 static JNINativeMethod methods[] =
188 { 220 {
189 { (char*)"ctor", (char*)"(Ljava/lang/Object;)J", (void*)JniCtor }, 221 { (char*)"ctor", (char*)"(Ljava/lang/Object;)J", (void*)JniCtor },
190 { (char*)"dtor", (char*)"(J)V", (void*)JniDtor } 222 { (char*)"dtor", (char*)"(J)V", (void*)JniDtor }
191 }; 223 };
192 224
193 extern "C" JNIEXPORT void JNICALL Java_org_adblockplus_libadblockplus_FileSystem _registerNatives(JNIEnv *env, jclass clazz) 225 extern "C" JNIEXPORT void JNICALL Java_org_adblockplus_libadblockplus_FileSystem _registerNatives(JNIEnv *env, jclass clazz)
194 { 226 {
195 env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])); 227 env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0]));
196 } 228 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld