实现一个简单的C++ BinaryWriter类
在C++网络编程中通常需要自己拼包来发送数据,以下是一个简单的BinaryWriter类
BinaryReader 看这里!
完整代码
//BinaryWriter.h
//
// Created by xxx on 2023-12-24.
//
#ifndef BINARYWRITER_H
#define BINARYWRITER_H
#include <string>
#include <iostream>
#include <memory>
#include <cstring>
#include <iostream>
#include <vector>
#include <cstdint>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
class BinaryWriter
{
public:
BinaryWriter() : _flipBytes(false) {}
// 重载 = 运算符
BinaryWriter &operator=(const std::string &buffer)
{
_buffer.clear();
_buffer.assign(buffer.begin(), buffer.end()); // 从string中拷贝数据到vector
return *this;
}
// 设置字节顺序
void setByteOrder(bool flipBytes)
{
_flipBytes = flipBytes;
}
// 在最前面插入数据
void insertData(const void *data, std::streamsize size)
{
if (_flipBytes)
{
// 如果需要翻转字节顺序,则进行翻转
const char *ptr = static_cast<const char *>(data);
for (std::streamsize i = size - 1; i >= 0; --i)
{
_buffer.insert(_buffer.begin(), ptr[i]);
}
}
else
{
// 否则直接写入数据
_buffer.insert(_buffer.begin(), static_cast<const char *>(data), static_cast<const char *>(data) + size);
}
}
// 在最前面插入数据
template <typename T>
void insertData(const T &value)
{
insertData(&value, sizeof(T));
}
// 在最前面插入字符串
void insertData(const std::string &value)
{
insertData(value.c_str(), (long)value.size());
insertData(static_cast<uint8_t>(0)); // 写入字符串结束符
}
// 写入数据到输出流
void writeData(const void *data, std::streamsize size)
{
if (_flipBytes)
{
// 如果需要翻转字节顺序,则进行翻转
const char *ptr = static_cast<const char *>(data);
for (std::streamsize i = size - 1; i >= 0; --i)
{
_buffer.push_back(ptr[i]);
}
}
else
{
// 否则直接写入数据
_buffer.insert(_buffer.end(), static_cast<const char *>(data), static_cast<const char *>(data) + size);
}
}
// 写入数据到输出流
template <typename T>
void writeData(const T &value)
{
writeData(&value, sizeof(T));
}
// 写入字符串到输出流
void writeData(const std::string &value)
{
writeData(value.c_str(), (long)value.size());
writeData(static_cast<uint8_t>(0)); // 写入字符串结束符
}
// 获取打包后的数据
[[nodiscard]] const std::vector<uint8_t> &getBuffer() const
{
return _buffer;
}
// 获取打包后的数据 string
[[nodiscard]] std::string getBufferString() const
{
return { _buffer.begin(), _buffer.end() };
}
// 清空缓冲区
void clear()
{
_buffer.clear();
}
// 获取缓冲区大小
[[nodiscard]] std::size_t getSize() const
{
return _buffer.size();
}
private:
std::vector<uint8_t> _buffer;
bool _flipBytes;
};
#endif //BINARYWRITER_H
1. 重载运算符"=" : operator
BinaryWriter &operator=(const std::string &buffer)
{
_buffer.clear();
_buffer.assign(buffer.begin(), buffer.end()); // 从string中拷贝数据到vector
return *this;
}
重载了赋值运算符,允许将字符串直接赋值给BinaryWriter对象。
2. setByteOrder
void setByteOrder(bool flipBytes)
{
_flipBytes = flipBytes;
}
设置字节顺序,与BinaryReader类的方法对应。可以在写入过程中动态切换字节顺序。
3. insertData
void insertData(const void *data, std::streamsize size)
{
if (_flipBytes)
{
// 如果需要翻转字节顺序,则进行翻转
const char *ptr = static_cast<const char *>(data);
for (std::streamsize i = size - 1; i >= 0; --i)
{
_buffer.insert(_buffer.begin(), ptr[i]);
}
}
else
{
// 否则直接写入数据
_buffer.insert(_buffer.begin(), static_cast<const char *>(data), static_cast<const char *>(data) + size);
}
}
在字节流的最前面插入数据,支持传入指针和大小。
4. insertData
template <typename T>
void insertData(const T &value)
{
insertData(&value, sizeof(T));
}
在字节流的最前面插入数据,支持传入不同类型的值。
5 insertData
// 在最前面插入字符串
void insertData(const std::string &value)
{
insertData(value.c_str(), (long)value.size());
insertData(static_cast<uint8_t>(0)); // 写入字符串结束符
}
在字节流的最前面插入数据,支持传入string。
6. writeData
// 写入数据到输出流
void writeData(const void *data, std::streamsize size)
{
if (_flipBytes)
{
// 如果需要翻转字节顺序,则进行翻转
const char *ptr = static_cast<const char *>(data);
for (std::streamsize i = size - 1; i >= 0; --i)
{
_buffer.push_back(ptr[i]);
}
}
else
{
// 否则直接写入数据
_buffer.insert(_buffer.end(), static_cast<const char *>(data), static_cast<const char *>(data) + size);
}
}
将数据追加到字节流的末尾,支持传入指针和大小。
7. writeData
// 写入数据到输出流
template <typename T>
void writeData(const T &value)
{
writeData(&value, sizeof(T));
}
将数据追加到字节流的末尾,支持传入不同类型的值。
8. writeData
// 写入字符串到输出流
void writeData(const std::string &value)
{
writeData(value.c_str(), (long)value.size());
writeData(static_cast<uint8_t>(0)); // 写入字符串结束符
}
将数据追加到字节流的末尾,支持传入string。
9. getBuffer
[[nodiscard]] const std::vector<uint8_t> &getBuffer() const
{
return _buffer;
}
获取当前字节流的内容。
10. getBufferString
[[nodiscard]] std::string getBufferString() const
{
return { _buffer.begin(), _buffer.end() };
}
获取当前字节流的内容,并以字符串形式返回。
11. clear
void clear()
{
_buffer.clear();
}
清空缓冲区,使其变为空字节流。
12. getSize
[[nodiscard]] std::size_t getSize() const
{
return _buffer.size();
}
获取当前字节流的大小。
示例程序
#include "BinaryWriter.h"
int main() {
BinaryWriter writer;
int intValue = 42;
writer.writeData(intValue);
std::string stringValue = "Hello, BinaryWriter!";
writer.writeData(stringValue);
std::vector<uint8_t> buffer = writer.getBuffer();
for (uint8_t byte : buffer) {
std::cout << std::hex << static_cast<int>(byte) << " ";
}
std::string bufferString = writer.getBufferString();
std::cout << bufferString;
return 0;
}
如发现错误,请指正,谢谢!