基于C++的ByteBuf封装
1、说明
netty 的 ByteBuf 中的 readerIndex 和 writerIndex 的设置十分巧妙,它内部对读取和写入位置进行控制,避免自己处理index的时候的各种麻烦,大大减少业务处理时的代码量
用 C++ 重构一下,删减了 netty 的 ByteBuf 中的一些不常用的接口
代码中其中只用到了 STL 的 string 和 unique_ptr,除此以外,再无其他依赖,轻量,易用,至少需要C++11以上的支持
直接上代码(含注释)
2、代码
ByteBuf.h
#ifndef SH_BYTE_BUF_H
#define SH_BYTE_BUF_H
#include <string>
#include <memory>
class ByteBufData;
namespace sh
{
enum Case
{
Lower = 0, //小写
Upper, //大写
};
/**
* ByteBuf封装,内置readerIndex和writerIndex基数,用于记录当前读取和写入的位置
*
* +-------------------+------------------+------------------+
* | discardable bytes | readable bytes | writable bytes |
* | | (CONTENT) | |
* +-------------------+------------------+------------------+
* | | | |
* 0 <= readerIndex <= writerIndex <= capacity
*
* @author: sherlock_lht
*/
class ByteBuf
{
public:
static char toHexLower(uint32_t value) noexcept;
static char toHexUpper(uint32_t value) noexcept;
static int32_t fromHex(uint32_t c) noexcept;
static ByteBuf fromHex(const std::string &hexEncoded) noexcept;
public:
explicit ByteBuf();
explicit ByteBuf(const char *data, int32_t size = -1);
explicit ByteBuf(const std::string &data);
explicit ByteBuf(int32_t size, char ch);
ByteBuf(const ByteBuf &other);
virtual ~ByteBuf();
ByteBuf &operator=(const ByteBuf &other);
/**
* 转换成16进制字符串
*/
std::string toHexString(Case type = Case::Lower, const std::string &fill_str = "") const;
/**
* 返回现有的字节数组
*/
const char *data() const noexcept;
/**
* 从readerIndex开始(包括readerIndex),到writerIndex结束(不包括writerIndex),找到buff内第一次出现的value的位置
* 该方法不会改变readerIndex和writerIndex
*
* @return value出现的位置到readerIndex之间的字节数,如果没找到则返回-1
*/
int32_t bytesBefore(char value);
/**
* 从readerIndex开始(包括readerIndex),到writerIndex结束(不包括writerIndex),找到buff内第一次出现连续长度为length的value的位置
* 该方法不会改变readerIndex和writerIndex
*
* @return value出现的位置到readerIndex之间的字节数,如果没找到则返回-1
*/
int32_t bytesBefore(int32_t length, char value);
/**
* 从index开始(包括index),到writerIndex结束(不包括writerIndex),找到buff内第一次出现连续长度为length的value的位置
* 该方法不会改变readerIndex和writerIndex
*
* @return value出现的位置到readerIndex之间的字节数,如果没找到则返回-1
*/
int32_t bytesBefore(int32_t index, int32_t length, char value);
/**
* 返回为对象分配的存储空间大小
*/
int32_t capacity() const;
/**
* 重新分配对象的存储空间大小,如果new_capacity不够存储现有的数据,则capacity保持不变
*/
ByteBuf &capacity(int32_t new_capacity);
/**
* readerIndex和writerIndex全部归零,等同于setIndex(0, 0)
*/
ByteBuf &clear();
/**
* 比较缓存区的数据内容,同strcmp
*/
int32_t compareTo(const ByteBuf &buffer) const;
/**
* 返回对象的可读字节数据的副本,即从readerIndex开始到writerIndex结束的数据
* 等同于 buf.copy(buf.readerIndex(), buf.readableBytes())
* 不影响原始对象的readerIndex和writerIndex,且两个对象互不影响
*/
ByteBuf copy() const;
/**
* 返回对象数据从index开始,长度的length的数据的副本
* 不影响原始对象的readerIndex和writerIndex,且两个对象互不影响
*/
ByteBuf copy(int32_t index, int32_t length) const;
/**
* 丢弃从0th到readerIndex之间的所有数据
* 即移动readerIndex到writerIndex之间的数据到0th,并且设置readerIndex和writerIndex为0
*/
ByteBuf &discardReadBytes();
/**
* 从buffer中定位第一次出现的value字符,搜索从fromIndex(包括fromIndex)到toIndex(不包括toIndex)
* 该方法不会改变readerIndex和writerIndex
*
* @return value第一次出现的下表,没找到返回-1
*/
int32_t indexOf(int32_t fromIndex, int32_t toIndex, char value) const;
/**
* 设置readerIndex和writerIndex,如果buffer内无数据,则无效;
* 如果readerIndex超出了buffer内数据的长度,则readerIndex = buffer.length() - 1;
* 如果writerIndex超出了buffer内数据的长度,则writerIndex = buffer.length()
*/
ByteBuf setIndex(int32_t readerIndex, int32_t writerIndex);
/**
* 只有当this.writerIndex - this.readerIndex大于0时,返回true
*/
bool isReadable() const;
/**
* 只有当this.writerIndex - this.readerIndex大于size时,返回true
*/
bool isReadable(int32_t size);
/**
* 标记当前的readerIndex,后面可以使用resetReaderIndex()撤回readerIndex到标记位置,初始标记位置为0
*/
ByteBuf &markReaderIndex();
/**
* 标记当前的writerIndex,后面可以使用resetWriterIndex()撤回resetWriterIndex到标记位置,初始标记位置为0
*/
ByteBuf &markWriterIndex();
/**
* 返回readerIndex
*/
int32_t readerIndex() const;
/**
* 设置readerIndex
*/
ByteBuf &readerIndex(int32_t reader_index);
/**
* 重新定位readerIndex到标记的readerIndex位置
*/
ByteBuf &resetReaderIndex();
/**
* 返回writerIndex
*/
int32_t writerIndex() const;
/**
* 设置writerIndex
*/
ByteBuf &writerIndex(int32_t writer_index);
/**
* 重新定位writerIndex到标记的writerIndex位置
*/
ByteBuf &resetWriterIndex();
/**
* 返回当前buffer中的可读的字节数,等同于(this.writerIndex - this.readerIndex)
*/
int32_t readableBytes() const;
/**
* 获取指定下标的字符
* 该方法不会修改readerIndex和writerIndex
*
* @return 如果index超出buffer数据长度,返回0
*/
char getByte(int32_t index) const;
/**
* 从指定的index位置,获取符合条件的字符,该方法不会修改readerIndex和writerIndex
*
* @return 返回实际获取的字符数目
*/
int32_t getBytes(int32_t index, char *dst) const;
int32_t getBytes(int32_t index, char *dst, int32_t length) const;
/**
* 从指定的index位置,获取符合条件的字符,该方法不会修改readerIndex和writerIndex
*/
ByteBuf getBytes(int32_t index) const;
ByteBuf getBytes(int32_t index, int32_t length) const;
ByteBuf getBytes(int32_t index, int32_t dstIndex, int32_t length) const;
/**
* 以下方法分别从index位置读取8/16/32/64位的数据,不会修改readerIndex和writerIndex
*/
int8_t getChar(int32_t index) const;
uint8_t getUnsignedChar(int32_t index) const;
int16_t getShort(int32_t index) const;
int16_t getShortLE(int32_t index) const;
uint16_t getUnsignedShort(int32_t index) const;
uint16_t getUnsignedShortLE(int32_t index) const;
int32_t getInt(int32_t index) const;
int32_t getIntLE(int32_t index) const;
uint32_t getUnsignedInt(int32_t index) const;
uint32_t getUnsignedIntLE(int32_t index) const;
int64_t getLong(int32_t index) const;
int64_t getLongLE(int32_t index) const;
uint64_t getUnsignedLong(int32_t index) const;
uint64_t getUnsignedLongLE(int32_t index) const;
float getFloat(int32_t index) const;
float getFloatLE(int32_t index) const;
double getDouble(int32_t index) const;
double getDoubleLE(int32_t index) const;
/**
* 以下方法分别从readerIndex位置读取8/16/32/64位的数据,readerIndex根据实际读出的位数增加
*/
int8_t readChar();
uint8_t readUnsignedChar();
int16_t readShort();
int16_t readShortLE();
uint16_t readUnsignedShort();
uint16_t readUnsignedShortLE();
int32_t readInt();
int32_t readIntLE();
uint32_t readUnsignedInt();
uint32_t readUnsignedIntLE();
int64_t readLong();
int64_t readLongLE();
uint64_t readUnsignedLong();
uint64_t readUnsignedLongLE();
ByteBuf readBytes(int32_t length);
double readDouble();
double readDoubleLE();
/**
* readerIndex增加指定长度
*/
ByteBuf &skipBytes(int32_t length);
/**
* 以下方法在index位置写入8/16/32/64位的数据,如果index超出现有数据范围,则追加,否则插入,不会修改readerIndex和writerIndex
*/
ByteBuf &setChar(int32_t index, int8_t value);
ByteBuf &setUnsignedChar(int32_t index, uint8_t value);
ByteBuf &setShort(int32_t index, int16_t value);
ByteBuf &setShortLE(int32_t index, int16_t value);
ByteBuf &setUnsignedShort(int32_t index, uint16_t value);
ByteBuf &setUnsignedShortLE(int32_t index, uint16_t value);
ByteBuf &setInt(int32_t index, int32_t value);
ByteBuf &setIntLE(int32_t index, int32_t value);
ByteBuf &setUnsignedInt(int32_t index, uint32_t value);
ByteBuf &setUnsignedIntLE(int32_t index, uint32_t value);
ByteBuf &setLong(int32_t index, int64_t value);
ByteBuf &setLongLE(int32_t index, int64_t value);
ByteBuf &setUnsignedLong(int32_t index, uint64_t value);
ByteBuf &setUnsignedLongLE(int32_t index, uint64_t value);
ByteBuf &setBytes(int32_t index, const ByteBuf &buf);
ByteBuf &setBytes(int32_t index, const char *data, int32_t size);
/**
* 从index位置填充指定长度的0,index超出现有数据,则追加,否则,插入,readerIndex和writerIndex不会改变
*/
ByteBuf &setZero(int32_t index, int32_t length);
/**
* 以下方法会在writerIndex位置写入8/16/32/64位数据,若writerIndex超出现有数据范围,则追加并调整,否则插入,writerIndex根据实际写入的情况调整位置
*/
ByteBuf &writeChar(int8_t value);
ByteBuf &writeUnsignedChar(uint8_t value);
ByteBuf &writeShort(int16_t value);
ByteBuf &writeShortLE(int16_t value);
ByteBuf &writeUnsignedShort(uint16_t value);
ByteBuf &writeUnsignedShortLE(uint16_t value);
ByteBuf &writeInt(int32_t value);
ByteBuf &writeIntLE(int32_t value);
ByteBuf &writeUnsignedInt(uint32_t value);
ByteBuf &writeUnsignedIntLE(uint32_t value);
ByteBuf &writeLong(int64_t value);
ByteBuf &writeLongLE(int64_t value);
ByteBuf &writeUnsignedLong(uint64_t value);
ByteBuf &writeUnsignedLongLE(uint64_t value);
ByteBuf &writeBytes(const ByteBuf &buf);
ByteBuf &writeBytes(const char *data, int32_t size);
/**
* 从writerIndex位置填充指定长度的0,writerIndex超出现有数据,则追加并调整,否则插入,writerIndex根据实际写入的情况调整位置
*/
ByteBuf &writeZero(int32_t length);
private:
std::unique_ptr<ByteBufData> d;
};
}
#endif//SH_BYTE_BUF_H
ByteBuf.cpp
#include "ByteBuf.h"
namespace
{
#define INT8_BIT sizeof(int8_t)
#define INT16_BIT sizeof(int16_t)
#define INT32_BIT sizeof(int32_t)
#define INT64_BIT sizeof(int64_t)
#define FLOAT_BIT sizeof(float)
#define DOUBLE_BIT sizeof(double)
}
class ByteBufData
{
public:
ByteBufData()
: readerIndex(0), writerIndex(0), markedReaderIndex(0), markedWriterIndex(0)
{}
private:
friend class sh::ByteBuf;
std::string originData;
int32_t readerIndex;
int32_t writerIndex;
int32_t markedReaderIndex;
int32_t markedWriterIndex;
private:
template<class T>
T getT(int32_t index, uint8_t max_bit) const
{
if (originData.length() - index < max_bit)
{
return 0;
}
T value = 0;
for (uint8_t delta = 0; delta < max_bit; delta++)
{
value += (originData.at(delta + index) & 0xff) << (8 * (max_bit - delta - 1));
}
return value;
}
template<class T>
T getTLE(int32_t index, uint8_t max_bit) const
{
if (originData.length() - index < max_bit)
{
return 0;
}
T value = 0;
for (uint8_t delta = 0; delta < max_bit; delta++)
{
value += (originData.at(delta + index) & 0xff) << (8 * delta);
}
return value;
}
template<class T>
T readT(uint8_t max_bit)
{
if (originData.length() - readerIndex < max_bit)
{
return 0;
}
T value = 0;
for (uint8_t delta = 0; delta < max_bit; delta++)
{
value += (originData.at(delta + readerIndex) & 0xff) << (8 * (max_bit - delta - 1));
}
readerIndex += max_bit;
return value;
}
template<class T>
T readTLE(uint8_t max_bit)
{
if (originData.length() - readerIndex < max_bit)
{
return 0;
}
T value = 0;
for (uint8_t delta = 0; delta < max_bit; delta++)
{
value += (originData.at(delta + readerIndex) & 0xff) << (8 * delta);
}
readerIndex += max_bit;
return value;
}
template<class T>
void setT(int32_t index, T value)
{
setData(index, toBinary(value));
}
template<class T>
void setTLE(int32_t index, T value)
{
setData(index, toBinaryLE(value));
}
void setData(int32_t index, const std::string &data)
{
if (index > originData.length())
{
originData.append(data);
}
else
{
originData.insert(index, data);
}
}
template<class T>
void writeT(T value)
{
writeData(toBinary(value));
}
template<class T>
void writeTLE(T value)
{
writeData(toBinaryLE(value));
}
void writeData(const std::string &data)
{
if (writerIndex > originData.length())
{
originData.append(data);
writerIndex = (int32_t) originData.length();
}
else
{
originData.insert(writerIndex, data);
writerIndex += (int32_t) data.length();
}
}
template<class T>
std::string toBinary(T value)
{
std::string result;
int8_t max_bit = sizeof(T);
for (uint8_t index = 0; index < max_bit; index++)
{
result.push_back(value >> (8 * (max_bit - index - 1)) & 0xff);
}
return result;
}
template<class T>
std::string toBinaryLE(T value)
{
std::string result;
int8_t max_bit = sizeof(T);
for (uint8_t index = 0; index < max_bit; index++)
{
result.push_back(value >> (8 * index) & 0xff);
}
return result;
}
};
sh::ByteBuf::ByteBuf()
{
d = std::unique_ptr<::ByteBufData>(new ByteBufData());
}
sh::ByteBuf::ByteBuf(const char *data, int32_t size)
{
d = std::unique_ptr<::ByteBufData>(new ByteBufData());
d->originData.append(data, size);
d->writerIndex += size;
}
sh::ByteBuf::ByteBuf(const std::string &data)
{
d = std::unique_ptr<::ByteBufData>(new ByteBufData());
d->originData.append(data);
d->writerIndex += data.length();
}
sh::ByteBuf::ByteBuf(int32_t size, char ch)
{
d = std::unique_ptr<::ByteBufData>(new ByteBufData());
d->originData.append(size, ch);
d->writerIndex += size;
}
sh::ByteBuf::ByteBuf(const sh::ByteBuf &other)
{
d = std::unique_ptr<::ByteBufData>(new ByteBufData());
d->originData.append(other.d->originData);
d->readerIndex = other.d->readerIndex;
d->writerIndex = other.d->writerIndex;
d->markedReaderIndex = other.d->markedReaderIndex;
d->markedWriterIndex = other.d->markedWriterIndex;
}
sh::ByteBuf::~ByteBuf() = default;
sh::ByteBuf &sh::ByteBuf::operator=(const sh::ByteBuf &other)
{
if (&other != this)
{
d->originData.append(other.d->originData);
d->readerIndex = other.d->readerIndex;
d->writerIndex = other.d->writerIndex;
d->markedReaderIndex = other.d->markedReaderIndex;
d->markedWriterIndex = other.d->markedWriterIndex;
}
return *this;
}
std::string sh::ByteBuf::toHexString(Case type, const std::string &fill_str) const
{
std::string result;
for (char ch: d->originData)
{
if (Case::Lower == type)
{
result.push_back(toHexLower(ch >> 4));
result.push_back(toHexLower(ch & 0xF));
}
else
{
result.push_back(toHexUpper(ch >> 4));
result.push_back(toHexUpper(ch & 0xF));
}
result.append(fill_str);
}
return result;
}
const char *sh::ByteBuf::data() const noexcept
{
return d->originData.data();
}
int32_t sh::ByteBuf::bytesBefore(char value)
{
for (int32_t index = d->readerIndex; index < d->writerIndex; index++)
{
if (d->originData.at(index) == value)
{
return index - d->readerIndex;
}
}
return -1;
}
int32_t sh::ByteBuf::bytesBefore(int32_t length, char value)
{
return bytesBefore(d->readerIndex, length, value);
}
int32_t sh::ByteBuf::bytesBefore(int32_t index, int32_t length, char value)
{
bool last_ok;
int32_t second_index;
for (; index < d->writerIndex - length; index++)
{
//找到第一个符合 && 剩余的长度足够
if (d->originData.at(index) == value && (index + length) < d->writerIndex)
{
last_ok = true;
//从后一个开始检查length-1个字符
for (second_index = index + 1; second_index < (index + length); second_index++)
{
if (d->originData.at(second_index) != value)
{
last_ok = false;
break;
}
}
if (last_ok)
{
return index - d->readerIndex;
}
}
}
return -1;
}
int32_t sh::ByteBuf::capacity() const
{
return (int32_t) d->originData.capacity();
}
sh::ByteBuf &sh::ByteBuf::capacity(int32_t new_capacity)
{
d->originData.reserve(new_capacity);
return *this;
}
sh::ByteBuf &sh::ByteBuf::clear()
{
d->readerIndex = 0;
d->writerIndex = 0;
return *this;
}
int32_t sh::ByteBuf::compareTo(const sh::ByteBuf &buffer) const
{
return d->originData.compare(buffer.d->originData);
}
sh::ByteBuf sh::ByteBuf::copy() const
{
return sh::ByteBuf(d->originData);
}
sh::ByteBuf sh::ByteBuf::copy(int32_t index, int32_t length) const
{
return sh::ByteBuf(d->originData.substr(index, length));
}
sh::ByteBuf &sh::ByteBuf::discardReadBytes()
{
d->originData = d->originData.substr(d->readerIndex + 1);
d->readerIndex = 0;
d->writerIndex = 0;
return *this;
}
int32_t sh::ByteBuf::indexOf(int32_t fromIndex, int32_t toIndex, char value) const
{
for (int32_t index = fromIndex; index < d->originData.length() && index < toIndex; index++)
{
if (d->originData.at(index) == value)
{
return index;
}
}
return -1;
}
sh::ByteBuf sh::ByteBuf::setIndex(int32_t readerIndex, int32_t writerIndex)
{
if (d->originData.empty())
{
return *this;
}
d->readerIndex = readerIndex;
d->writerIndex = writerIndex;
if (d->readerIndex >= d->originData.length())
{
d->readerIndex = (int32_t) d->originData.length() - 1;
}
if (d->writerIndex > d->originData.length())
{
d->writerIndex = (int32_t) d->originData.length();
}
return *this;
}
bool sh::ByteBuf::isReadable() const
{
return (d->writerIndex - d->readerIndex) > 0;
}
bool sh::ByteBuf::isReadable(int32_t size)
{
return (d->writerIndex - d->readerIndex) >= size;
}
sh::ByteBuf &sh::ByteBuf::markReaderIndex()
{
d->markedReaderIndex = d->readerIndex;
return *this;
}
sh::ByteBuf &sh::ByteBuf::markWriterIndex()
{
d->markedWriterIndex = d->writerIndex;
return *this;
}
int32_t sh::ByteBuf::readerIndex() const
{
return d->readerIndex;
}
sh::ByteBuf &sh::ByteBuf::readerIndex(int32_t reader_index)
{
if (reader_index <= d->writerIndex)
{
d->readerIndex = reader_index;
}
return *this;
}
sh::ByteBuf &sh::ByteBuf::resetReaderIndex()
{
d->readerIndex = d->markedReaderIndex;
return *this;
}
int32_t sh::ByteBuf::writerIndex() const
{
return d->writerIndex;
}
sh::ByteBuf &sh::ByteBuf::writerIndex(int32_t writer_index)
{
if (writer_index < d->originData.length())
{
d->writerIndex = writer_index;
}
return *this;
}
sh::ByteBuf &sh::ByteBuf::resetWriterIndex()
{
d->writerIndex = d->markedWriterIndex;
return *this;
}
int32_t sh::ByteBuf::readableBytes() const
{
return d->writerIndex - d->readerIndex;
}
char sh::ByteBuf::getByte(int32_t index) const
{
if (index >= d->originData.length())
{
return 0;
}
return d->originData.at(index);
}
int32_t sh::ByteBuf::getBytes(int32_t index, char *dst) const
{
if (index >= d->originData.length())
{
return 0;
}
std::string res = d->originData.substr(index);
*dst = *res.data();
return (int32_t) res.length();
}
int32_t sh::ByteBuf::getBytes(int32_t index, char *dst, int32_t length) const
{
if (index >= d->originData.length())
{
return 0;
}
std::string res = d->originData.substr(index, length);
*dst = *res.data();
return (int32_t) res.length();
}
sh::ByteBuf sh::ByteBuf::getBytes(int32_t index) const
{
if (index >= d->originData.length())
{
return sh::ByteBuf();
}
std::string res = d->originData.substr(index);
return sh::ByteBuf(res);
}
sh::ByteBuf sh::ByteBuf::getBytes(int32_t index, int32_t length) const
{
if (index >= d->originData.length())
{
return sh::ByteBuf();
}
std::string res = d->originData.substr(index, length);
return sh::ByteBuf(res);
}
sh::ByteBuf sh::ByteBuf::getBytes(int32_t index, int32_t dstIndex, int32_t length) const
{
if (index >= d->originData.length())
{
return sh::ByteBuf();
}
sh::ByteBuf data(dstIndex, 0);
std::string res = d->originData.substr(index, length);
data.writeBytes(res.data(), (int32_t) res.length());
return data;
}
int8_t sh::ByteBuf::getChar(int32_t index) const
{
if (index >= d->originData.length())
{
return 0;
}
return d->originData.at(index);
}
uint8_t sh::ByteBuf::getUnsignedChar(int32_t index) const
{
return getChar(index);
}
int16_t sh::ByteBuf::getShort(int32_t index) const
{
return d->getT<int16_t>(index, INT16_BIT);
}
int16_t sh::ByteBuf::getShortLE(int32_t index) const
{
return d->getTLE<int16_t>(index, INT16_BIT);
}
uint16_t sh::ByteBuf::getUnsignedShort(int32_t index) const
{
return d->getT<int16_t>(index, INT16_BIT);
}
uint16_t sh::ByteBuf::getUnsignedShortLE(int32_t index) const
{
return d->getTLE<int16_t>(index, INT16_BIT);
}
int32_t sh::ByteBuf::getInt(int32_t index) const
{
return d->getT<int32_t>(index, INT32_BIT);
}
int32_t sh::ByteBuf::getIntLE(int32_t index) const
{
return d->getTLE<int32_t>(index, INT32_BIT);
}
uint32_t sh::ByteBuf::getUnsignedInt(int32_t index) const
{
return d->getT<int32_t>(index, INT32_BIT);
}
uint32_t sh::ByteBuf::getUnsignedIntLE(int32_t index) const
{
return d->getTLE<int32_t>(index, INT32_BIT);
}
int64_t sh::ByteBuf::getLong(int32_t index) const
{
return d->getT<int64_t>(index, INT64_BIT);
}
int64_t sh::ByteBuf::getLongLE(int32_t index) const
{
return d->getTLE<int64_t>(index, INT64_BIT);
}
uint64_t sh::ByteBuf::getUnsignedLong(int32_t index) const
{
return d->getT<int64_t>(index, INT64_BIT);
}
uint64_t sh::ByteBuf::getUnsignedLongLE(int32_t index) const
{
return d->getTLE<int64_t>(index, INT64_BIT);
}
float sh::ByteBuf::getFloat(int32_t index) const
{
float result = 0.00;
if (d->originData.length() - index < FLOAT_BIT)
{
return 0.00;
}
char *p = (char *) &result;
for (; index < index + FLOAT_BIT; index++)
{
*(p + index) = d->originData.at(index);
}
return result;
}
float sh::ByteBuf::getFloatLE(int32_t index) const
{
float result = 0.00;
if (d->originData.length() - index < FLOAT_BIT)
{
return 0.00;
}
char *p = (char *) &result;
for (; index < index + FLOAT_BIT; index++)
{
*(p + index) = d->originData.at(FLOAT_BIT - index - 1);
}
return result;
}
double sh::ByteBuf::getDouble(int32_t index) const
{
double result = 0.00;
if (d->originData.length() - index < DOUBLE_BIT)
{
return 0.00;
}
char *p = (char *) &result;
for (; index < index + DOUBLE_BIT; index++)
{
*(p + index) = d->originData.at(index);
}
return result;
}
double sh::ByteBuf::getDoubleLE(int32_t index) const
{
double result = 0.00;
if (d->originData.length() - index < DOUBLE_BIT)
{
return 0.00;
}
char *p = (char *) &result;
for (; index < index + DOUBLE_BIT; index++)
{
*(p + index) = d->originData.at(DOUBLE_BIT - index - 1);
}
return result;
}
int8_t sh::ByteBuf::readChar()
{
if (d->originData.length() - d->readerIndex < INT8_BIT)
{
return 0;
}
return d->originData.at(d->readerIndex++);
}
uint8_t sh::ByteBuf::readUnsignedChar()
{
return readChar();
}
int16_t sh::ByteBuf::readShort()
{
return d->readT<int16_t>(INT16_BIT);
}
int16_t sh::ByteBuf::readShortLE()
{
return d->readTLE<int16_t>(INT16_BIT);
}
uint16_t sh::ByteBuf::readUnsignedShort()
{
return d->readT<int16_t>(INT16_BIT);
}
uint16_t sh::ByteBuf::readUnsignedShortLE()
{
return d->readTLE<int16_t>(INT16_BIT);
}
int32_t sh::ByteBuf::readInt()
{
return d->readT<int32_t>(INT32_BIT);
}
int32_t sh::ByteBuf::readIntLE()
{
return d->readTLE<int32_t>(INT32_BIT);
}
uint32_t sh::ByteBuf::readUnsignedInt()
{
return d->readT<int32_t>(INT32_BIT);
}
uint32_t sh::ByteBuf::readUnsignedIntLE()
{
return d->readTLE<int32_t>(INT32_BIT);
}
int64_t sh::ByteBuf::readLong()
{
return d->readT<int64_t>(INT64_BIT);
}
int64_t sh::ByteBuf::readLongLE()
{
return d->readTLE<int64_t>(INT64_BIT);
}
uint64_t sh::ByteBuf::readUnsignedLong()
{
return d->readT<int64_t>(INT64_BIT);
}
uint64_t sh::ByteBuf::readUnsignedLongLE()
{
return d->readTLE<int64_t>(INT64_BIT);
}
sh::ByteBuf sh::ByteBuf::readBytes(int32_t length)
{
std::string data = d->originData.substr(d->readerIndex, length);
d->readerIndex += (int32_t) data.length();
return sh::ByteBuf(data);
}
double sh::ByteBuf::readDouble()
{
double result = 0.00;
if (d->originData.length() - d->readerIndex < DOUBLE_BIT)
{
return 0.00;
}
char *p = (char *) &result;
for (; d->readerIndex < d->readerIndex + DOUBLE_BIT; d->readerIndex++)
{
*(p + d->readerIndex) = d->originData.at(d->readerIndex);
}
return result;
}
double sh::ByteBuf::readDoubleLE()
{
double result = 0.00;
if (d->originData.length() - d->readerIndex < DOUBLE_BIT)
{
return 0.00;
}
char *p = (char *) &result;
for (; d->readerIndex < d->readerIndex + DOUBLE_BIT; d->readerIndex++)
{
*(p + d->readerIndex) = d->originData.at(DOUBLE_BIT - d->readerIndex - 1);
}
return result;
}
sh::ByteBuf &sh::ByteBuf::skipBytes(int32_t length)
{
d->readerIndex += length;
if (d->readerIndex > d->originData.length())
{
d->readerIndex = (int32_t) d->originData.length();
}
return *this;
}
sh::ByteBuf &sh::ByteBuf::setChar(int32_t index, int8_t value)
{
d->setT(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setUnsignedChar(int32_t index, uint8_t value)
{
d->setT(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setShort(int32_t index, int16_t value)
{
d->setT(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setShortLE(int32_t index, int16_t value)
{
d->setTLE(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setUnsignedShort(int32_t index, uint16_t value)
{
d->setT(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setUnsignedShortLE(int32_t index, uint16_t value)
{
d->setTLE(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setInt(int32_t index, int32_t value)
{
d->setT(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setIntLE(int32_t index, int32_t value)
{
d->setTLE(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setUnsignedInt(int32_t index, uint32_t value)
{
d->setT(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setUnsignedIntLE(int32_t index, uint32_t value)
{
d->setTLE(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setLong(int32_t index, int64_t value)
{
d->setT(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setLongLE(int32_t index, int64_t value)
{
d->setTLE(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setUnsignedLong(int32_t index, uint64_t value)
{
d->setT(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setUnsignedLongLE(int32_t index, uint64_t value)
{
d->setTLE(index, value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::setBytes(int32_t index, const ByteBuf &buf)
{
d->setData(index, buf.data());
return *this;
}
sh::ByteBuf &sh::ByteBuf::setBytes(int32_t index, const char *data, int32_t size)
{
d->setData(index, std::string(data, size));
return *this;
}
sh::ByteBuf &sh::ByteBuf::setZero(int32_t index, int32_t length)
{
d->setData(index, std::string(length, 0));
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeChar(int8_t value)
{
d->writeT(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeUnsignedChar(uint8_t value)
{
d->writeT(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeShort(int16_t value)
{
d->writeT(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeShortLE(int16_t value)
{
d->writeTLE(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeUnsignedShort(uint16_t value)
{
d->writeT(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeUnsignedShortLE(uint16_t value)
{
d->writeTLE(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeInt(int32_t value)
{
d->writeT(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeIntLE(int32_t value)
{
d->writeTLE(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeUnsignedInt(uint32_t value)
{
d->writeT(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeUnsignedIntLE(uint32_t value)
{
d->writeTLE(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeLong(int64_t value)
{
d->writeT(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeLongLE(int64_t value)
{
d->writeTLE(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeUnsignedLong(uint64_t value)
{
d->writeT(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeUnsignedLongLE(uint64_t value)
{
d->writeTLE(value);
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeBytes(const ByteBuf &buf)
{
d->writeData(buf.data());
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeBytes(const char *data, int32_t size)
{
d->writeData(std::string(data, size));
return *this;
}
sh::ByteBuf &sh::ByteBuf::writeZero(int32_t length)
{
d->writeData(std::string(length, 0));
return *this;
}
char sh::ByteBuf::toHexLower(uint32_t value) noexcept
{
return "0123456789abcdef"[value & 0xF];
}
char sh::ByteBuf::toHexUpper(uint32_t value) noexcept
{
return "0123456789ABCDEF"[value & 0xF];
}
int32_t sh::ByteBuf::fromHex(uint32_t c) noexcept
{
return ((c >= '0') && (c <= '9')) ? int32_t(c - '0') :
((c >= 'A') && (c <= 'F')) ? int32_t(c - 'A' + 10) :
((c >= 'a') && (c <= 'f')) ? int32_t(c - 'a' + 10) :
/* otherwise */ -1;
}
sh::ByteBuf sh::ByteBuf::fromHex(const std::string &hexEncoded) noexcept
{
sh::ByteBuf data;
char ch = 0x00;
for (int32_t index = 0; index < hexEncoded.length() - 1; index++)
{
ch |= (char) fromHex(hexEncoded.at(index++)) << 4;
ch |= (char) fromHex(hexEncoded.at(index));
data.writeChar(ch);
ch = 0x00;
}
return data;
}