|
| 1 | +#ifndef FIREBASE_FIRESTORE_CLIENT_CPP_SRC_JNI_ENV_H_ |
| 2 | +#define FIREBASE_FIRESTORE_CLIENT_CPP_SRC_JNI_ENV_H_ |
| 3 | + |
| 4 | +#include <jni.h> |
| 5 | + |
| 6 | +#include <string> |
| 7 | + |
| 8 | +#include "firestore/src/jni/object.h" |
| 9 | +#include "firestore/src/jni/ownership.h" |
| 10 | +#include "firestore/src/jni/string.h" |
| 11 | +#include "firestore/src/jni/traits.h" |
| 12 | + |
| 13 | +namespace firebase { |
| 14 | +namespace firestore { |
| 15 | +namespace jni { |
| 16 | + |
| 17 | +/** |
| 18 | + * A wrapper around a JNIEnv pointer that makes dealing with JNI simpler in C++, |
| 19 | + * by: |
| 20 | + * |
| 21 | + * * Automatically converting arguments of C++ types to their JNI equivalents; |
| 22 | + * * handling C++ strings naturally; |
| 23 | + * * wrapping JNI references in `Local` RAII wrappers automatically; and |
| 24 | + * * simplifying error handling related to JNI calls (see below). |
| 25 | + * |
| 26 | + * Normally JNI requires that each call be followed by an explicit check to see |
| 27 | + * if an exception happened. This is tedious and clutters the code. Instead, |
| 28 | + * `Env` automatically checks for a JNI exception and short circuits any further |
| 29 | + * calls. This means that JNI-intensive code can be written straightforwardly |
| 30 | + * with a single, final check for errors. Exceptions can still be handled |
| 31 | + * inline if required. |
| 32 | + */ |
| 33 | +class Env { |
| 34 | + public: |
| 35 | + Env() : env_(GetEnv()) {} |
| 36 | + |
| 37 | + explicit Env(JNIEnv* env) : env_(env) {} |
| 38 | + |
| 39 | + /** Returns true if the Env has not encountered an exception. */ |
| 40 | + bool ok() const { return last_exception_ == nullptr; } |
| 41 | + |
| 42 | + /** Returns the underlying JNIEnv pointer. */ |
| 43 | + JNIEnv* get() const { return env_; } |
| 44 | + |
| 45 | + // MARK: String Operations |
| 46 | + |
| 47 | + /** |
| 48 | + * Creates a new proxy for a Java String from a sequences of modified UTF-8 |
| 49 | + * bytes. |
| 50 | + */ |
| 51 | + Local<String> NewStringUtf(const char* bytes); |
| 52 | + Local<String> NewStringUtf(const std::string& bytes) { |
| 53 | + return NewStringUtf(bytes.c_str()); |
| 54 | + } |
| 55 | + |
| 56 | + /** Returns the length of the string in modified UTF-8 bytes. */ |
| 57 | + size_t GetStringUtfLength(jstring string) { |
| 58 | + jsize result = env_->GetStringUTFLength(string); |
| 59 | + RecordException(); |
| 60 | + return static_cast<size_t>(result); |
| 61 | + } |
| 62 | + size_t GetStringUtfLength(const String& string) { |
| 63 | + return GetStringUtfLength(string.get()); |
| 64 | + } |
| 65 | + |
| 66 | + /** |
| 67 | + * Copies the contents of a region of a Java string to a C++ string. The |
| 68 | + * resulting string has a modified UTF-8 encoding. |
| 69 | + */ |
| 70 | + std::string GetStringUtfRegion(jstring string, size_t start, size_t len); |
| 71 | + std::string GetStringUtfRegion(const String& string, size_t start, |
| 72 | + size_t len) { |
| 73 | + return GetStringUtfRegion(string.get(), start, len); |
| 74 | + } |
| 75 | + |
| 76 | + private: |
| 77 | + void RecordException(); |
| 78 | + |
| 79 | + JNIEnv* env_ = nullptr; |
| 80 | + jthrowable last_exception_ = nullptr; |
| 81 | +}; |
| 82 | + |
| 83 | +} // namespace jni |
| 84 | +} // namespace firestore |
| 85 | +} // namespace firebase |
| 86 | + |
| 87 | +#endif // FIREBASE_FIRESTORE_CLIENT_CPP_SRC_JNI_ENV_H_ |
0 commit comments