1// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file. See the AUTHORS file for names of contributors.
4//
5// A Status encapsulates the result of an operation. It may indicate success,
6// or it may indicate an error with an associated error message.
7//
8// Multiple threads can invoke const methods on a Status without
9// external synchronization, but if any of the threads may call a
10// non-const method, all threads accessing the same Status must use
11// external synchronization.
12
13#ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_
14#define STORAGE_LEVELDB_INCLUDE_STATUS_H_
15
16#include <algorithm>
17#include <string>
18
19#include "leveldb/export.h"
20#include "leveldb/slice.h"
21
22namespace leveldb {
23
24class LEVELDB_EXPORT Status {
25 public:
26 // Create a success status.
27 Status() noexcept : state_(nullptr) {}
28 ~Status() { delete[] state_; }
29
30 Status(const Status& rhs);
31 Status& operator=(const Status& rhs);
32
33 Status(Status&& rhs) noexcept : state_(rhs.state_) { rhs.state_ = nullptr; }
34 Status& operator=(Status&& rhs) noexcept;
35
36 // Return a success status.
37 static Status OK() { return Status(); }
38
39 // Return error status of an appropriate type.
40 static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) {
41 return Status(kNotFound, msg, msg2);
42 }
43 static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) {
44 return Status(kCorruption, msg, msg2);
45 }
46 static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) {
47 return Status(kNotSupported, msg, msg2);
48 }
49 static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) {
50 return Status(kInvalidArgument, msg, msg2);
51 }
52 static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) {
53 return Status(kIOError, msg, msg2);
54 }
55
56 // Returns true iff the status indicates success.
57 bool ok() const { return (state_ == nullptr); }
58
59 // Returns true iff the status indicates a NotFound error.
60 bool IsNotFound() const { return code() == kNotFound; }
61
62 // Returns true iff the status indicates a Corruption error.
63 bool IsCorruption() const { return code() == kCorruption; }
64
65 // Returns true iff the status indicates an IOError.
66 bool IsIOError() const { return code() == kIOError; }
67
68 // Returns true iff the status indicates a NotSupportedError.
69 bool IsNotSupportedError() const { return code() == kNotSupported; }
70
71 // Returns true iff the status indicates an InvalidArgument.
72 bool IsInvalidArgument() const { return code() == kInvalidArgument; }
73
74 // Return a string representation of this status suitable for printing.
75 // Returns the string "OK" for success.
76 std::string ToString() const;
77
78 private:
79 enum Code {
80 kOk = 0,
81 kNotFound = 1,
82 kCorruption = 2,
83 kNotSupported = 3,
84 kInvalidArgument = 4,
85 kIOError = 5
86 };
87
88 Code code() const {
89 return (state_ == nullptr) ? kOk : static_cast<Code>(state_[4]);
90 }
91
92 Status(Code code, const Slice& msg, const Slice& msg2);
93 static const char* CopyState(const char* s);
94
95 // OK status has a null state_. Otherwise, state_ is a new[] array
96 // of the following form:
97 // state_[0..3] == length of message
98 // state_[4] == code
99 // state_[5..] == message
100 const char* state_;
101};
102
103inline Status::Status(const Status& rhs) {
104 state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
105}
106inline Status& Status::operator=(const Status& rhs) {
107 // The following condition catches both aliasing (when this == &rhs),
108 // and the common case where both rhs and *this are ok.
109 if (state_ != rhs.state_) {
110 delete[] state_;
111 state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
112 }
113 return *this;
114}
115inline Status& Status::operator=(Status&& rhs) noexcept {
116 std::swap(state_, rhs.state_);
117 return *this;
118}
119
120} // namespace leveldb
121
122#endif // STORAGE_LEVELDB_INCLUDE_STATUS_H_
123