00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef KUDU_UTIL_STATUS_H_
00014 #define KUDU_UTIL_STATUS_H_
00015
00016 #include <stdint.h>
00017 #include <string>
00018
00019 #ifdef KUDU_HEADERS_NO_STUBS
00020 #include "kudu/gutil/macros.h"
00021 #include "kudu/gutil/port.h"
00022 #else
00023 #include "kudu/client/stubs.h"
00024 #endif
00025
00026 #include "kudu/util/kudu_export.h"
00027 #include "kudu/util/slice.h"
00028
00030 #define KUDU_RETURN_NOT_OK(s) do { \
00031 const ::kudu::Status& _s = (s); \
00032 if (PREDICT_FALSE(!_s.ok())) return _s; \
00033 } while (0);
00034
00037 #define KUDU_RETURN_NOT_OK_PREPEND(s, msg) do { \
00038 const ::kudu::Status& _s = (s); \
00039 if (PREDICT_FALSE(!_s.ok())) return _s.CloneAndPrepend(msg); \
00040 } while (0);
00041
00045 #define KUDU_RETURN_NOT_OK_RET(to_call, to_return) do { \
00046 const ::kudu::Status& s = (to_call); \
00047 if (PREDICT_FALSE(!s.ok())) return (to_return); \
00048 } while (0);
00049
00051 #define KUDU_WARN_NOT_OK(to_call, warning_prefix) do { \
00052 const ::kudu::Status& _s = (to_call); \
00053 if (PREDICT_FALSE(!_s.ok())) { \
00054 KUDU_LOG(WARNING) << (warning_prefix) << ": " << _s.ToString(); \
00055 } \
00056 } while (0);
00057
00059 #define KUDU_LOG_AND_RETURN(level, status) do { \
00060 const ::kudu::Status& _s = (status); \
00061 KUDU_LOG(level) << _s.ToString(); \
00062 return _s; \
00063 } while (0);
00064
00067 #define KUDU_CHECK_OK_PREPEND(to_call, msg) do { \
00068 const ::kudu::Status& _s = (to_call); \
00069 KUDU_CHECK(_s.ok()) << (msg) << ": " << _s.ToString(); \
00070 } while (0);
00071
00074 #define KUDU_CHECK_OK(s) KUDU_CHECK_OK_PREPEND(s, "Bad status")
00075
00089 #ifdef KUDU_HEADERS_USE_SHORT_STATUS_MACROS
00090 #define RETURN_NOT_OK KUDU_RETURN_NOT_OK
00091 #define RETURN_NOT_OK_PREPEND KUDU_RETURN_NOT_OK_PREPEND
00092 #define RETURN_NOT_OK_RET KUDU_RETURN_NOT_OK_RET
00093 #define WARN_NOT_OK KUDU_WARN_NOT_OK
00094 #define LOG_AND_RETURN KUDU_LOG_AND_RETURN
00095 #define CHECK_OK_PREPEND KUDU_CHECK_OK_PREPEND
00096 #define CHECK_OK KUDU_CHECK_OK
00097
00098
00099 #define KUDU_LOG LOG
00100 #define KUDU_CHECK CHECK
00101 #endif
00102
00103 namespace kudu {
00104
00106 class KUDU_EXPORT Status {
00107 public:
00109 Status() : state_(NULL) { }
00110
00111 ~Status() { delete[] state_; }
00112
00117 Status(const Status& s);
00118
00123 void operator=(const Status& s);
00124
00125 #if __cplusplus >= 201103L
00130 Status(Status&& s);
00131
00136 void operator=(Status&& s);
00137 #endif
00138
00140 static Status OK() { return Status(); }
00141
00142
00154 static Status NotFound(const Slice& msg, const Slice& msg2 = Slice(),
00155 int16_t posix_code = -1) {
00156 return Status(kNotFound, msg, msg2, posix_code);
00157 }
00158 static Status Corruption(const Slice& msg, const Slice& msg2 = Slice(),
00159 int16_t posix_code = -1) {
00160 return Status(kCorruption, msg, msg2, posix_code);
00161 }
00162 static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice(),
00163 int16_t posix_code = -1) {
00164 return Status(kNotSupported, msg, msg2, posix_code);
00165 }
00166 static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice(),
00167 int16_t posix_code = -1) {
00168 return Status(kInvalidArgument, msg, msg2, posix_code);
00169 }
00170 static Status IOError(const Slice& msg, const Slice& msg2 = Slice(),
00171 int16_t posix_code = -1) {
00172 return Status(kIOError, msg, msg2, posix_code);
00173 }
00174 static Status AlreadyPresent(const Slice& msg, const Slice& msg2 = Slice(),
00175 int16_t posix_code = -1) {
00176 return Status(kAlreadyPresent, msg, msg2, posix_code);
00177 }
00178 static Status RuntimeError(const Slice& msg, const Slice& msg2 = Slice(),
00179 int16_t posix_code = -1) {
00180 return Status(kRuntimeError, msg, msg2, posix_code);
00181 }
00182 static Status NetworkError(const Slice& msg, const Slice& msg2 = Slice(),
00183 int16_t posix_code = -1) {
00184 return Status(kNetworkError, msg, msg2, posix_code);
00185 }
00186 static Status IllegalState(const Slice& msg, const Slice& msg2 = Slice(),
00187 int16_t posix_code = -1) {
00188 return Status(kIllegalState, msg, msg2, posix_code);
00189 }
00190 static Status NotAuthorized(const Slice& msg, const Slice& msg2 = Slice(),
00191 int16_t posix_code = -1) {
00192 return Status(kNotAuthorized, msg, msg2, posix_code);
00193 }
00194 static Status Aborted(const Slice& msg, const Slice& msg2 = Slice(),
00195 int16_t posix_code = -1) {
00196 return Status(kAborted, msg, msg2, posix_code);
00197 }
00198 static Status RemoteError(const Slice& msg, const Slice& msg2 = Slice(),
00199 int16_t posix_code = -1) {
00200 return Status(kRemoteError, msg, msg2, posix_code);
00201 }
00202 static Status ServiceUnavailable(const Slice& msg, const Slice& msg2 = Slice(),
00203 int16_t posix_code = -1) {
00204 return Status(kServiceUnavailable, msg, msg2, posix_code);
00205 }
00206 static Status TimedOut(const Slice& msg, const Slice& msg2 = Slice(),
00207 int16_t posix_code = -1) {
00208 return Status(kTimedOut, msg, msg2, posix_code);
00209 }
00210 static Status Uninitialized(const Slice& msg, const Slice& msg2 = Slice(),
00211 int16_t posix_code = -1) {
00212 return Status(kUninitialized, msg, msg2, posix_code);
00213 }
00214 static Status ConfigurationError(const Slice& msg, const Slice& msg2 = Slice(),
00215 int16_t posix_code = -1) {
00216 return Status(kConfigurationError, msg, msg2, posix_code);
00217 }
00218 static Status Incomplete(const Slice& msg, const Slice& msg2 = Slice(),
00219 int64_t posix_code = -1) {
00220 return Status(kIncomplete, msg, msg2, posix_code);
00221 }
00222 static Status EndOfFile(const Slice& msg, const Slice& msg2 = Slice(),
00223 int64_t posix_code = -1) {
00224 return Status(kEndOfFile, msg, msg2, posix_code);
00225 }
00227
00229 bool ok() const { return (state_ == NULL); }
00230
00232 bool IsNotFound() const { return code() == kNotFound; }
00233
00235 bool IsCorruption() const { return code() == kCorruption; }
00236
00238 bool IsNotSupported() const { return code() == kNotSupported; }
00239
00241 bool IsIOError() const { return code() == kIOError; }
00242
00244 bool IsInvalidArgument() const { return code() == kInvalidArgument; }
00245
00247 bool IsAlreadyPresent() const { return code() == kAlreadyPresent; }
00248
00250 bool IsRuntimeError() const { return code() == kRuntimeError; }
00251
00253 bool IsNetworkError() const { return code() == kNetworkError; }
00254
00256 bool IsIllegalState() const { return code() == kIllegalState; }
00257
00259 bool IsNotAuthorized() const { return code() == kNotAuthorized; }
00260
00262 bool IsAborted() const { return code() == kAborted; }
00263
00265 bool IsRemoteError() const { return code() == kRemoteError; }
00266
00268 bool IsServiceUnavailable() const { return code() == kServiceUnavailable; }
00269
00271 bool IsTimedOut() const { return code() == kTimedOut; }
00272
00274 bool IsUninitialized() const { return code() == kUninitialized; }
00275
00277 bool IsConfigurationError() const { return code() == kConfigurationError; }
00278
00280 bool IsIncomplete() const { return code() == kIncomplete; }
00281
00283 bool IsEndOfFile() const { return code() == kEndOfFile; }
00284
00287 std::string ToString() const;
00288
00291 std::string CodeAsString() const;
00292
00301 Slice message() const;
00302
00305 int16_t posix_code() const;
00306
00313 Status CloneAndPrepend(const Slice& msg) const;
00314
00321 Status CloneAndAppend(const Slice& msg) const;
00322
00325 size_t memory_footprint_excluding_this() const;
00326
00329 size_t memory_footprint_including_this() const;
00330
00331 private:
00332
00333
00334
00335
00336
00337
00338 const char* state_;
00339
00340 enum Code {
00341 kOk = 0,
00342 kNotFound = 1,
00343 kCorruption = 2,
00344 kNotSupported = 3,
00345 kInvalidArgument = 4,
00346 kIOError = 5,
00347 kAlreadyPresent = 6,
00348 kRuntimeError = 7,
00349 kNetworkError = 8,
00350 kIllegalState = 9,
00351 kNotAuthorized = 10,
00352 kAborted = 11,
00353 kRemoteError = 12,
00354 kServiceUnavailable = 13,
00355 kTimedOut = 14,
00356 kUninitialized = 15,
00357 kConfigurationError = 16,
00358 kIncomplete = 17,
00359 kEndOfFile = 18,
00360
00361
00362
00363
00364
00365 };
00366 COMPILE_ASSERT(sizeof(Code) == 4, code_enum_size_is_part_of_abi);
00367
00368 Code code() const {
00369 return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);
00370 }
00371
00372 Status(Code code, const Slice& msg, const Slice& msg2, int16_t posix_code);
00373 static const char* CopyState(const char* s);
00374 };
00375
00376 inline Status::Status(const Status& s) {
00377 state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
00378 }
00379 inline void Status::operator=(const Status& s) {
00380
00381
00382 if (state_ != s.state_) {
00383 delete[] state_;
00384 state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
00385 }
00386 }
00387
00388 #if __cplusplus >= 201103L
00389 inline Status::Status(Status&& s) : state_(s.state_) {
00390 s.state_ = nullptr;
00391 }
00392
00393 inline void Status::operator=(Status&& s) {
00394 if (state_ != s.state_) {
00395 delete[] state_;
00396 state_ = s.state_;
00397 s.state_ = nullptr;
00398 }
00399 }
00400 #endif
00401
00402 }
00403
00404 #endif // KUDU_UTIL_STATUS_H_