Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 1 | // Copyright 2024 The Chromium Authors |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "base/android/jni_bytebuffer.h" |
| 6 | |
| 7 | #include "base/numerics/safe_conversions.h" |
| 8 | |
| 9 | namespace base::android { |
| 10 | |
Stefano Duo | f749c1b8 | 2024-09-23 22:56:36 | [diff] [blame] | 11 | base::span<const uint8_t> JavaByteBufferToSpan(JNIEnv* env, jobject buffer) { |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 12 | auto span = MaybeJavaByteBufferToSpan(env, buffer); |
| 13 | CHECK(span.has_value()); |
| 14 | return *span; |
| 15 | } |
| 16 | |
Stefano Duo | f749c1b8 | 2024-09-23 22:56:36 | [diff] [blame] | 17 | base::span<uint8_t> JavaByteBufferToMutableSpan(JNIEnv* env, jobject buffer) { |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 18 | auto span = MaybeJavaByteBufferToMutableSpan(env, buffer); |
| 19 | CHECK(span.has_value()); |
| 20 | return *span; |
| 21 | } |
| 22 | |
Arthur Sonzogni | e5fff99c | 2024-02-21 15:58:24 | [diff] [blame] | 23 | std::optional<base::span<const uint8_t>> MaybeJavaByteBufferToSpan( |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 24 | JNIEnv* env, |
Stefano Duo | f749c1b8 | 2024-09-23 22:56:36 | [diff] [blame] | 25 | jobject buffer) { |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 26 | auto span = MaybeJavaByteBufferToMutableSpan(env, buffer); |
Arthur Sonzogni | e5fff99c | 2024-02-21 15:58:24 | [diff] [blame] | 27 | return span ? std::make_optional(base::span<const uint8_t>(*span)) |
| 28 | : std::nullopt; |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 29 | } |
| 30 | |
Arthur Sonzogni | e5fff99c | 2024-02-21 15:58:24 | [diff] [blame] | 31 | std::optional<base::span<uint8_t>> MaybeJavaByteBufferToMutableSpan( |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 32 | JNIEnv* env, |
Stefano Duo | f749c1b8 | 2024-09-23 22:56:36 | [diff] [blame] | 33 | jobject buffer) { |
| 34 | void* data = env->GetDirectBufferAddress(buffer); |
| 35 | jlong size = env->GetDirectBufferCapacity(buffer); |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 36 | |
Elly | c9d1b63 | 2024-02-14 18:23:09 | [diff] [blame] | 37 | // !data && size == 0 is allowed - this is how a 0-length Buffer is |
| 38 | // represented. |
Stefano Duo | f749c1b8 | 2024-09-23 22:56:36 | [diff] [blame] | 39 | if (size < 0 || (!data && size > 0)) { |
Arthur Sonzogni | e5fff99c | 2024-02-21 15:58:24 | [diff] [blame] | 40 | return std::nullopt; |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 41 | } |
| 42 | |
danakj | da96688e | 2024-05-21 21:46:33 | [diff] [blame] | 43 | // SAFETY: This relies on the ByteBuffer to be internally valid. |
Stefano Duo | f749c1b8 | 2024-09-23 22:56:36 | [diff] [blame] | 44 | return UNSAFE_BUFFERS(base::span<uint8_t>(static_cast<uint8_t*>(data), |
| 45 | base::checked_cast<size_t>(size))); |
Elly | 3e40616 | 2024-01-23 16:18:48 | [diff] [blame] | 46 | } |
| 47 | |
| 48 | } // namespace base::android |