File: error.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (170 lines) | stat: -rw-r--r-- 5,371 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

//=============================================================================
//
// Universal error class, that may be used both as a return value or
// thrown as an exception.
//
//=============================================================================

#ifndef AGS_SHARED_UTIL_ERROR_H
#define AGS_SHARED_UTIL_ERROR_H

#include "common/std/memory.h"
#include "ags/shared/util/string.h"

namespace AGS3 {
namespace AGS {
namespace Shared {

class Error;
typedef std::shared_ptr<Error> PError;

//
// A simple struct, that provides several fields to describe an error in the program.
// If wanted, may be reworked into subclass of std::exception.
//
class Error {
public:
	Error(int code, String general, PError inner_error = PError()) : _code(code), _general(general), _innerError(inner_error) {
	}
	Error(int code, String general, String comment, PError inner_error = PError()) : _code(code), _general(general), _comment(comment), _innerError(inner_error) {
	}
	Error(String general, PError inner_error = PError()) : _code(0), _general(general), _innerError(inner_error) {
	}
	Error(String general, String comment, PError inner_error = PError()) : _code(0), _general(general), _comment(comment), _innerError(inner_error) {
	}


	// Error code is a number, defining error subtype. It is not much use to the end-user,
	// but may be checked in the program to know more precise cause of the error.
	int    Code() const {
		return _code;
	}
	// General description of this error type and subtype.
	String General() const {
		return _general;
	}
	// Any complementary information.
	String Comment() const {
		return _comment;
	}
	PError InnerError() const {
		return _innerError;
	}
	// Full error message combines general description and comment.
	// NOTE: if made a child of std::exception, FullMessage may be substituted
	// or complemented with virtual const char* what().
	String FullMessage() const {
		String msg;
		const Error *err = this;
		do {
			msg.Append(err->General());
			if (!err->Comment().IsEmpty()) {
				msg.AppendChar('\n');
				msg.Append(err->Comment());
			}
			err = err->InnerError().get();
			if (err)
				msg.AppendChar('\n');
		} while (err);
		return msg;
	}

private:
	int    _code; // numeric code, for specific uses
	String _general; // general description of this error class
	String _comment; // additional information about particular case
	PError _innerError; // previous error that caused this one
};


// ErrorHandle is a helper class that lets you have an Error object
// wrapped in a smart pointer. ErrorHandle's only data member is a
// shared_ptr, which means that it does not cause too much data copying
// when used as a function's return value.
// Note, that the reason to have distinct class instead of a shared_ptr's
// typedef is an inverted boolean comparison:
// shared_ptr converts to 'true' when it contains an object, but ErrorHandle
// returns 'true' when it *does NOT* contain an object, meaning there
// is no error.
template <class T> class ErrorHandle {
public:
	static ErrorHandle<T> None() {
		return ErrorHandle();
	}

	ErrorHandle() {}
	ErrorHandle(T *err) : _error(err) {
	}
	ErrorHandle(std::shared_ptr<T> err) : _error(err) {
	}

	bool HasError() const {
		return _error.get() != NULL;
	}
	explicit operator bool() const {
		return _error.get() == nullptr;
	}
	operator PError() const {
		return _error;
	}
	T *operator ->() const {
		return _error.operator->();
	}
	T &operator *() const {
		return _error.operator * ();
	}

private:
	std::shared_ptr<T> _error;
};


// Basic error handle, containing Error object
typedef ErrorHandle<Error> HError;


// TypedCodeError is the Error's subclass, which only purpose is to override
// error code type in constructor and Code() getter, that may be useful if
// you'd like to restrict code values to particular enumerator.
// TODO: a type identifier as a part of template (string, or perhaps a int16
// to be placed at high-bytes in Code) to be able to distinguish error group.
template <typename CodeType, String(*GetErrorText)(CodeType)>
class TypedCodeError : public Error {
public:
	TypedCodeError(CodeType code, PError inner_error = PError()) : Error(code, GetErrorText(code), inner_error) {
	}
	TypedCodeError(CodeType code, String comment, PError inner_error = PError()) :
		Error(code, GetErrorText(code), comment, inner_error) {
	}

	CodeType Code() const {
		return (CodeType)Error::Code();
	}
};

} // namespace Shared
} // namespace AGS
} // namespace AGS3

#endif