xref: /aosp_15_r20/external/leveldb/include/leveldb/status.h (revision 9507f98c5f32dee4b5f9e4a38cd499f3ff5c4490)
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 
22 namespace leveldb {
23 
24 class LEVELDB_EXPORT Status {
25  public:
26   // Create a success status.
Status()27   Status() noexcept : state_(nullptr) {}
~Status()28   ~Status() { delete[] state_; }
29 
30   Status(const Status& rhs);
31   Status& operator=(const Status& rhs);
32 
Status(Status && rhs)33   Status(Status&& rhs) noexcept : state_(rhs.state_) { rhs.state_ = nullptr; }
34   Status& operator=(Status&& rhs) noexcept;
35 
36   // Return a success status.
OK()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.
ok()57   bool ok() const { return (state_ == nullptr); }
58 
59   // Returns true iff the status indicates a NotFound error.
IsNotFound()60   bool IsNotFound() const { return code() == kNotFound; }
61 
62   // Returns true iff the status indicates a Corruption error.
IsCorruption()63   bool IsCorruption() const { return code() == kCorruption; }
64 
65   // Returns true iff the status indicates an IOError.
IsIOError()66   bool IsIOError() const { return code() == kIOError; }
67 
68   // Returns true iff the status indicates a NotSupportedError.
IsNotSupportedError()69   bool IsNotSupportedError() const { return code() == kNotSupported; }
70 
71   // Returns true iff the status indicates an InvalidArgument.
IsInvalidArgument()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 
code()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 
Status(const Status & rhs)103 inline Status::Status(const Status& rhs) {
104   state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
105 }
106 inline 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 }
115 inline 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