summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2011-04-25 18:33:06 -0700
committerElliott Hughes <enh@google.com>2011-04-25 18:33:06 -0700
commit0568a63ba1086a78ffb4cff68dd2eac4f9908e13 (patch)
tree1dd10cd6eaba967333031b23631afb7c5639d481 /include
parentb374119ca8a6b8852013c923053ce149b4aaf737 (diff)
downloadlibcore-0568a63ba1086a78ffb4cff68dd2eac4f9908e13.zip
libcore-0568a63ba1086a78ffb4cff68dd2eac4f9908e13.tar.gz
libcore-0568a63ba1086a78ffb4cff68dd2eac4f9908e13.tar.bz2
Fix ByteBuffer.put(ByteBuffer).
To do this tastefully required some cunning in the native code. The new ScopedBytesRO/ScopedBytesRW classes let us paper over the differences between byte[] and DirectByteBuffer, which in turn lets us paper over the differences between the various kinds of ByteBuffer. I've also rewritten Posix.read/Posix.readDirectBuffer and Posix.write/Posix.writeDirectBuffer to use the same idea. I haven't rewritten readv and writev, but can do and probably should. Bug: http://code.google.com/p/android/issues/detail?id=16184 Change-Id: Ia30d2f2fe1b1716a8f068187df2218b407a55aae
Diffstat (limited to 'include')
-rw-r--r--include/ScopedBytes.h80
1 files changed, 80 insertions, 0 deletions
diff --git a/include/ScopedBytes.h b/include/ScopedBytes.h
new file mode 100644
index 0000000..cb2614b
--- /dev/null
+++ b/include/ScopedBytes.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SCOPED_BYTES_H_included
+#define SCOPED_BYTES_H_included
+
+#include "JNIHelp.h"
+
+/**
+ * ScopedBytesRO and ScopedBytesRW attempt to paper over the differences between byte[]s and
+ * ByteBuffers. This in turn helps paper over the differences between non-direct ByteBuffers backed
+ * by byte[]s, direct ByteBuffers backed by bytes[]s, and direct ByteBuffers not backed by byte[]s.
+ * (On Android, this last group only contains MappedByteBuffers.)
+ */
+template<bool readOnly>
+class ScopedBytes {
+public:
+ ScopedBytes(JNIEnv* env, jobject object)
+ : mEnv(env), mObject(object), mByteArray(NULL), mPtr(NULL)
+ {
+ if (mObject == NULL) {
+ jniThrowNullPointerException(mEnv, NULL);
+ } else if (mEnv->IsInstanceOf(mObject, JniConstants::byteArrayClass)) {
+ mByteArray = reinterpret_cast<jbyteArray>(mObject);
+ mPtr = mEnv->GetByteArrayElements(mByteArray, NULL);
+ } else {
+ mPtr = reinterpret_cast<jbyte*>(mEnv->GetDirectBufferAddress(mObject));
+ }
+ }
+
+ ~ScopedBytes() {
+ if (mByteArray != NULL) {
+ mEnv->ReleaseByteArrayElements(mByteArray, mPtr, readOnly ? JNI_ABORT : 0);
+ }
+ }
+
+private:
+ JNIEnv* mEnv;
+ jobject mObject;
+ jbyteArray mByteArray;
+
+protected:
+ jbyte* mPtr;
+
+private:
+ // Disallow copy and assignment.
+ ScopedBytes(const ScopedBytes&);
+ void operator=(const ScopedBytes&);
+};
+
+class ScopedBytesRO : public ScopedBytes<true> {
+public:
+ ScopedBytesRO(JNIEnv* env, jobject object) : ScopedBytes<true>(env, object) {}
+ const jbyte* get() const {
+ return mPtr;
+ }
+};
+
+class ScopedBytesRW : public ScopedBytes<false> {
+public:
+ ScopedBytesRW(JNIEnv* env, jobject object) : ScopedBytes<false>(env, object) {}
+ jbyte* get() {
+ return mPtr;
+ }
+};
+
+#endif // SCOPED_BYTES_H_included