HDFS-9712. libhdfs++: Reimplement Status object as a normal struct

This commit is contained in:
Bob Hansen 2016-02-01 07:57:29 -05:00 committed by James Clampffer
parent ad23cf1490
commit 7e946c7e30
2 changed files with 64 additions and 84 deletions

View File

@ -23,43 +23,30 @@
namespace hdfs { namespace hdfs {
class StatusHelper;
class Status { class Status {
public: public:
// Create a success status. // Create a success status.
Status() : state_(NULL) { } Status() : code_(0) {};
~Status() { delete[] state_; } Status(int code, const char *msg);
explicit Status(int code, const char *msg); Status(int code, const char *msg1, const char *msg2);
// Copy the specified status. // Factory methods
Status(const Status& s); static Status OK();
void operator=(const Status& s); static Status InvalidArgument(const char *msg);
static Status ResourceUnavailable(const char *msg);
static Status Unimplemented();
static Status Exception(const char *expception_class_name, const char *error_message);
static Status Error(const char *error_message);
static Status Canceled();
// Return a success status. // success
static Status OK() { return Status(); } bool ok() const { return code_ == 0; }
static Status InvalidArgument(const char *msg)
{ return Status(kInvalidArgument, msg); }
static Status ResourceUnavailable(const char *msg)
{ return Status(kResourceUnavailable, msg); }
static Status Unimplemented()
{ return Status(kUnimplemented, ""); }
static Status Exception(const char *expception_class_name, const char *error_message)
{ return Status(kException, expception_class_name, error_message); }
static Status Error(const char *error_message)
{ return Exception("Exception", error_message); }
static Status Canceled()
{ return Status(kOperationCanceled,""); }
// Returns true iff the status indicates success.
bool ok() const { return (state_ == NULL); }
// Return a string representation of this status suitable for printing.
// Returns the string "OK" for success. // Returns the string "OK" for success.
std::string ToString() const; std::string ToString() const;
int code() const { // get error code
return (state_ == NULL) ? kOk : static_cast<int>(state_[4]); int code() const { return code_; }
}
enum Code { enum Code {
kOk = 0, kOk = 0,
@ -71,31 +58,10 @@ class Status {
}; };
private: private:
// OK status has a NULL state_. Otherwise, state_ is a new[] array int code_;
// of the following form: std::string msg_;
// state_[0..3] == length of message
// state_[4] == code
// state_[5..] == message
const char* state_;
explicit Status(int code, const char *msg1, const char *msg2);
static const char *CopyState(const char* s);
static const char *ConstructState(int code, const char *msg1, const char *msg2);
}; };
inline Status::Status(const Status& s) {
state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
}
inline void Status::operator=(const Status& s) {
// The following condition catches both aliasing (when this == &s),
// and the common case where both s and *this are ok.
if (state_ != s.state_) {
delete[] state_;
state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
}
}
} }
#endif #endif

View File

@ -19,48 +19,62 @@
#include "hdfspp/status.h" #include "hdfspp/status.h"
#include <cassert> #include <cassert>
#include <cstring> #include <sstream>
namespace hdfs { namespace hdfs {
Status::Status(int code, const char *msg1) Status::Status(int code, const char *msg1) : code_(code) {
: state_(ConstructState(code, msg1, nullptr)) {} if(msg1) {
msg_ = msg1;
Status::Status(int code, const char *msg1, const char *msg2)
: state_(ConstructState(code, msg1, msg2)) {}
const char *Status::ConstructState(int code, const char *msg1,
const char *msg2) {
assert(code != kOk);
const uint32_t len1 = strlen(msg1);
const uint32_t len2 = msg2 ? strlen(msg2) : 0;
const uint32_t size = len1 + (len2 ? (2 + len2) : 0);
char *result = new char[size + 8 + 2];
*reinterpret_cast<uint32_t *>(result) = size;
*reinterpret_cast<uint32_t *>(result + 4) = code;
memcpy(result + 8, msg1, len1);
if (len2) {
result[8 + len1] = ':';
result[9 + len1] = ' ';
memcpy(result + 10 + len1, msg2, len2);
} }
return result;
} }
Status::Status(int code, const char *msg1, const char *msg2) : code_(code) {
std::stringstream ss;
if(msg1) {
ss << msg1;
if(msg2) {
ss << ":" << msg2;
}
}
msg_ = ss.str();
}
Status Status::OK() {
return Status();
}
Status Status::InvalidArgument(const char *msg) {
return Status(kInvalidArgument, msg);
}
Status Status::ResourceUnavailable(const char *msg) {
return Status(kResourceUnavailable, msg);
}
Status Status::Unimplemented() {
return Status(kUnimplemented, "");
}
Status Status::Exception(const char *exception_class_name, const char *error_message) {
return Status(kException, exception_class_name, error_message);
}
Status Status::Error(const char *error_message) {
return Exception("Exception", error_message);
}
Status Status::Canceled() {
return Status(kOperationCanceled,"Operation canceled");
}
std::string Status::ToString() const { std::string Status::ToString() const {
if (!state_) { if (code_ == kOk) {
return "OK"; return "OK";
} else {
uint32_t length = *reinterpret_cast<const uint32_t *>(state_);
return std::string(state_ + 8, length);
} }
return msg_;
} }
const char *Status::CopyState(const char *state) {
uint32_t size;
memcpy(&size, state, sizeof(size));
char *result = new char[size + 8];
memcpy(result, state, size + 8);
return result;
}
} }