/ src / leveldb / include / leveldb / status.h
status.h
  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.
 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  
103  inline Status::Status(const Status& rhs) {
104    state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
105  }
106  
107  // NOLINTBEGIN(bugprone-unhandled-self-assignment)
108  inline Status& Status::operator=(const Status& rhs) {
109    // The following condition catches both aliasing (when this == &rhs),
110    // and the common case where both rhs and *this are ok.
111    if (state_ != rhs.state_) {
112      delete[] state_;
113      state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
114    }
115    return *this;
116  }
117  // NOLINTEND(bugprone-unhandled-self-assignment)
118  
119  inline Status& Status::operator=(Status&& rhs) noexcept {
120    std::swap(state_, rhs.state_);
121    return *this;
122  }
123  
124  }  // namespace leveldb
125  
126  #endif  // STORAGE_LEVELDB_INCLUDE_STATUS_H_