xref: /aosp_15_r20/external/fbjni/cxx/fbjni/ByteBuffer.cpp (revision 65c59e023c5336bbd4a23be7af78407e3d80e7e7)
1*65c59e02SInna Palant /*
2*65c59e02SInna Palant  * Copyright (c) Facebook, Inc. and its affiliates.
3*65c59e02SInna Palant  *
4*65c59e02SInna Palant  * Licensed under the Apache License, Version 2.0 (the "License");
5*65c59e02SInna Palant  * you may not use this file except in compliance with the License.
6*65c59e02SInna Palant  * You may obtain a copy of the License at
7*65c59e02SInna Palant  *
8*65c59e02SInna Palant  *     http://www.apache.org/licenses/LICENSE-2.0
9*65c59e02SInna Palant  *
10*65c59e02SInna Palant  * Unless required by applicable law or agreed to in writing, software
11*65c59e02SInna Palant  * distributed under the License is distributed on an "AS IS" BASIS,
12*65c59e02SInna Palant  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*65c59e02SInna Palant  * See the License for the specific language governing permissions and
14*65c59e02SInna Palant  * limitations under the License.
15*65c59e02SInna Palant  */
16*65c59e02SInna Palant 
17*65c59e02SInna Palant #include <fbjni/ByteBuffer.h>
18*65c59e02SInna Palant 
19*65c59e02SInna Palant #include <stdexcept>
20*65c59e02SInna Palant 
21*65c59e02SInna Palant namespace facebook {
22*65c59e02SInna Palant namespace jni {
23*65c59e02SInna Palant 
rewind() const24*65c59e02SInna Palant void JBuffer::rewind() const {
25*65c59e02SInna Palant   static auto meth =
26*65c59e02SInna Palant       javaClassStatic()->getMethod<alias_ref<JBuffer>()>("rewind");
27*65c59e02SInna Palant   meth(self());
28*65c59e02SInna Palant }
29*65c59e02SInna Palant 
getDirectAddress() const30*65c59e02SInna Palant void* JBuffer::getDirectAddress() const {
31*65c59e02SInna Palant   if (!self()) {
32*65c59e02SInna Palant     throwNewJavaException(
33*65c59e02SInna Palant         "java/lang/NullPointerException", "java.lang.NullPointerException");
34*65c59e02SInna Palant   }
35*65c59e02SInna Palant   void* addr = Environment::current()->GetDirectBufferAddress(self());
36*65c59e02SInna Palant   FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
37*65c59e02SInna Palant   if (!addr) {
38*65c59e02SInna Palant     throw std::runtime_error(
39*65c59e02SInna Palant         isDirect() ? "Attempt to get direct bytes of non-direct buffer."
40*65c59e02SInna Palant                    : "Error getting direct bytes of buffer.");
41*65c59e02SInna Palant   }
42*65c59e02SInna Palant   return addr;
43*65c59e02SInna Palant }
44*65c59e02SInna Palant 
getDirectCapacity() const45*65c59e02SInna Palant size_t JBuffer::getDirectCapacity() const {
46*65c59e02SInna Palant   if (!self()) {
47*65c59e02SInna Palant     throwNewJavaException(
48*65c59e02SInna Palant         "java/lang/NullPointerException", "java.lang.NullPointerException");
49*65c59e02SInna Palant   }
50*65c59e02SInna Palant   int size = Environment::current()->GetDirectBufferCapacity(self());
51*65c59e02SInna Palant   FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
52*65c59e02SInna Palant   if (size < 0) {
53*65c59e02SInna Palant     throw std::runtime_error(
54*65c59e02SInna Palant         isDirect() ? "Attempt to get direct size of non-direct buffer."
55*65c59e02SInna Palant                    : "Error getting direct size of buffer.");
56*65c59e02SInna Palant   }
57*65c59e02SInna Palant   return static_cast<size_t>(size);
58*65c59e02SInna Palant }
59*65c59e02SInna Palant 
isDirect() const60*65c59e02SInna Palant bool JBuffer::isDirect() const {
61*65c59e02SInna Palant   static auto meth = javaClassStatic()->getMethod<jboolean()>("isDirect");
62*65c59e02SInna Palant   return meth(self());
63*65c59e02SInna Palant }
64*65c59e02SInna Palant 
nativeOrder()65*65c59e02SInna Palant local_ref<JByteOrder> JByteOrder::nativeOrder() {
66*65c59e02SInna Palant   static auto meth =
67*65c59e02SInna Palant       JByteOrder::javaClassStatic()->getStaticMethod<local_ref<JByteOrder>()>(
68*65c59e02SInna Palant           "nativeOrder");
69*65c59e02SInna Palant   return meth(JByteOrder::javaClassStatic());
70*65c59e02SInna Palant }
71*65c59e02SInna Palant 
bigEndian()72*65c59e02SInna Palant local_ref<JByteOrder> JByteOrder::bigEndian() {
73*65c59e02SInna Palant   static auto field =
74*65c59e02SInna Palant       JByteOrder::javaClassStatic()->getStaticField<JByteOrder>("BIG_ENDIAN");
75*65c59e02SInna Palant   return JByteOrder::javaClassStatic()->getStaticFieldValue(field);
76*65c59e02SInna Palant }
77*65c59e02SInna Palant 
littleEndian()78*65c59e02SInna Palant local_ref<JByteOrder> JByteOrder::littleEndian() {
79*65c59e02SInna Palant   static auto field = JByteOrder::javaClassStatic()->getStaticField<JByteOrder>(
80*65c59e02SInna Palant       "LITTLE_ENDIAN");
81*65c59e02SInna Palant   return JByteOrder::javaClassStatic()->getStaticFieldValue(field);
82*65c59e02SInna Palant }
83*65c59e02SInna Palant 
wrapBytes(uint8_t * data,size_t size)84*65c59e02SInna Palant local_ref<JByteBuffer> JByteBuffer::wrapBytes(uint8_t* data, size_t size) {
85*65c59e02SInna Palant   // env->NewDirectByteBuffer requires that size is positive. Android's
86*65c59e02SInna Palant   // dalvik returns an invalid result and Android's art aborts if size == 0.
87*65c59e02SInna Palant   // Workaround this by using a slow path through Java in that case.
88*65c59e02SInna Palant   if (!size) {
89*65c59e02SInna Palant     return allocateDirect(0);
90*65c59e02SInna Palant   }
91*65c59e02SInna Palant   auto res = adopt_local(static_cast<javaobject>(
92*65c59e02SInna Palant       Environment::current()->NewDirectByteBuffer(data, size)));
93*65c59e02SInna Palant   FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
94*65c59e02SInna Palant   if (!res) {
95*65c59e02SInna Palant     throw std::runtime_error("Direct byte buffers are unsupported.");
96*65c59e02SInna Palant   }
97*65c59e02SInna Palant   return res;
98*65c59e02SInna Palant }
99*65c59e02SInna Palant 
allocateDirect(jint size)100*65c59e02SInna Palant local_ref<JByteBuffer> JByteBuffer::allocateDirect(jint size) {
101*65c59e02SInna Palant   static auto cls = JByteBuffer::javaClassStatic();
102*65c59e02SInna Palant   static auto meth = cls->getStaticMethod<JByteBuffer(int)>("allocateDirect");
103*65c59e02SInna Palant   return meth(cls, size);
104*65c59e02SInna Palant }
105*65c59e02SInna Palant 
order(alias_ref<JByteOrder> order)106*65c59e02SInna Palant local_ref<JByteBuffer> JByteBuffer::order(alias_ref<JByteOrder> order) {
107*65c59e02SInna Palant   static auto meth =
108*65c59e02SInna Palant       JByteBuffer::javaClassStatic()
109*65c59e02SInna Palant           ->getMethod<local_ref<JByteBuffer>(alias_ref<JByteOrder>)>("order");
110*65c59e02SInna Palant   return meth(self(), order);
111*65c59e02SInna Palant }
112*65c59e02SInna Palant 
113*65c59e02SInna Palant } // namespace jni
114*65c59e02SInna Palant } // namespace facebook
115