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