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 <string>
17#include "leveldb/slice.h"
18
19namespace leveldb {
20
21class Status {
22 public:
23  // Create a success status.
24  Status() : state_(NULL) { }
25  ~Status() { delete[] state_; }
26
27  // Copy the specified status.
28  Status(const Status& s);
29  void operator=(const Status& s);
30
31  // Return a success status.
32  static Status OK() { return Status(); }
33
34  // Return error status of an appropriate type.
35  static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) {
36    return Status(kNotFound, msg, msg2);
37  }
38  static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) {
39    return Status(kCorruption, msg, msg2);
40  }
41  static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) {
42    return Status(kNotSupported, msg, msg2);
43  }
44  static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) {
45    return Status(kInvalidArgument, msg, msg2);
46  }
47  static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) {
48    return Status(kIOError, msg, msg2);
49  }
50
51  // Returns true iff the status indicates success.
52  bool ok() const { return (state_ == NULL); }
53
54  // Returns true iff the status indicates a NotFound error.
55  bool IsNotFound() const { return code() == kNotFound; }
56
57  // Returns true iff the status indicates a Corruption error.
58  bool IsCorruption() const { return code() == kCorruption; }
59
60  // Returns true iff the status indicates an IOError.
61  bool IsIOError() const { return code() == kIOError; }
62
63  // Return a string representation of this status suitable for printing.
64  // Returns the string "OK" for success.
65  std::string ToString() const;
66
67 private:
68  // OK status has a NULL state_.  Otherwise, state_ is a new[] array
69  // of the following form:
70  //    state_[0..3] == length of message
71  //    state_[4]    == code
72  //    state_[5..]  == message
73  const char* state_;
74
75  enum Code {
76    kOk = 0,
77    kNotFound = 1,
78    kCorruption = 2,
79    kNotSupported = 3,
80    kInvalidArgument = 4,
81    kIOError = 5
82  };
83
84  Code code() const {
85    return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);
86  }
87
88  Status(Code code, const Slice& msg, const Slice& msg2);
89  static const char* CopyState(const char* s);
90};
91
92inline Status::Status(const Status& s) {
93  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
94}
95inline void Status::operator=(const Status& s) {
96  // The following condition catches both aliasing (when this == &s),
97  // and the common case where both s and *this are ok.
98  if (state_ != s.state_) {
99    delete[] state_;
100    state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
101  }
102}
103
104}  // namespace leveldb
105
106#endif  // STORAGE_LEVELDB_INCLUDE_STATUS_H_
107