tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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__