Line data Source code
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 : #include "unicode/uobject.h"
30 :
31 : U_NAMESPACE_BEGIN
32 :
33 : /**
34 : * Wrapper class for UErrorCode, with conversion operators for direct use
35 : * in ICU C and C++ APIs.
36 : * Intended to be used as a base class, where a subclass overrides
37 : * the handleFailure() function so that it throws an exception,
38 : * does an assert(), logs an error, etc.
39 : * This is not an abstract base class. This class can be used and instantiated
40 : * by itself, although it will be more useful when subclassed.
41 : *
42 : * Features:
43 : * - The constructor initializes the internal UErrorCode to U_ZERO_ERROR,
44 : * removing one common source of errors.
45 : * - Same use in C APIs taking a UErrorCode * (pointer)
46 : * and C++ taking UErrorCode & (reference) via conversion operators.
47 : * - Possible automatic checking for success when it goes out of scope.
48 : *
49 : * Note: For automatic checking for success in the destructor, a subclass
50 : * must implement such logic in its own destructor because the base class
51 : * destructor cannot call a subclass function (like handleFailure()).
52 : * The ErrorCode base class destructor does nothing.
53 : *
54 : * Note also: While it is possible for a destructor to throw an exception,
55 : * it is generally unsafe to do so. This means that in a subclass the destructor
56 : * and the handleFailure() function may need to take different actions.
57 : *
58 : * Sample code:
59 : * \code
60 : * class IcuErrorCode: public icu::ErrorCode {
61 : * public:
62 : * virtual ~IcuErrorCode() { // should be defined in .cpp as "key function"
63 : * // Safe because our handleFailure() does not throw exceptions.
64 : * if(isFailure()) { handleFailure(); }
65 : * }
66 : * protected:
67 : * virtual void handleFailure() const {
68 : * log_failure(u_errorName(errorCode));
69 : * exit(errorCode);
70 : * }
71 : * };
72 : * IcuErrorCode error_code;
73 : * UConverter *cnv = ucnv_open("Shift-JIS", error_code);
74 : * length = ucnv_fromUChars(dest, capacity, src, length, error_code);
75 : * ucnv_close(cnv);
76 : * // IcuErrorCode destructor checks for success.
77 : * \endcode
78 : *
79 : * @stable ICU 4.2
80 : */
81 : class U_COMMON_API ErrorCode: public UMemory {
82 : public:
83 : /**
84 : * Default constructor. Initializes its UErrorCode to U_ZERO_ERROR.
85 : * @stable ICU 4.2
86 : */
87 : ErrorCode() : errorCode(U_ZERO_ERROR) {}
88 : /** Destructor, does nothing. See class documentation for details. @stable ICU 4.2 */
89 : virtual ~ErrorCode();
90 : /** Conversion operator, returns a reference. @stable ICU 4.2 */
91 : operator UErrorCode & () { return errorCode; }
92 : /** Conversion operator, returns a pointer. @stable ICU 4.2 */
93 : operator UErrorCode * () { return &errorCode; }
94 : /** Tests for U_SUCCESS(). @stable ICU 4.2 */
95 : UBool isSuccess() const { return U_SUCCESS(errorCode); }
96 : /** Tests for U_FAILURE(). @stable ICU 4.2 */
97 0 : UBool isFailure() const { return U_FAILURE(errorCode); }
98 : /** Returns the UErrorCode value. @stable ICU 4.2 */
99 : UErrorCode get() const { return errorCode; }
100 : /** Sets the UErrorCode value. @stable ICU 4.2 */
101 : void set(UErrorCode value) { errorCode=value; }
102 : /** Returns the UErrorCode value and resets it to U_ZERO_ERROR. @stable ICU 4.2 */
103 : UErrorCode reset();
104 : /**
105 : * Asserts isSuccess().
106 : * In other words, this method checks for a failure code,
107 : * and the base class handles it like this:
108 : * \code
109 : * if(isFailure()) { handleFailure(); }
110 : * \endcode
111 : * @stable ICU 4.4
112 : */
113 : void assertSuccess() const;
114 : /**
115 : * Return a string for the UErrorCode value.
116 : * The string will be the same as the name of the error code constant
117 : * in the UErrorCode enum.
118 : * @stable ICU 4.4
119 : */
120 : const char* errorName() const;
121 :
122 : protected:
123 : /**
124 : * Internal UErrorCode, accessible to subclasses.
125 : * @stable ICU 4.2
126 : */
127 : UErrorCode errorCode;
128 : /**
129 : * Called by assertSuccess() if isFailure() is true.
130 : * A subclass should override this function to deal with a failure code:
131 : * Throw an exception, log an error, terminate the program, or similar.
132 : * @stable ICU 4.2
133 : */
134 0 : virtual void handleFailure() const {}
135 : };
136 :
137 : U_NAMESPACE_END
138 :
139 : #endif // __ERRORCODE_H__
|