1b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/*
2b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru*******************************************************************************
3b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru*
483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius*   Copyright (C) 2009-2011, 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 *
4059d709d503bab6e2b61931737e662dd293b40578ccornelius * Inside Google, this class is modified to use Google error logging.
4159d709d503bab6e2b61931737e662dd293b40578ccornelius *
42b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Features:
43b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * - The constructor initializes the internal UErrorCode to U_ZERO_ERROR,
44b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   removing one common source of errors.
45b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * - Same use in C APIs taking a UErrorCode * (pointer)
46b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   and C++ taking UErrorCode & (reference) via conversion operators.
47b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * - Possible automatic checking for success when it goes out of scope.
48b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *
49b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Note: For automatic checking for success in the destructor, a subclass
50b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * must implement such logic in its own destructor because the base class
51b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * destructor cannot call a subclass function (like handleFailure()).
52b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * The ErrorCode base class destructor does nothing.
53b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *
54b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Note also: While it is possible for a destructor to throw an exception,
55b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * it is generally unsafe to do so. This means that in a subclass the destructor
56b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * and the handleFailure() function may need to take different actions.
57b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *
58b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Sample code:
59b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * \code
60b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   class IcuErrorCode: public icu::ErrorCode {
61b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   public:
6283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius *     virtual ~IcuErrorCode() {  // should be defined in .cpp as "key function"
63b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *       // Safe because our handleFailure() does not throw exceptions.
64b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *       if(isFailure()) { handleFailure(); }
65b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *     }
66b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   protected:
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *     virtual void handleFailure() const {
68b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *       log_failure(u_errorName(errorCode));
69b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *       exit(errorCode);
70b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *     }
71b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   };
72b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   IcuErrorCode error_code;
73b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   UConverter *cnv = ucnv_open("Shift-JIS", error_code);
74b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   length = ucnv_fromUChars(dest, capacity, src, length, error_code);
75b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   ucnv_close(cnv);
76b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *   // IcuErrorCode destructor checks for success.
77b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * \endcode
78b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @stable ICU 4.2
80b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */
81b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruclass U_COMMON_API ErrorCode: public UMemory {
82b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querupublic:
83b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    /**
84b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * Default constructor. Initializes its UErrorCode to U_ZERO_ERROR.
8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @stable ICU 4.2
86b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     */
87b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ErrorCode() : errorCode(U_ZERO_ERROR) {}
8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /** Destructor, does nothing. See class documentation for details. @stable ICU 4.2 */
8983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    virtual ~ErrorCode();
9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /** Conversion operator, returns a reference. @stable ICU 4.2 */
91b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    operator UErrorCode & () { return errorCode; }
9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /** Conversion operator, returns a pointer. @stable ICU 4.2 */
93b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    operator UErrorCode * () { return &errorCode; }
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /** Tests for U_SUCCESS(). @stable ICU 4.2 */
95b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UBool isSuccess() const { return U_SUCCESS(errorCode); }
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /** Tests for U_FAILURE(). @stable ICU 4.2 */
97b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UBool isFailure() const { return U_FAILURE(errorCode); }
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /** Returns the UErrorCode value. @stable ICU 4.2 */
99b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UErrorCode get() const { return errorCode; }
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /** Sets the UErrorCode value. @stable ICU 4.2 */
101b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    void set(UErrorCode value) { errorCode=value; }
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /** Returns the UErrorCode value and resets it to U_ZERO_ERROR. @stable ICU 4.2 */
103b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UErrorCode reset();
104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    /**
10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Asserts isSuccess().
10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * In other words, this method checks for a failure code,
10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * and the base class handles it like this:
108b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * \code
109b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     *   if(isFailure()) { handleFailure(); }
110b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * \endcode
11127f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
112b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     */
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    void assertSuccess() const;
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Return a string for the UErrorCode value.
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * The string will be the same as the name of the error code constant
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * in the UErrorCode enum.
11827f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* errorName() const;
121b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruprotected:
123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    /**
124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * Internal UErrorCode, accessible to subclasses.
12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @stable ICU 4.2
126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     */
127b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UErrorCode errorCode;
128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    /**
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Called by assertSuccess() if isFailure() is true.
130b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * A subclass should override this function to deal with a failure code:
131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * Throw an exception, log an error, terminate the program, or similar.
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @stable ICU 4.2
133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     */
13459d709d503bab6e2b61931737e662dd293b40578ccornelius
135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    virtual void handleFailure() const {}
136b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru};
137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_NAMESPACE_END
139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif  // __ERRORCODE_H__
141