big endian (comes from RocketMQ)

#ifndef BASE_BIG_ENDIAN_H_
#define BASE_BIG_ENDIAN_H_
 
template <typename T>
inline void ReadBigEndian(const char buf[], T* out) {
  *out = buf[0];
  for (size_t i = 1; i < sizeof(T); ++i) {
    *out <<= 8;
    // Must cast to uint8_t to avoid clobbering by sign extension.
    *out |= static_cast<uint8_t>(buf[i]);
   }
}
 
template <typename T>
inline void WriteBigEndian(char buf[], T val) {
  for (size_t i = 0; i < sizeof(T); ++i) {
    buf[sizeof(T) - i - 1] = static_cast<char>(val & 0xFF);
    val >>= 8;
  }
}
 
class BigEndianReader {
public:
BigEndianReader(const char* buf, size_t len);

const char* ptr() const { return ptr_; }
int remaining() const { return end_ - ptr_; }

bool Skip(size_t len);
bool ReadBytes(void* out, size_t len);
bool ReadU8(uint8_t* value);
bool ReadU16(uint16_t* value);
bool ReadU32(uint32_t* value);
bool ReadU64(uint64_t* value);

private:
// Hidden to promote type safety.
template <typename T>
bool Read(T* v);

const char* ptr_;
const char* end_;
};
 
class BigEndianWriter {
public:
BigEndianWriter(char* buf, size_t len);

char* ptr() const { return ptr_; }
int remaining() const { return end_ - ptr_; }

bool Skip(size_t len);
bool WriteBytes(const void* buf, size_t len);
bool WriteU8(uint8_t value);
bool WriteU16(uint16_t value);
bool WriteU32(uint32_t value);
bool WriteU64(uint64_t value);

private:
// Hidden to promote type safety.
template <typename T>
bool Write(T v);

char* ptr_;
char* end_;
};
#endif // BASE_BIG_ENDIAN_H_
 
====================================================================
#include "big_endian.h"
#include <cstdlib>
#include <cstring>


BigEndianReader::BigEndianReader(const char* buf, size_t len) : ptr_(buf), end_(ptr_ + len) {}

bool BigEndianReader::Skip(size_t len) {
if (ptr_ + len > end_)
return false;
ptr_ += len;
return true;
}

bool BigEndianReader::ReadBytes(void* out, size_t len) {
if (ptr_ + len > end_)
return false;
memcpy(out, ptr_, len);
ptr_ += len;
return true;
}

template <typename T>
bool BigEndianReader::Read(T* value) {
if (ptr_ + sizeof(T) > end_)
return false;
ReadBigEndian<T>(ptr_, value);
ptr_ += sizeof(T);
return true;
}

bool BigEndianReader::ReadU8(uint8_t* value) {
return Read(value);
}

bool BigEndianReader::ReadU16(uint16_t* value) {
return Read(value);
}

bool BigEndianReader::ReadU32(uint32_t* value) {
return Read(value);
}

bool BigEndianReader::ReadU64(uint64_t* value) {
return Read(value);
}

BigEndianWriter::BigEndianWriter(char* buf, size_t len) : ptr_(buf), end_(ptr_ + len) {}

bool BigEndianWriter::Skip(size_t len) {
if (ptr_ + len > end_)
return false;
ptr_ += len;
return true;
}

bool BigEndianWriter::WriteBytes(const void* buf, size_t len) {
if (ptr_ + len > end_)
return false;
memcpy(ptr_, buf, len);
ptr_ += len;
return true;
}

template <typename T>
bool BigEndianWriter::Write(T value) {
if (ptr_ + sizeof(T) > end_)
return false;
WriteBigEndian<T>(ptr_, value);
ptr_ += sizeof(T);
return true;
}

bool BigEndianWriter::WriteU8(uint8_t value) {
return Write(value);
}

bool BigEndianWriter::WriteU16(uint16_t value) {
return Write(value);
}

bool BigEndianWriter::WriteU32(uint32_t value) {
return Write(value);
}

bool BigEndianWriter::WriteU64(uint64_t value) {
return Write(value);
}



 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章