LevelDB 错误码 Status

2021-04-05  本文已影响0人  wayyyy

一般而言,函数处理错误信息主要由错误代码与具体的错误描述信息组成。

LevelDB定义了6种错误状态码:

enum Code
{
    kOk = 0,
    kNotFound = 1,
    kCorruption = 2,
    kNotSupported = 3,
    kInvalidArgument = 4,
    kIOError = 5
};

并实现Status 类,将其进行封装:

class Status {
private:  
    const char *state_;
};

私有变量只是一个char指针,前4个字节存储message的长度,第5个字节存储code码,后边的字节存储消息本身。

Status::Status(Code code, const Slice &msg, const Slice &msg2)
{
    assert(code != kOk);
    const uint32_t len1 = static_cast<uint32_t>(msg.size());
    const uint32_t len2 = static_cast<uint32_t>(msg2.size());
    const uint32_t size = len1 + (len2 ? (2 + len2) : 0);
    char *result = new char[size + 5];
    std::memcpy(result, &size, sizeof(size));
    result[4] = static_cast<char>(code);
    std::memcpy(result + 5, msg.data(), len1);
    if (len2)
    {
          result[5 + len1] = ':';
          result[6 + len1] = ' ';
          std::memcpy(result + 7 + len1, msg2.data(), len2);
     }
     state_ = result;
}

拷贝,移动相关函数:

inline Status::Status(const Status &rhs)
{
    state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
}

inline Status &Status::operator=(const Status &rhs)
{
    // The following condition catches both aliasing (when this == &rhs),
    // and the common case where both rhs and *this are ok.
    if (state_ != rhs.state_)
    {
        delete[] state_;
        state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
    }
    return *this;
}

inline Status &Status::operator=(Status &&rhs) noexcept
{
    std::swap(state_, rhs.state_);
    return *this;
}

// Status.cpp
const char *Status::CopyState(const char *state)
{
    uint32_t size;
    std::memcpy(&size, state, sizeof(size));
    char *result = new char[size + 5];
    std::memcpy(result, state, size + 5);
    return result;
}

ToString()方法:

std::string Status::ToString() const
{
    if (state_ == nullptr)
    {
        return "OK";
    }
    else
    {
        char tmp[30];
        const char *type;

        switch (code())
        {
        case kOk:
            type = "OK";
            break;
        case kNotFound:
            type = "NotFound: ";
            break;
        case kCorruption:
            type = "Corruption: ";
            break;
        case kNotSupported:
            type = "Not implemented: ";
            break;
        case kInvalidArgument:
            type = "Invalid argument: ";
            break;
        case kIOError:
            type = "IO error: ";
            break;
        default:
            std::snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", static_cast<int>(code()));
            type = tmp;
            break;
        }
        
        std::string result(type);
        uint32_t length;
        std::memcpy(&length, state_, sizeof(length));
        result.append(state_ + 5, length);
        
        return result;
    }
}

有如下静态函数返回响应对象:

// Return a success status.
static Status OK() { return Status(); }

static Status InvalidArgument(const Slice &msg, const Slice &msg2 = Slice())
{
    return Status(kInvalidArgument, msg, msg2);
}

static Status IOError(const Slice &msg, const Slice &msg2 = Slice()) {
    return Status(kIOError, msg, msg2);
}

// 使用:
Status status = Status::InvalidArgument("XXXX");
上一篇下一篇

猜你喜欢

热点阅读