Home | History | Annotate | Download | only in android
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_ANDROID_JNI_INT_WRAPPER_H_
      6 #define BASE_ANDROID_JNI_INT_WRAPPER_H_
      7 
      8 // Wrapper used to receive int when calling Java from native.
      9 // The wrapper disallows automatic conversion of long to int.
     10 // This is to avoid a common anti-pattern where a Java int is used
     11 // to receive a native pointer. Please use a Java long to receive
     12 // native pointers, so that the code works on both 32-bit and 64-bit
     13 // platforms. Note the wrapper allows other lossy conversions into
     14 // jint that could be consider anti-patterns, such as from size_t.
     15 
     16 // Checking is only done in debugging builds.
     17 
     18 #ifdef NDEBUG
     19 
     20 typedef jint JniIntWrapper;
     21 
     22 // This inline is sufficiently trivial that it does not change the
     23 // final code generated by g++.
     24 inline jint as_jint(JniIntWrapper wrapper) {
     25   return wrapper;
     26 }
     27 
     28 #else
     29 
     30 class JniIntWrapper {
     31  public:
     32   JniIntWrapper() : i_(0) {}
     33   JniIntWrapper(int i) : i_(i) {}
     34   JniIntWrapper(const JniIntWrapper& ji) : i_(ji.i_) {}
     35   template <class T> JniIntWrapper(const T& t) : i_(t) {}
     36   jint as_jint() const { return i_; }
     37  private:
     38   // If you get an "is private" error at the line below it is because you used
     39   // an implicit conversion to convert a long to an int when calling Java.
     40   // We disallow this, as a common anti-pattern allows converting a native
     41   // pointer (intptr_t) to a Java int. Please use a Java long to represent
     42   // a native pointer. If you want a lossy conversion, please use an
     43   // explicit conversion in your C++ code. Note an error is only seen when
     44   // compiling on a 64-bit platform, as intptr_t is indistinguishable from
     45   // int on 32-bit platforms.
     46   JniIntWrapper(long);
     47   jint i_;
     48 };
     49 
     50 inline jint as_jint(const JniIntWrapper& wrapper) {
     51   return wrapper.as_jint();
     52 }
     53 
     54 #endif  // NDEBUG
     55 
     56 #endif  // BASE_ANDROID_JNI_INT_WRAPPER_H_
     57