如下是一个简单的 c++ class。目标是作为一个容器管理一段连续的内存,并且可以简单别太浪费,不要内存泄漏地被 copy/move。
水平太菜自觉考虑难以周全,所以想要求 v 友们指教下代码还有哪些 bug。
无论是本身的指点,还是更好的实现思路的指教都非常感谢。
typedef uint8_t byte;
class Bytes {
public:
Bytes() noexcept : data_(nullptr), size_(0) {}
// 给定 string, 读取数据后保存
explicit Bytes(const string& data) noexcept
: Bytes(reinterpret_cast<const byte*>(data.data()), data.size()) {}
explicit Bytes(const byte* bytes, size_t size) noexcept {
assign(bytes, size);
}
Bytes(const Bytes& rhs) noexcept : data_(rhs.data_), size_(rhs.size_) {}
Bytes(const Bytes&& rhs) noexcept
: data_(std::move(rhs.data_)), size_(rhs.size_) {}
virtual ~Bytes() {}
const size_t size() const noexcept { return size_; }
const std::shared_ptr<byte> data() const noexcept { return data_; }
// return is empty
const bool Empty() const noexcept {
return data_.get() == nullptr || size() == 0;
}
string String() const noexcept {
return data_.get() == nullptr
? string()
: string(reinterpret_cast<const char*>(data_.get()), size());
}
string HexString() const noexcept {
size_t n = size_;
char* cout = new char[n * 2];
const char* rune = "0123456789abcdef";
for (size_t i = 0; i < n; i++) {
byte uc = data_.get()[i];
// little-endian
cout[2 * i] = rune[uc >> 4];
cout[2 * i + 1] = rune[uc & 0xf];
}
string out(cout, n * 2);
delete[] cout;
return out;
}
int Compare(const Bytes& that) const noexcept {
size_t sz = size();
size_t that_sz = that.size();
size_t min_sz = (sz < that_sz) ? sz : that_sz;
int r = memcmp(data().get(), that.data().get(), min_sz);
return r != 0 ? r : (sz == that_sz ? 0 : (sz < that_sz ? -1 : +1));
}
// Return the nth byte in the referenced data.
// Didn't check: n < size
byte& operator[](size_t n) noexcept { //
return data_.get()[n];
}
std::shared_ptr<byte> Resize(size_t size) noexcept {
std::shared_ptr<byte> new_data(new byte[size],
std::default_delete<byte[]>());
memset(new_data.get(), 0, size);
if (this->data_.get() != nullptr) {
size_t min_sz = (size < this->size_) ? size : this->size_;
memcpy(static_cast<byte*>(new_data.get()),
static_cast<const byte*>(this->data_.get()), min_sz);
}
this->data_.swap(new_data);
this->size_ = size;
return this->data_;
}
static Bytes ConcatBytes(const vector<Bytes>& v) noexcept {
Bytes bytes;
size_t sz = 0;
for (auto i : v) {
sz += i.size();
}
bytes.Resize(sz);
size_t off = 0;
for (auto i : v) {
bytes.writeTo(i.data_.get(), off, i.size());
off += i.size();
}
return bytes;
}
private:
std::shared_ptr<byte> data_;
size_t size_;
void clear() noexcept {
data_.reset();
size_ = 0;
}
void writeTo(const byte* bytes, size_t offset, size_t size) noexcept {
memcpy(data_.get() + offset, //
static_cast<const byte*>(bytes), size);
}
void assign(const byte* bytes, size_t size) noexcept {
std::shared_ptr<byte> new_data(new byte[size],
std::default_delete<byte[]>());
memcpy(static_cast<byte*>(new_data.get()), static_cast<const byte*>(bytes),
size);
size_ = size;
data_.swap(new_data);
}
};
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.