diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /intl/icu/source/common/capi_helper.h | |
parent | Initial commit. (diff) | |
download | firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'intl/icu/source/common/capi_helper.h')
-rw-r--r-- | intl/icu/source/common/capi_helper.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/intl/icu/source/common/capi_helper.h b/intl/icu/source/common/capi_helper.h new file mode 100644 index 0000000000..54b1db9e33 --- /dev/null +++ b/intl/icu/source/common/capi_helper.h @@ -0,0 +1,97 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#ifndef __CAPI_HELPER_H__ +#define __CAPI_HELPER_H__ + +#include "unicode/utypes.h" + +U_NAMESPACE_BEGIN + +/** + * An internal helper class to help convert between C and C++ APIs. + */ +template<typename CType, typename CPPType, int32_t kMagic> +class IcuCApiHelper { + public: + /** + * Convert from the C type to the C++ type (const version). + */ + static const CPPType* validate(const CType* input, UErrorCode& status); + + /** + * Convert from the C type to the C++ type (non-const version). + */ + static CPPType* validate(CType* input, UErrorCode& status); + + /** + * Convert from the C++ type to the C type (const version). + */ + const CType* exportConstForC() const; + + /** + * Convert from the C++ type to the C type (non-const version). + */ + CType* exportForC(); + + /** + * Invalidates the object. + */ + ~IcuCApiHelper(); + + private: + /** + * While the object is valid, fMagic equals kMagic. + */ + int32_t fMagic = kMagic; +}; + + +template<typename CType, typename CPPType, int32_t kMagic> +const CPPType* +IcuCApiHelper<CType, CPPType, kMagic>::validate(const CType* input, UErrorCode& status) { + if (U_FAILURE(status)) { + return nullptr; + } + if (input == nullptr) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return nullptr; + } + auto* impl = reinterpret_cast<const CPPType*>(input); + if (static_cast<const IcuCApiHelper<CType, CPPType, kMagic>*>(impl)->fMagic != kMagic) { + status = U_INVALID_FORMAT_ERROR; + return nullptr; + } + return impl; +} + +template<typename CType, typename CPPType, int32_t kMagic> +CPPType* +IcuCApiHelper<CType, CPPType, kMagic>::validate(CType* input, UErrorCode& status) { + auto* constInput = static_cast<const CType*>(input); + auto* validated = validate(constInput, status); + return const_cast<CPPType*>(validated); +} + +template<typename CType, typename CPPType, int32_t kMagic> +const CType* +IcuCApiHelper<CType, CPPType, kMagic>::exportConstForC() const { + return reinterpret_cast<const CType*>(static_cast<const CPPType*>(this)); +} + +template<typename CType, typename CPPType, int32_t kMagic> +CType* +IcuCApiHelper<CType, CPPType, kMagic>::exportForC() { + return reinterpret_cast<CType*>(static_cast<CPPType*>(this)); +} + +template<typename CType, typename CPPType, int32_t kMagic> +IcuCApiHelper<CType, CPPType, kMagic>::~IcuCApiHelper() { + // head off application errors by preventing use of of deleted objects. + fMagic = 0; +} + + +U_NAMESPACE_END + +#endif // __CAPI_HELPER_H__ |