Skip to content

Commit 3d6dc8f

Browse files
authored
Remove STL dependency (#161)
1 parent 7d472db commit 3d6dc8f

9 files changed

+70
-154
lines changed

README.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ CPU Architectures
7878

7979
The native library is built for the following CPU architectures:
8080

81-
- `armeabi-v7a` ~1.4 MB
82-
- `arm64-v8a` ~2 MB
83-
- `x86` ~2.1 MB
84-
- `x86_64` ~2.1 MB
81+
- `armeabi-v7a` ~1.2 MB
82+
- `arm64-v8a` ~1.7 MB
83+
- `x86` ~1.7 MB
84+
- `x86_64` ~1.8 MB
8585

8686
However you may not want to include all binaries in your apk. You can exclude certain variants by
8787
using `packagingOptions`:
@@ -97,7 +97,7 @@ android {
9797
}
9898
```
9999

100-
The size of the artifacts with only the armeabi-v7a binary is **~1.4 MB**. In general you can use
100+
The size of the artifacts with only the armeabi-v7a binary is **~1.2 MB**. In general you can use
101101
armeabi-v7a on the majority of Android devices including Intel Atom which provides a native
102102
translation layer, however performance under the translation layer is worse than using the x86
103103
binary.
@@ -146,6 +146,7 @@ Changes
146146
- Made the AOSP code (mostly) warning free but still mergable from source
147147
- Deprecated classes/methods removed
148148
- Loadable extension support
149+
- STL dependency removed
149150

150151
License
151152
-------

sqlite-android/src/main/jni/Application.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
APP_STL:=c++_static
1+
APP_STL:=none
22
APP_OPTIM := release
33
APP_ABI := armeabi-v7a,arm64-v8a,x86,x86_64
44
NDK_TOOLCHAIN_VERSION := clang

sqlite-android/src/main/jni/sqlite/CursorWindow.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,18 @@
2727

2828
namespace android {
2929

30-
CursorWindow::CursorWindow(const std::string& name, void* data, size_t size, bool readOnly) :
31-
mName(name), mData(data), mSize(size), mReadOnly(readOnly) {
30+
CursorWindow::CursorWindow(const char* name, void* data, size_t size, bool readOnly) :
31+
mData(data), mSize(size), mReadOnly(readOnly) {
32+
mName = strdup(name);
3233
mHeader = static_cast<Header*>(mData);
3334
}
3435

3536
CursorWindow::~CursorWindow() {
37+
free(mName);
3638
free(mData);
3739
}
3840

39-
status_t CursorWindow::create(const std::string& name, size_t size, CursorWindow** outWindow) {
41+
status_t CursorWindow::create(const char* name, size_t size, CursorWindow** outWindow) {
4042
status_t result;
4143
void* data = malloc(size);
4244
if (!data) {
@@ -54,6 +56,7 @@ status_t CursorWindow::create(const std::string& name, size_t size, CursorWindow
5456
*outWindow = window;
5557
return OK;
5658
}
59+
delete window;
5760
return result;
5861
}
5962

sqlite-android/src/main/jni/sqlite/CursorWindow.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include <stdint.h>
2424

2525
#include "Errors.h"
26-
#include <string>
2726

2827
#if LOG_NDEBUG
2928

@@ -50,7 +49,7 @@ namespace android {
5049
* Strings are stored in UTF-8.
5150
*/
5251
class CursorWindow {
53-
CursorWindow(const std::string& name, void* data, size_t size, bool readOnly);
52+
CursorWindow(const char* name, void* data, size_t size, bool readOnly);
5453

5554
public:
5655
/* Field types. */
@@ -80,9 +79,9 @@ class CursorWindow {
8079

8180
~CursorWindow();
8281

83-
static status_t create(const std::string& name, size_t size, CursorWindow** outCursorWindow);
82+
static status_t create(const char* name, size_t size, CursorWindow** outCursorWindow);
8483

85-
inline std::string name() { return mName; }
84+
inline const char* name() { return mName; }
8685
inline size_t size() { return mSize; }
8786
inline size_t freeSpace() { return mSize - mHeader->freeOffset; }
8887
inline uint32_t getNumRows() { return mHeader->numRows; }
@@ -156,7 +155,7 @@ class CursorWindow {
156155
uint32_t nextChunkOffset;
157156
};
158157

159-
std::string mName;
158+
char* mName;
160159
void* mData;
161160
size_t mSize;
162161
bool mReadOnly;

sqlite-android/src/main/jni/sqlite/JNIHelp.cpp

+19-107
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
#include <string.h>
2525
#include <assert.h>
2626

27-
#include <string>
28-
2927
/**
3028
* Equivalent to ScopedLocalRef, but for C_JNIEnv instead. (And slightly more powerful.)
3129
*/
@@ -94,7 +92,8 @@ extern "C" int jniRegisterNativeMethods(C_JNIEnv* env, const char* className,
9492
* be populated with the "binary" class name and, if present, the
9593
* exception message.
9694
*/
97-
static bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string& result) {
95+
static bool logExceptionSummary(C_JNIEnv *env, jthrowable exception,
96+
const char* exceptionClassName) {
9897
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
9998

10099
/* get the name of the exception's class */
@@ -107,16 +106,17 @@ static bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string
107106
(jstring) (*env)->CallObjectMethod(e, exceptionClass.get(), classGetNameMethod));
108107
if (classNameStr.get() == NULL) {
109108
(*env)->ExceptionClear(e);
110-
result = "<error getting class name>";
109+
ALOGW("Discarding pending exception (%s) to throw %s", "<error getting class name>",
110+
exceptionClassName);
111111
return false;
112112
}
113113
const char* classNameChars = (*env)->GetStringUTFChars(e, classNameStr.get(), NULL);
114114
if (classNameChars == NULL) {
115115
(*env)->ExceptionClear(e);
116-
result = "<error getting class name UTF-8>";
116+
ALOGW("Discarding pending exception (%s) to throw %s", "<error getting class name UTF-8>",
117+
exceptionClassName);
117118
return false;
118119
}
119-
result += classNameChars;
120120
(*env)->ReleaseStringUTFChars(e, classNameStr.get(), classNameChars);
121121

122122
/* if the exception has a detail message, get that */
@@ -128,81 +128,23 @@ static bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string
128128
return true;
129129
}
130130

131-
result += ": ";
132-
133131
const char* messageChars = (*env)->GetStringUTFChars(e, messageStr.get(), NULL);
134132
if (messageChars != NULL) {
135-
result += messageChars;
133+
ALOGW("Discarding pending exception (%s: %s) to throw %s",
134+
classNameChars,
135+
messageChars,
136+
exceptionClassName);
136137
(*env)->ReleaseStringUTFChars(e, messageStr.get(), messageChars);
137138
} else {
138-
result += "<error getting message>";
139+
ALOGW("Discarding pending exception (%s: <error getting message>) to throw %s",
140+
classNameChars,
141+
exceptionClassName);
139142
(*env)->ExceptionClear(e); // clear OOM
140143
}
141144

142145
return true;
143146
}
144147

145-
/*
146-
* Returns an exception (with stack trace) as a string.
147-
*/
148-
static bool getStackTrace(C_JNIEnv* env, jthrowable exception, std::string& result) {
149-
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
150-
151-
scoped_local_ref<jclass> stringWriterClass(env, findClass(env, "java/io/StringWriter"));
152-
if (stringWriterClass.get() == NULL) {
153-
return false;
154-
}
155-
156-
jmethodID stringWriterCtor = (*env)->GetMethodID(e, stringWriterClass.get(), "<init>", "()V");
157-
jmethodID stringWriterToStringMethod =
158-
(*env)->GetMethodID(e, stringWriterClass.get(), "toString", "()Ljava/lang/String;");
159-
160-
scoped_local_ref<jclass> printWriterClass(env, findClass(env, "java/io/PrintWriter"));
161-
if (printWriterClass.get() == NULL) {
162-
return false;
163-
}
164-
165-
jmethodID printWriterCtor =
166-
(*env)->GetMethodID(e, printWriterClass.get(), "<init>", "(Ljava/io/Writer;)V");
167-
168-
scoped_local_ref<jobject> stringWriter(env,
169-
(*env)->NewObject(e, stringWriterClass.get(), stringWriterCtor));
170-
if (stringWriter.get() == NULL) {
171-
return false;
172-
}
173-
174-
jobject printWriter =
175-
(*env)->NewObject(e, printWriterClass.get(), printWriterCtor, stringWriter.get());
176-
if (printWriter == NULL) {
177-
return false;
178-
}
179-
180-
scoped_local_ref<jclass> exceptionClass(env, (*env)->GetObjectClass(e, exception)); // can't fail
181-
jmethodID printStackTraceMethod =
182-
(*env)->GetMethodID(e, exceptionClass.get(), "printStackTrace", "(Ljava/io/PrintWriter;)V");
183-
(*env)->CallVoidMethod(e, exception, printStackTraceMethod, printWriter);
184-
185-
if ((*env)->ExceptionCheck(e)) {
186-
return false;
187-
}
188-
189-
scoped_local_ref<jstring> messageStr(env,
190-
(jstring) (*env)->CallObjectMethod(e, stringWriter.get(), stringWriterToStringMethod));
191-
if (messageStr.get() == NULL) {
192-
return false;
193-
}
194-
195-
const char* utfChars = (*env)->GetStringUTFChars(e, messageStr.get(), NULL);
196-
if (utfChars == NULL) {
197-
return false;
198-
}
199-
200-
result = utfChars;
201-
202-
(*env)->ReleaseStringUTFChars(e, messageStr.get(), utfChars);
203-
return true;
204-
}
205-
206148
extern "C" int jniThrowException(C_JNIEnv* env, const char* className, const char* msg) {
207149
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
208150

@@ -212,9 +154,7 @@ extern "C" int jniThrowException(C_JNIEnv* env, const char* className, const cha
212154
(*env)->ExceptionClear(e);
213155

214156
if (exception.get() != NULL) {
215-
std::string text;
216-
getExceptionSummary(env, exception.get(), text);
217-
ALOGW("Discarding pending exception (%s) to throw %s", text.c_str(), className);
157+
logExceptionSummary(env, exception.get(), className);
218158
}
219159
}
220160

@@ -254,39 +194,6 @@ int jniThrowIOException(C_JNIEnv* env, int errnum) {
254194
return jniThrowException(env, "java/io/IOException", message);
255195
}
256196

257-
static std::string jniGetStackTrace(C_JNIEnv* env, jthrowable exception) {
258-
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
259-
260-
scoped_local_ref<jthrowable> currentException(env, (*env)->ExceptionOccurred(e));
261-
if (exception == NULL) {
262-
exception = currentException.get();
263-
if (exception == NULL) {
264-
return "<no pending exception>";
265-
}
266-
}
267-
268-
if (currentException.get() != NULL) {
269-
(*env)->ExceptionClear(e);
270-
}
271-
272-
std::string trace;
273-
if (!getStackTrace(env, exception, trace)) {
274-
(*env)->ExceptionClear(e);
275-
getExceptionSummary(env, exception, trace);
276-
}
277-
278-
if (currentException.get() != NULL) {
279-
(*env)->Throw(e, currentException.get()); // rethrow
280-
}
281-
282-
return trace;
283-
}
284-
285-
void jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception) {
286-
std::string trace(jniGetStackTrace(env, exception));
287-
__android_log_write(priority, tag, trace.c_str());
288-
}
289-
290197
const char* jniStrError(int errnum, char* buf, size_t buflen) {
291198
#if __GLIBC__
292199
// Note: glibc has a nonstandard strerror_r that returns char* rather than POSIX's int.
@@ -303,3 +210,8 @@ const char* jniStrError(int errnum, char* buf, size_t buflen) {
303210
return buf;
304211
#endif
305212
}
213+
214+
void* operator new (size_t size) { return malloc(size); }
215+
void* operator new [] (size_t size) { return malloc(size); }
216+
void operator delete (void* pointer) { free(pointer); }
217+
void operator delete [] (void* pointer) { free(pointer); }

sqlite-android/src/main/jni/sqlite/JNIHelp.h

-10
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,6 @@ void jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor, int value);
102102
*/
103103
jobject jniGetReferent(C_JNIEnv* env, jobject ref);
104104

105-
/*
106-
* Log a message and an exception.
107-
* If exception is NULL, logs the current exception in the JNI environment.
108-
*/
109-
void jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception);
110-
111105
#ifdef __cplusplus
112106
}
113107
#endif
@@ -167,10 +161,6 @@ inline jobject jniGetReferent(JNIEnv* env, jobject ref) {
167161
return jniGetReferent(&env->functions, ref);
168162
}
169163

170-
inline void jniLogException(JNIEnv* env, int priority, const char* tag, jthrowable exception = NULL) {
171-
jniLogException(&env->functions, priority, tag, exception);
172-
}
173-
174164
#endif
175165

176166
#define FIND_CLASS(var, className) \

sqlite-android/src/main/jni/sqlite/android_database_CursorWindow.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <jni.h>
2424
#include <JNIHelp.h>
2525
#include <stdio.h>
26-
#include <string>
26+
#include <stdlib.h>
2727
#include <unistd.h>
2828

2929
#include "CursorWindow.h"
@@ -51,12 +51,11 @@ static void throwUnknownTypeException(JNIEnv * env, jint type) {
5151
}
5252

5353
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring nameObj, jint cursorWindowSize) {
54+
CursorWindow* window;
5455
const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
55-
std::string name(nameStr);
56+
status_t status = CursorWindow::create(nameStr, cursorWindowSize, &window);
5657
env->ReleaseStringUTFChars(nameObj, nameStr);
5758

58-
CursorWindow* window;
59-
status_t status = CursorWindow::create(name, cursorWindowSize, &window);
6059
if (status || !window) {
6160
ALOGE("Could not allocate CursorWindow of size %d due to error %d.",
6261
cursorWindowSize, status);
@@ -77,7 +76,7 @@ static void nativeDispose(JNIEnv* env, jclass clazz, jlong windowPtr) {
7776

7877
static jstring nativeGetName(JNIEnv* env, jclass clazz, jlong windowPtr) {
7978
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
80-
return env->NewStringUTF(window->name().c_str());
79+
return env->NewStringUTF(window->name());
8180
}
8281

8382
static void nativeClear(JNIEnv * env, jclass clazz, jlong windowPtr) {

0 commit comments

Comments
 (0)