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