PResult.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015-2018 Digital Barriers plc. All rights reserved.
3  * Contact: http://www.digitalbarriers.com/
4  *
5  * This file is part of the Papillon SDK.
6  *
7  * You can't use, modify or distribute any part of this file without
8  * the explicit written agreements of Digital Barriers.
9  */
10 
15 #pragma once
16 #include <PapillonCommon.h>
17 #include <PString.h>
18 
19 PAPILLON_BEGIN_NAMESPACE
20 
32 #define ReturnIfFailed(expr) { \
33  papillon::PResult __ret = (expr); \
34  if (__ret.Failed()) \
35  return __ret; \
36 }
37 
38  // beta
39 #define P_ON_FAILURE(result) papillon::PResult __localErrorToStackIfFailure = result
40 #define P_RETURN(result) return __localErrorToStackIfFailure.Push(result)
41 #define P_RETURN_IF_FAILURE(expr) { papillon::PResult __ret = (expr); if (__ret.Failed()) return __localErrorToStackIfFailure.Push(__ret); }
42 
54 #define ReturnIfOk(expr) { \
55  papillon::PResult __ret = (expr); \
56  if (__ret.Ok()) \
57  return __ret; \
58 }
59 
71 #define LogAndReturnIfFailed(expr) { \
72  papillon::PResult __ret = (expr); \
73  if (__ret.LogErrorIfAny(papillon::PString::Empty(), PAPILLON_SRC_POS).Failed()) \
74  return __ret; \
75 }
76 
92 #define LogAndReturnIfFalse(expr, message) { \
93  bool result = (expr); \
94  if (!result) { \
95  papillon::PResult __ret = papillon::PResult::Error(message); \
96  __ret.LogErrorIfAny(papillon::PString::Empty(), PAPILLON_SRC_POS); \
97  return __ret; \
98  } \
99 }
100 
101 
102 #if !(defined(DOXYGEN_SHOULD_SKIP_THIS) || defined(SWIG))
103 /*
104  * Few extra macros to make removal of extra comma before __VA_ARGS__ cross compiler
105  * effectively it does
106  * #define LogIfError( ... ) LogErrorIfAny2(PAPILLON_SRC_POS, ##__VA_ARGS__ )
107  */
108 #define _ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15
109 #define HAS_COMMA(...) _ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
110 #define _TRIGGER_PARENTHESIS_(...) ,
111 
112 #define ISEMPTY(...) \
113 _ISEMPTY( \
114  /* test if there is just one argument, eventually an empty \
115  one */ \
116  HAS_COMMA(__VA_ARGS__), \
117  /* test if _TRIGGER_PARENTHESIS_ together with the argument \
118  adds a comma */ \
119  HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__), \
120  /* test if the argument together with a parenthesis \
121  adds a comma */ \
122  HAS_COMMA(__VA_ARGS__ (/*empty*/)), \
123  /* test if placing it between _TRIGGER_PARENTHESIS_ and the \
124  parenthesis adds a comma */ \
125  HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (/*empty*/)) \
126  )
127 
128 #define PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4
129 #define _ISEMPTY(_0, _1, _2, _3) HAS_COMMA(PASTE5(_IS_EMPTY_CASE_, _0, _1, _2, _3))
130 #define _IS_EMPTY_CASE_0001 ,
131 
132 #define LogIfError_H0( ... ) LogErrorIfAny2(PAPILLON_SRC_POS, __VA_ARGS__ )
133 #define LogIfError_H1( ... ) LogErrorIfAny2(PAPILLON_SRC_POS)
134 #define PASTE2(_0, _1) PASTE2H(_0, _1)
135 #define PASTE2H(_0, _1) _0 ## _1
136 
137 #define LogIfError( ... ) PASTE2(LogIfError_H, ISEMPTY(__VA_ARGS__)) (__VA_ARGS__)
138 #endif // DOXYGEN_SHOULD_SKIP_THIS or SWIG
139 
159 class PAPILLON_API_CORE PResult
160 {
161 public:
166  {
167  E_OK = 0,
168  E_ERROR_BAD_MEMORY_ALLOCATION = 1,
206  E_ERROR_UNDEFINED = 0xFFFF
207  };
208 
209 public:
213  static const PResult C_OK;
214 
218  static const PResult C_FALSE;
219 
223  static const PResult C_ERROR_UNKNOWN;
224 
229 
234 
239 
244 
249 
253  PResult() : p(0) {}
254 
258  explicit PResult(EReturnCode code);
259 
263  explicit PResult(EReturnCode code, const PString& message);
264 
268  PResult(const PResult& other);
269 
274  static PResult Error(const PString& errorMessage);
275 
280  static PResult ErrorBadCast(papillon::classid fromClassId, papillon::classid toClassId);
281 
286  static PResult ErrorNullPointer(const PString& errorMessage);
287 
292  static PResult ErrorSerialisation();
293 
299  static PResult ErrorSerialization();
300 
305  static PResult ErrorSerialisationUnsupportedFormat(papillon::ESerialisationFormat format);
306 
312  static PResult ErrorSerializationUnsupportedFormat(papillon::ESerialisationFormat format);
313 
318  static PResult ErrorDeserialisationReadFailed();
319 
325  static PResult ErrorDeserializationReadFailed();
326 
331  static PResult ErrorDeserialisationBadClassId();
332 
338  static PResult ErrorDeserializationBadClassId();
339 
344  static PResult ErrorDeserialisationUnsupportedFormat(papillon::ESerialisationFormat format);
345 
351  static PResult ErrorDeserializationUnsupportedFormat(papillon::ESerialisationFormat format);
352 
357  static PResult ErrorBadArgument(const PString& message);
358 
363  static PResult ErrorInvalidState(const PString& message);
364 
369  static PResult ErrorUnhandledCase(const PString& message);
370 
375  static PResult ErrorFileNotFound(const PString& filename);
376 
381  static PResult ErrorEndOfFile(const PString& message);
382 
387  static PResult ErrorOpenFileForWriting(const PString& filename);
388 
393  static PResult ErrorOpenFileForReading(const PString& filename);
394 
399  static PResult ErrorBadPluginParameters(const PString& message);
400 
405  static PResult ErrorFailedToCheckOutLicense(const PString& productName, const PString& productVersion, const PString& message);
406 
411  static PResult ErrorBadURIFormat(const PString& message);
412 
417  static PResult ErrorEndOfStream(const PString& message);
418 
423  static PResult ErrorStreamNotFound(const PString& message);
424 
429  static PResult ErrorServerDown(const PString& message);
430 
435  static PResult ErrorStreamNotAvailable(const PString& message);
436 
441  static PResult ErrorStreamClosed(const PString& message);
442 
447  static PResult ErrorStreamInvalidated(const PString& message);
448 
453  static PResult ErrorStreamKicked(const PString& message);
454 
459  static PResult ErrorTimeout(const PString& message);
460 
465  static PResult ErrorDestringifyNotSupported();
466 
470  ~PResult();
471 
475  PResult& operator=(const PResult& other);
476 
480  bool operator==(const PResult& other) const;
481 
485  bool operator!() const { return !Ok(); }
486 
490  operator bool() const { return Ok(); }
491 
495  EReturnCode GetCode() const;
496 
500  bool IsEndOfStream() const;
501 
505  PString GetErrorMessage() const;
506 
511  PResult& Push(const PResult& result);
512 
517  PResult& Pop();
518 
523  PResult& PrependErrorMessage(const PString& message);
524 
530  bool Ok() const;
531 
537  bool Failed() const { return !Ok(); }
538 
544  bool IsFalse() const;
545 
558  PResult& LogErrorIfAny(const PString& prefix = PString::Empty(), int32 lineNumber = 0, const PString& filename = PString::Empty());
559  const PResult& LogErrorIfAny(const PString& prefix = "", papillon::int32 lineNumber = 0, const PString& filename = PString::Empty()) const
560  {
561  return const_cast<PResult *>(this)->LogErrorIfAny(prefix, lineNumber, filename);
562  }
563 
564  PResult& LogErrorIfAny2(int32 lineNumber1, const PString& filename1, const PString& prefix = PString::Empty(), papillon::int32 lineNumber2 = 0, const PString& filename2 = PString::Empty());
565 
566  const PResult& LogErrorIfAny2(papillon::int32 lineNumber1, const PString& filename1, const PString& prefix = PString::Empty(), papillon::int32 lineNumber2 = 0, const PString& filename2 = PString::Empty()) const
567  {
568  return const_cast<PResult *>(this)->LogErrorIfAny2(lineNumber1, filename1, prefix, lineNumber2, filename2);
569  }
570 
578  void OrDie(const PString& prefix = PString::Empty(), int32 lineNumber = 0, const PString& filename = PString::Empty()) const;
579 
584  papillon::int32 Size() const;
585 
592  PResult Write(PByteStream& os, ESerialisationFormat format = papillon::E_BINARY_FORMAT) const;
593 
603  PResult Read(PByteStream& is, papillon::ESerialisationFormat format = papillon::E_BINARY_FORMAT);
604 
608  PString ToString() const;
609 
613  friend PAPILLON_API_CORE std::ostream& operator<<(std::ostream& os, const PResult& obj);
614 
615 private:
616  void Destroy();
617  void DeepCopy(const PResult& other);
618 
619 private:
620  void* p;
621 };
622 
623 PAPILLON_END_NAMESPACE
static const PResult C_ERROR_SERIALISATION_NOT_SUPPORTED
A constant holding the "serialisation not supported" result.
Definition: PResult.h:248
static const PResult C_ERROR_UNKNOWN
A constant holding the "unknown error" result.
Definition: PResult.h:223
static const PResult C_OK
A constant holding the "success" result.
Definition: PResult.h:213
The PString class provides an Unicode character strings.
Definition: PString.h:37
static const PResult C_ERROR_NOT_YET_IMPLEMENTED
A constant holding the "not yet implemented" result.
Definition: PResult.h:233
const PLogStream & operator<<(const PLogStream &os, void *ptr)
Definition: PLog.h:279
static const PResult C_FALSE
A constant holding the "false" result (not necessary an error).
Definition: PResult.h:218
const PResult & LogErrorIfAny(const PString &prefix="", papillon::int32 lineNumber=0, const PString &filename=PString::Empty()) const
Definition: PResult.h:559
The PResult class represents the result returned by most of Papillon functions; this class is used to...
Definition: PResult.h:159
PResult()
Constructs a empty result, same as SUCCESS.
Definition: PResult.h:253
static const PResult C_ERROR_NULL_OBJECT
A constant holding the "NULL object" result.
Definition: PResult.h:228
bool Failed() const
Returns true if the code of this result is not E_OK (failure), false otherwise.
Definition: PResult.h:537
static const PResult C_ERROR_NOT_SUPPORTED
A constant holding the "not supported" result.
Definition: PResult.h:238
static const PResult C_ERROR_NO_PRIVATE_IMPLEMENTATION
A constant holding the "no implementation" result.
Definition: PResult.h:243
Class PString: an unicode character strings (use copy-on-write idiom).
PString ToString(const T &t)
Definition: PString.h:757
EReturnCode
All the available return codes.
Definition: PResult.h:165
The PByteStream class is a generic byte stream (can be a memory stream or a file stream).
Definition: PByteStream.h:69
static const PString & Empty()
Returns the constant holding the empty string "".
Definition: PString.h:64
bool operator!() const
Enables a PResult object to be cast to boolean easily.
Definition: PResult.h:485
const PResult & LogErrorIfAny2(papillon::int32 lineNumber1, const PString &filename1, const PString &prefix=PString::Empty(), papillon::int32 lineNumber2=0, const PString &filename2=PString::Empty()) const
Definition: PResult.h:566
PAPILLON_BEGIN_NAMESPACE typedef uint16_t classid
Definition: PRtti.h:21