Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cpp.ByteBuffer.h Maven / Gradle / Ivy
Go to download
zfoo protocol is binary serialization framework for Java/C++/js/ts/C#/Go/Lua/GDScript/Python
#ifndef ZFOO_BYTEBUFFER_H
#define ZFOO_BYTEBUFFER_H
#include
#include
#include
#include
#include
#include
#include
// 网络传输默认使用大端传输
namespace zfoo {
using std::string;
using std::vector;
using std::list;
using std::set;
using std::map;
using std::make_pair;
using std::pair;
using std::unique_ptr;
// Returns true if the current machine is little endian
static inline bool is_little_endian() {
static int32_t test = 1;
return (*reinterpret_cast(&test) == 1);
}
// Default size of the buffer
static const int32_t DEFAULT_BUFFER_SIZE = 2048;
static const bool IS_LITTLE_ENDIAN = is_little_endian();
static const string EMPTY_STRING = "";
class ByteBuffer;
class IProtocol {
public:
virtual int16_t protocolId() = 0;
virtual ~IProtocol() {
}
};
class IProtocolRegistration {
public:
virtual int16_t protocolId() = 0;
virtual void write(ByteBuffer &buffer, IProtocol *packet) = 0;
virtual IProtocol *read(ByteBuffer &buffer) = 0;
};
IProtocolRegistration *getProtocol(int16_t protocolId);
class ByteBuffer {
private:
int8_t *buffer;
int32_t max_capacity;
int32_t writeOffset;
int32_t readOffset;
public:
ByteBuffer(int32_t capacity = DEFAULT_BUFFER_SIZE) : max_capacity(capacity) {
buffer = (int8_t *) calloc(max_capacity, sizeof(int8_t));
clear();
}
~ByteBuffer() {
free(buffer);
buffer = nullptr;
}
ByteBuffer(const ByteBuffer &buffer) = delete;
ByteBuffer &operator=(const ByteBuffer &buffer) = delete;
void adjustPadding(int32_t predictionLength, int32_t beforeWriteIndex) {
int32_t currentWriteIndex = getWriteOffset();
int32_t predictionCount = writeIntCount(predictionLength);
int32_t length = currentWriteIndex - beforeWriteIndex - predictionCount;
int32_t lengthCount = writeIntCount(length);
int32_t padding = lengthCount - predictionCount;
if (padding == 0) {
setWriteOffset(beforeWriteIndex);
writeInt(length);
setWriteOffset(currentWriteIndex);
} else {
// int8_t *targetPtr = (int8_t *) calloc(length, sizeof(int8_t));
// memcpy(targetPtr, &buffer[currentWriteIndex - length], length);
// setWriteOffset(beforeWriteIndex);
// writeInt(length);
// writeBytes(targetPtr, length);
// free(targetPtr);
memmove(&buffer[beforeWriteIndex + lengthCount], &buffer[currentWriteIndex - length], length);
setWriteOffset(beforeWriteIndex);
writeInt(length);
setWriteOffset(beforeWriteIndex + lengthCount + length);
}
}
bool compatibleRead(int32_t beforeReadIndex, int32_t length) {
return length != -1 && getReadOffset() < length + beforeReadIndex;
}
void clear() {
writeOffset = 0;
readOffset = 0;
}
int8_t *getBuffer() {
return buffer;
}
int32_t getWriteOffset() const {
return writeOffset;
}
int32_t getReadOffset() const {
return readOffset;
}
void setWriteOffset(int32_t writeIndex) {
if (writeIndex > max_capacity) {
string errorMessage =
"writeIndex[" + std::to_string(writeIndex) + "] out of bounds exception: readOffset: " +
std::to_string(readOffset) +
", writeOffset: " + std::to_string(writeOffset) +
"(expected: 0 <= readOffset <= writeOffset <= capacity:" + std::to_string(max_capacity) + ")";
throw errorMessage;
}
writeOffset = writeIndex;
}
void setReadOffset(int32_t readIndex) {
if (readIndex > writeOffset) {
string errorMessage =
"readIndex[" + std::to_string(readIndex) + "] out of bounds exception: readOffset: " +
std::to_string(readOffset) +
", writeOffset: " + std::to_string(writeOffset) +
"(expected: 0 <= readOffset <= writeOffset <= capacity:" + std::to_string(max_capacity) + ")";
throw errorMessage;
}
readOffset = readIndex;
}
inline int32_t getCapacity() const {
return max_capacity - writeOffset;
}
inline void ensureCapacity(const int32_t &capacity) {
while (capacity - getCapacity() > 0) {
int32_t newSize = max_capacity * 2;
int8_t *pBuf = (int8_t *) realloc(buffer, newSize);
if (!pBuf) {
string errorMessage = "relloc failed!";
throw errorMessage;
}
buffer = pBuf;
max_capacity = newSize;
}
}
inline bool isReadable() {
return writeOffset > readOffset;
}
inline void writeBool(const bool &value) {
ensureCapacity(1);
int8_t v = value ? 1 : 0;
buffer[writeOffset++] = v;
}
inline bool readBool() {
int8_t value = buffer[readOffset++];
return value == 1;
}
inline void writeByte(const int8_t &value) {
ensureCapacity(1);
buffer[writeOffset++] = value;
}
inline int8_t readByte() {
return buffer[readOffset++];
}
inline void setByte(const int32_t &index, const int8_t &value) {
buffer[index] = value;
}
inline int8_t getByte(const int32_t &index) {
return buffer[index];
}
inline void writeBytes(const int8_t *buf, const int32_t &length) {
ensureCapacity(length);
memcpy(&buffer[writeOffset], buf, length);
writeOffset += length;
}
inline int8_t *readBytes(const int32_t &length) {
int8_t *bytes = &buffer[readOffset];
readOffset += length;
return bytes;
}
inline void writeShort(const int16_t &value) {
write(value);
}
inline int16_t readShort() {
return read();
}
inline void writeInt(const int32_t &intValue) {
writeVarInt((uint32_t) ((intValue << 1) ^ (intValue >> 31)));
}
inline void writeVarInt(const uint32_t &value) {
uint32_t a = value >> 7;
if (a == 0) {
writeByte((int8_t) value);
return;
}
int32_t writeIndex = writeOffset;
ensureCapacity(5);
setByte(writeIndex++, (int8_t) (value | 0x80));
uint32_t b = value >> 14;
if (b == 0) {
setByte(writeIndex++, (int8_t) a);
setWriteOffset(writeIndex);
return;
}
setByte(writeIndex++, (int8_t) (a | 0x80));
a = value >> 21;
if (a == 0) {
setByte(writeIndex++, (int8_t) b);
setWriteOffset(writeIndex);
return;
}
setByte(writeIndex++, (int8_t) (b | 0x80));
b = value >> 28;
if (b == 0) {
setByte(writeIndex++, (int8_t) a);
setWriteOffset(writeIndex);
return;
}
setByte(writeIndex++, (int8_t) (a | 0x80));
setByte(writeIndex++, (int8_t) b);
setWriteOffset(writeIndex);
}
inline int32_t writeIntCount(const int32_t &intValue) {
uint32_t value = (uint32_t) ((intValue << 1) ^ (intValue >> 31));
if (value >> 7 == 0) {
return 1;
}
if (value >> 14 == 0) {
return 2;
}
if (value >> 21 == 0) {
return 3;
}
if (value >> 28 == 0) {
return 4;
}
return 5;
}
inline int32_t readInt() {
int32_t readIndex = readOffset;
int32_t b = getByte(readIndex++);
uint32_t value = b;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x0000007F | b << 7;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x00003FFF | b << 14;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x001FFFFF | b << 21;
if (b < 0) {
value = value & 0x0FFFFFFF | getByte(readIndex++) << 28;
}
}
}
}
setReadOffset(readIndex);
value = ((value >> 1) ^ -((int32_t) value & 1));
return (int32_t) value;
}
inline void writeLong(const int64_t &longValue) {
uint64_t mask = (uint64_t) ((longValue << 1) ^ (longValue >> 63));
if (mask >> 32 == 0) {
writeVarInt((uint32_t) mask);
return;
}
int8_t bytes[9];
bytes[0] = (int8_t) (mask | 0x80);
bytes[1] = (int8_t) (mask >> 7 | 0x80);
bytes[2] = (int8_t) (mask >> 14 | 0x80);
bytes[3] = (int8_t) (mask >> 21 | 0x80);
uint32_t a = (uint32_t) (mask >> 28);
uint32_t b = (uint32_t) (mask >> 35);
if (b == 0) {
bytes[4] = (int8_t) a;
writeBytes(bytes, 5);
return;
}
bytes[4] = (int8_t) (a | 0x80);
a = (uint32_t) (mask >> 42);
if (a == 0) {
bytes[5] = (int8_t) b;
writeBytes(bytes, 6);
return;
}
bytes[5] = (int8_t) (b | 0x80);
b = (int) (mask >> 49);
if (b == 0) {
bytes[6] = (int8_t) a;
writeBytes(bytes, 7);
return;
}
bytes[6] = (int8_t) (a | 0x80);
a = (int) (mask >> 56);
if (a == 0) {
bytes[7] = (int8_t) b;
writeBytes(bytes, 8);
return;
}
bytes[7] = (int8_t) (b | 0x80);
bytes[8] = (int8_t) a;
writeBytes(bytes, 9);
}
inline int64_t readLong() {
int32_t readIndex = readOffset;
int64_t b = getByte(readIndex++);
uint64_t value = b;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x000000000000007FLL | b << 7;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x0000000000003FFFLL | b << 14;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x00000000001FFFFFLL | b << 21;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x000000000FFFFFFFLL | b << 28;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x00000007FFFFFFFFLL | b << 35;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x000003FFFFFFFFFFLL | b << 42;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x0001FFFFFFFFFFFFLL | b << 49;
if (b < 0) {
b = getByte(readIndex++);
value = value & 0x00FFFFFFFFFFFFFFLL | b << 56;
}
}
}
}
}
}
}
}
setReadOffset(readIndex);
value = ((value >> 1) ^ -((int64_t) value & 1));
return (int64_t) value;
}
inline void writeFloat(const float &value) {
write(value);
}
inline float readFloat() {
return read();
}
inline void writeDouble(const double &value) {
write(value);
}
inline double readDouble() {
return read();
}
inline void writeString(const string &value) {
if (value.empty()) {
writeInt(0);
return;
}
int32_t length = value.size() * sizeof(value.front());
writeInt(length);
writeBytes(reinterpret_cast(&value[0]), length);
}
inline string readString() {
int32_t length = readInt();
if (length <= 0) {
return EMPTY_STRING;
}
auto bytes = readBytes(length);
string str(reinterpret_cast(bytes), length);
return str;
}
inline void writePacket(IProtocol *packet, const int16_t &protocolId) {
IProtocolRegistration *protocolRegistration = getProtocol(protocolId);
protocolRegistration->write(*this, packet);
}
inline unique_ptr readPacket(const int16_t &protocolId) {
IProtocolRegistration *protocolRegistration = getProtocol(protocolId);
auto packet = protocolRegistration->read(*this);
return unique_ptr(packet);
}
//---------------------------------boolean--------------------------------------
inline void writeBoolArray(const vector &array) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writeBool(value);
}
}
inline vector readBoolArray() {
int32_t length = readInt();
int8_t *bytes = readBytes(length);
vector array;
for (auto i = 0; i < length; i++) {
array.emplace_back((bytes[i] == 1));
}
return array;
}
inline void writeBoolList(const list &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeBool(value);
}
}
inline list readBoolList() {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
list.emplace_back(readBool());
}
return list;
}
inline void writeBoolSet(const set &set) {
if (set.empty()) {
writeByte(0);
return;
}
int32_t length = set.size();
writeInt(length);
for (auto value: set) {
writeBool(value);
}
}
inline set readBoolSet() {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
set.emplace(readBool());
}
return set;
}
//---------------------------------byte--------------------------------------
inline void writeByteArray(const vector &array) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writeByte(value);
}
}
inline vector readByteArray() {
int32_t length = readInt();
int8_t *bytes = readBytes(length);
vector array;
for (auto i = 0; i < length; i++) {
array.emplace_back(bytes[i]);
}
return array;
}
inline void writeByteList(const list &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeByte(value);
}
}
inline list readByteList() {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
list.emplace_back(readByte());
}
return list;
}
inline void writeByteSet(const set &set) {
if (set.empty()) {
writeByte(0);
return;
}
int32_t length = set.size();
writeInt(length);
for (auto value: set) {
writeByte(value);
}
}
inline set readByteSet() {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
set.emplace(readByte());
}
return set;
}
//---------------------------------short--------------------------------------
inline void writeShortArray(const vector &array) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writeShort(value);
}
}
inline vector readShortArray() {
int32_t length = readInt();
vector array;
for (auto i = 0; i < length; i++) {
array.emplace_back(readShort());
}
return array;
}
inline void writeShortList(const list &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeShort(value);
}
}
inline list readShortList() {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
list.emplace_back(readShort());
}
return list;
}
inline void writeShortSet(const set &set) {
if (set.empty()) {
writeByte(0);
return;
}
int32_t length = set.size();
writeInt(length);
for (auto value: set) {
writeShort(value);
}
}
inline set readShortSet() {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
set.emplace(readShort());
}
return set;
}
//---------------------------------int--------------------------------------
inline void writeIntArray(const vector &array) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writeInt(value);
}
}
inline vector readIntArray() {
int32_t length = readInt();
vector array;
for (auto i = 0; i < length; i++) {
array.emplace_back(readInt());
}
return array;
}
inline void writeIntList(const list &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeInt(value);
}
}
inline list readIntList() {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
list.emplace_back(readInt());
}
return list;
}
inline void writeIntSet(const set &set) {
if (set.empty()) {
writeByte(0);
return;
}
int32_t length = set.size();
writeInt(length);
for (auto value: set) {
writeInt(value);
}
}
inline set readIntSet() {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
set.emplace(readInt());
}
return set;
}
//---------------------------------long--------------------------------------
inline void writeLongArray(const vector &array) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writeLong(value);
}
}
inline vector readLongArray() {
int32_t length = readInt();
vector array;
for (auto i = 0; i < length; i++) {
array.emplace_back(readLong());
}
return array;
}
inline void writeLongList(const list &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeLong(value);
}
}
inline list readLongList() {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
list.emplace_back(readLong());
}
return list;
}
inline void writeLongSet(const set &set) {
if (set.empty()) {
writeByte(0);
return;
}
int32_t length = set.size();
writeInt(length);
for (auto value: set) {
writeLong(value);
}
}
inline set readLongSet() {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
set.emplace(readLong());
}
return set;
}
//---------------------------------float--------------------------------------
inline void writeFloatArray(const vector &array) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writeFloat(value);
}
}
inline vector readFloatArray() {
int32_t length = readInt();
vector array;
for (auto i = 0; i < length; i++) {
array.emplace_back(readFloat());
}
return array;
}
inline void writeFloatList(const list &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeFloat(value);
}
}
inline list readFloatList() {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
list.emplace_back(readFloat());
}
return list;
}
inline void writeFloatSet(const set &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeFloat(value);
}
}
inline set readFloatSet() {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
set.emplace(readFloat());
}
return set;
}
//---------------------------------double--------------------------------------
inline void writeDoubleArray(const vector &array) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writeDouble(value);
}
}
inline vector readDoubleArray() {
int32_t length = readInt();
vector array;
for (auto i = 0; i < length; i++) {
array.emplace_back(readDouble());
}
return array;
}
inline void writeDoubleList(const list &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeDouble(value);
}
}
inline list readDoubleList() {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
list.emplace_back(readDouble());
}
return list;
}
inline void writeDoubleSet(const set &set) {
if (set.empty()) {
writeByte(0);
return;
}
int32_t length = set.size();
writeInt(length);
for (auto value: set) {
writeDouble(value);
}
}
inline set readDoubleSet() {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
set.emplace(readDouble());
}
return set;
}
//---------------------------------string--------------------------------------
inline void writeStringArray(const vector &array) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writeString(value);
}
}
inline vector readStringArray() {
int32_t length = readInt();
vector array;
for (auto i = 0; i < length; i++) {
array.emplace_back(readString());
}
return array;
}
inline void writeStringList(const list &list) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writeString(value);
}
}
inline list readStringList() {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
list.emplace_back(readString());
}
return list;
}
inline void writeStringSet(const set &set) {
if (set.empty()) {
writeByte(0);
return;
}
int32_t length = set.size();
writeInt(length);
for (auto value: set) {
writeString(value);
}
}
inline set readStringSet() {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
set.emplace(readString());
}
return set;
}
inline void writeIntIntMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeInt(key);
writeInt(value);
}
}
inline map readIntIntMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readInt();
auto value = readInt();
map.insert(pair(key, value));
}
return map;
}
inline void writeIntLongMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeInt(key);
writeLong(value);
}
}
inline map readIntLongMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readInt();
auto value = readLong();
map.insert(pair(key, value));
}
return map;
}
inline void writeIntStringMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeInt(key);
writeString(value);
}
}
inline map readIntStringMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readInt();
auto value = readString();
map.insert(pair(key, value));
}
return map;
}
template
inline void writeIntPacketMap(const map &map, const int16_t &protocolId) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeInt(key);
writePacket((IProtocol *) &value, protocolId);
}
}
template
inline map readIntPacketMap(const int16_t &protocolId) {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readInt();
auto value = readPacket(protocolId);
auto *p = (T *) value.get();
map.insert(pair(key, *p));
}
return map;
}
inline void writeLongIntMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeLong(key);
writeInt(value);
}
}
inline map readLongIntMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readLong();
auto value = readInt();
map.insert(pair(key, value));
}
return map;
}
inline void writeLongLongMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeLong(key);
writeLong(value);
}
}
inline map readLongLongMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readLong();
auto value = readLong();
map.insert(pair(key, value));
}
return map;
}
inline void writeLongStringMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeLong(key);
writeString(value);
}
}
inline map readLongStringMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readLong();
auto value = readString();
map.insert(pair(key, value));
}
return map;
}
template
inline void writeLongPacketMap(const map &map, const int16_t &protocolId) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeLong(key);
writePacket((IProtocol *) &value, protocolId);
}
}
template
inline map readLongPacketMap(const int16_t &protocolId) {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readLong();
auto value = readPacket(protocolId);
auto *p = (T *) value.get();
map.insert(pair(key, *p));
}
return map;
}
inline void writeStringIntMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeString(key);
writeInt(value);
}
}
inline map readStringIntMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readString();
auto value = readInt();
map.insert(pair(key, value));
}
return map;
}
inline void writeStringLongMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeString(key);
writeLong(value);
}
}
inline map readStringLongMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readString();
auto value = readLong();
map.insert(pair(key, value));
}
return map;
}
inline void writeStringStringMap(const map &map) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeString(key);
writeString(value);
}
}
inline map readStringStringMap() {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readString();
auto value = readString();
map.insert(pair(key, value));
}
return map;
}
template
inline void writeStringPacketMap(const map &map, const int16_t &protocolId) {
if (map.empty()) {
writeByte(0);
return;
}
writeInt(map.size());
for (const auto &[key, value]: map) {
writeString(key);
writePacket((IProtocol *) &value, protocolId);
}
}
template
inline map readStringPacketMap(const int16_t &protocolId) {
int32_t length = readInt();
map map;
for (auto i = 0; i < length; i++) {
auto key = readString();
auto value = readPacket(protocolId);
auto *p = (T *) value.get();
map.insert(pair(key, *p));
}
return map;
}
//---------------------------------packet--------------------------------------
template
inline void writePacketArray(const vector &array, const int16_t &protocolId) {
if (array.empty()) {
writeByte(0);
return;
}
int32_t length = array.size();
writeInt(length);
for (auto value: array) {
writePacket((IProtocol *) &value, protocolId);
}
}
template
inline vector readPacketArray(const int16_t &protocolId) {
int32_t length = readInt();
vector array;
for (auto i = 0; i < length; i++) {
auto value = readPacket(protocolId);
auto *p = (T *) value.get();
array.emplace_back(*p);
}
return array;
}
template
inline void writePacketList(const list &list, const int16_t &protocolId) {
if (list.empty()) {
writeByte(0);
return;
}
int32_t length = list.size();
writeInt(length);
for (auto value: list) {
writePacket((IProtocol *) &value, protocolId);
}
}
template
inline list readPacketList(const int16_t &protocolId) {
int32_t length = readInt();
list list;
for (auto i = 0; i < length; i++) {
auto value = readPacket(protocolId);
auto *p = (T *) value.get();
list.emplace_back(*p);
}
return list;
}
template
inline void writePacketSet(const set &set, const int16_t &protocolId) {
if (set.empty()) {
writeByte(0);
return;
}
int32_t length = set.size();
writeInt(length);
for (auto value: set) {
writePacket((IProtocol *) &value, protocolId);
}
}
template
inline set readPacketSet(const int16_t &protocolId) {
int32_t length = readInt();
set set;
for (auto i = 0; i < length; i++) {
auto value = readPacket(protocolId);
auto *p = (T *) value.get();
set.emplace(*p);
}
return set;
}
private:
template
inline void write(T value) {
ensureCapacity(sizeof(T));
// MSDN: The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian).
// ** This mean the network byte order is big-endian **
if (IS_LITTLE_ENDIAN) {
swap_bytes(reinterpret_cast(&value));
}
memcpy(&buffer[writeOffset], (int8_t *) &value, sizeof(T));
writeOffset += sizeof(T);
}
template
inline T read() {
T value = *((T *) &buffer[readOffset]);
if (IS_LITTLE_ENDIAN) {
swap_bytes(reinterpret_cast(&value));
}
readOffset += sizeof(T);
return value;
}
// Swaps the order of bytes for some chunk of memory
template
inline void swap_bytes(int8_t *data) {
for (std::size_t i = 0, end = DataSize / 2; i < end; ++i) {
std::swap(data[i], data[DataSize - i - 1]);
}
}
};
}
#endif