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