capi_helper.h 2.6 KB

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