capi_helper.h (2647B)
1 // © 2018 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 #ifndef __CAPI_HELPER_H__ 5 #define __CAPI_HELPER_H__ 6 7 #include "unicode/utypes.h" 8 9 U_NAMESPACE_BEGIN 10 11 /** 12 * An internal helper class to help convert between C and C++ APIs. 13 */ 14 template<typename CType, typename CPPType, int32_t kMagic> 15 class IcuCApiHelper { 16 public: 17 /** 18 * Convert from the C type to the C++ type (const version). 19 */ 20 static const CPPType* validate(const CType* input, UErrorCode& status); 21 22 /** 23 * Convert from the C type to the C++ type (non-const version). 24 */ 25 static CPPType* validate(CType* input, UErrorCode& status); 26 27 /** 28 * Convert from the C++ type to the C type (const version). 29 */ 30 const CType* exportConstForC() const; 31 32 /** 33 * Convert from the C++ type to the C type (non-const version). 34 */ 35 CType* exportForC(); 36 37 /** 38 * Invalidates the object. 39 */ 40 ~IcuCApiHelper(); 41 42 private: 43 /** 44 * While the object is valid, fMagic equals kMagic. 45 */ 46 int32_t fMagic = kMagic; 47 }; 48 49 50 template<typename CType, typename CPPType, int32_t kMagic> 51 const CPPType* 52 IcuCApiHelper<CType, CPPType, kMagic>::validate(const CType* input, UErrorCode& status) { 53 if (U_FAILURE(status)) { 54 return nullptr; 55 } 56 if (input == nullptr) { 57 status = U_ILLEGAL_ARGUMENT_ERROR; 58 return nullptr; 59 } 60 auto* impl = reinterpret_cast<const CPPType*>(input); 61 if (static_cast<const IcuCApiHelper<CType, CPPType, kMagic>*>(impl)->fMagic != kMagic) { 62 status = U_INVALID_FORMAT_ERROR; 63 return nullptr; 64 } 65 return impl; 66 } 67 68 template<typename CType, typename CPPType, int32_t kMagic> 69 CPPType* 70 IcuCApiHelper<CType, CPPType, kMagic>::validate(CType* input, UErrorCode& status) { 71 auto* constInput = static_cast<const CType*>(input); 72 auto* validated = validate(constInput, status); 73 return const_cast<CPPType*>(validated); 74 } 75 76 template<typename CType, typename CPPType, int32_t kMagic> 77 const CType* 78 IcuCApiHelper<CType, CPPType, kMagic>::exportConstForC() const { 79 return reinterpret_cast<const CType*>(static_cast<const CPPType*>(this)); 80 } 81 82 template<typename CType, typename CPPType, int32_t kMagic> 83 CType* 84 IcuCApiHelper<CType, CPPType, kMagic>::exportForC() { 85 return reinterpret_cast<CType*>(static_cast<CPPType*>(this)); 86 } 87 88 template<typename CType, typename CPPType, int32_t kMagic> 89 IcuCApiHelper<CType, CPPType, kMagic>::~IcuCApiHelper() { 90 // head off application errors by preventing use of of deleted objects. 91 fMagic = 0; 92 } 93 94 95 U_NAMESPACE_END 96 97 #endif // __CAPI_HELPER_H__