1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ******************************************************************************* 5 * 6 * Copyright (C) 2009-2011, International Business Machines 7 * Corporation and others. All Rights Reserved. 8 * 9 ******************************************************************************* 10 * file name: errorcode.h 11 * encoding: UTF-8 12 * tab size: 8 (not used) 13 * indentation:4 14 * 15 * created on: 2009mar10 16 * created by: Markus W. Scherer 17 */ 18 19 #ifndef __ERRORCODE_H__ 20 #define __ERRORCODE_H__ 21 22 /** 23 * \file 24 * \brief C++ API: ErrorCode class intended to make it easier to use 25 * ICU C and C++ APIs from C++ user code. 26 */ 27 28 #include "unicode/utypes.h" 29 30 #if U_SHOW_CPLUSPLUS_API 31 32 #include "unicode/uobject.h" 33 34 U_NAMESPACE_BEGIN 35 36 /** 37 * Wrapper class for UErrorCode, with conversion operators for direct use 38 * in ICU C and C++ APIs. 39 * Intended to be used as a base class, where a subclass overrides 40 * the handleFailure() function so that it throws an exception, 41 * does an assert(), logs an error, etc. 42 * This is not an abstract base class. This class can be used and instantiated 43 * by itself, although it will be more useful when subclassed. 44 * 45 * Features: 46 * - The constructor initializes the internal UErrorCode to U_ZERO_ERROR, 47 * removing one common source of errors. 48 * - Same use in C APIs taking a UErrorCode * (pointer) 49 * and C++ taking UErrorCode & (reference) via conversion operators. 50 * - Possible automatic checking for success when it goes out of scope. 51 * 52 * Note: For automatic checking for success in the destructor, a subclass 53 * must implement such logic in its own destructor because the base class 54 * destructor cannot call a subclass function (like handleFailure()). 55 * The ErrorCode base class destructor does nothing. 56 * 57 * Note also: While it is possible for a destructor to throw an exception, 58 * it is generally unsafe to do so. This means that in a subclass the destructor 59 * and the handleFailure() function may need to take different actions. 60 * 61 * Sample code: 62 * \code 63 * class IcuErrorCode: public icu::ErrorCode { 64 * public: 65 * virtual ~IcuErrorCode() { // should be defined in .cpp as "key function" 66 * // Safe because our handleFailure() does not throw exceptions. 67 * if(isFailure()) { handleFailure(); } 68 * } 69 * protected: 70 * virtual void handleFailure() const { 71 * log_failure(u_errorName(errorCode)); 72 * exit(errorCode); 73 * } 74 * }; 75 * IcuErrorCode error_code; 76 * UConverter *cnv = ucnv_open("Shift-JIS", error_code); 77 * length = ucnv_fromUChars(dest, capacity, src, length, error_code); 78 * ucnv_close(cnv); 79 * // IcuErrorCode destructor checks for success. 80 * \endcode 81 * 82 * @stable ICU 4.2 83 */ 84 class U_COMMON_API ErrorCode: public UMemory { 85 public: 86 /** 87 * Default constructor. Initializes its UErrorCode to U_ZERO_ERROR. 88 * @stable ICU 4.2 89 */ ErrorCode()90 ErrorCode() : errorCode(U_ZERO_ERROR) {} 91 /** Destructor, does nothing. See class documentation for details. @stable ICU 4.2 */ 92 virtual ~ErrorCode(); 93 /** Conversion operator, returns a reference. @stable ICU 4.2 */ 94 operator UErrorCode & () { return errorCode; } 95 /** Conversion operator, returns a pointer. @stable ICU 4.2 */ 96 operator UErrorCode * () { return &errorCode; } 97 /** Tests for U_SUCCESS(). @stable ICU 4.2 */ isSuccess()98 UBool isSuccess() const { return U_SUCCESS(errorCode); } 99 /** Tests for U_FAILURE(). @stable ICU 4.2 */ isFailure()100 UBool isFailure() const { return U_FAILURE(errorCode); } 101 /** Returns the UErrorCode value. @stable ICU 4.2 */ get()102 UErrorCode get() const { return errorCode; } 103 /** Sets the UErrorCode value. @stable ICU 4.2 */ set(UErrorCode value)104 void set(UErrorCode value) { errorCode=value; } 105 /** Returns the UErrorCode value and resets it to U_ZERO_ERROR. @stable ICU 4.2 */ 106 UErrorCode reset(); 107 /** 108 * Asserts isSuccess(). 109 * In other words, this method checks for a failure code, 110 * and the base class handles it like this: 111 * \code 112 * if(isFailure()) { handleFailure(); } 113 * \endcode 114 * @stable ICU 4.4 115 */ 116 void assertSuccess() const; 117 /** 118 * Return a string for the UErrorCode value. 119 * The string will be the same as the name of the error code constant 120 * in the UErrorCode enum. 121 * @stable ICU 4.4 122 */ 123 const char* errorName() const; 124 125 protected: 126 /** 127 * Internal UErrorCode, accessible to subclasses. 128 * @stable ICU 4.2 129 */ 130 UErrorCode errorCode; 131 /** 132 * Called by assertSuccess() if isFailure() is true. 133 * A subclass should override this function to deal with a failure code: 134 * Throw an exception, log an error, terminate the program, or similar. 135 * @stable ICU 4.2 136 */ handleFailure()137 virtual void handleFailure() const {} 138 }; 139 140 U_NAMESPACE_END 141 142 #endif /* U_SHOW_CPLUSPLUS_API */ 143 144 #endif // __ERRORCODE_H__ 145