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 {
class StatusHelper;
class Status {
public:
// Create a success status.
Status() : state_(NULL) { }
~Status() { delete[] state_; }
explicit Status(int code, const char *msg);
Status() : code_(0) {};
Status(int code, const char *msg);
Status(int code, const char *msg1, const char *msg2);
// Copy the specified status.
Status(const Status& s);
void operator=(const Status& s);
// Factory methods
static Status OK();
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.
static Status OK() { return Status(); }
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,""); }
// success
bool ok() const { return code_ == 0; }
// 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.
std::string ToString() const;
int code() const {
return (state_ == NULL) ? kOk : static_cast<int>(state_[4]);
}
// get error code
int code() const { return code_; }
enum Code {
kOk = 0,
@ -71,31 +58,10 @@ class Status {
};
private:
// OK status has a NULL state_. Otherwise, state_ is a new[] array
// of the following form:
// 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);
int code_;
std::string msg_;
};
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

View File

@ -19,48 +19,62 @@
#include "hdfspp/status.h"
#include <cassert>
#include <cstring>
#include <sstream>
namespace hdfs {
Status::Status(int code, const char *msg1)
: state_(ConstructState(code, msg1, nullptr)) {}
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);
Status::Status(int code, const char *msg1) : code_(code) {
if(msg1) {
msg_ = msg1;
}
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 {
if (!state_) {
if (code_ == kOk) {
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;
}
}