-
Notifications
You must be signed in to change notification settings - Fork 7
/
PacketWriter.hpp
144 lines (119 loc) · 3.57 KB
/
PacketWriter.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#pragma once
#include <Windows.h>
#include <string>
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setfill, std::setw
#include <stdint.h>
#include <sstream>
typedef uint16_t header_t;
class PacketWriter {
public:
PacketWriter() : m_pos(0), m_buffer(new unsigned char[bufferLen]), m_length(bufferLen) { }
PacketWriter(uint16_t h) : m_pos(0), m_buffer(new unsigned char[bufferLen]), m_length(bufferLen) { Write(h); }
void ReadString(std::string value);
template<typename T>
void Write(T value);
template<typename T>
void Fill(int times);
void WriteString(const std::string &str); // Dynamically-lengthed strings
void WriteString(const std::string &str, size_t len); // Static-lengthed strings
void WriteWideString(const std::wstring &str, size_t len);
void WriteNoLengthString(const std::string &str);
void WriteZeros(int zeros);
inline
const unsigned char * PacketWriter::GetBuffer() const {
return m_buffer;
}
int GetSize() const { return m_pos; }
std::string ToString() const;
private:
static const size_t bufferLen = 1000; // Initial buffer length
friend std::ostream & operator <<(std::ostream &out, const PacketWriter &packet); // Thanks, Bui!
unsigned char * GetBuffer(int pos, int len);
unsigned char * m_buffer;
int m_pos, m_length;
};
template <typename T>
void PacketWriter::Write(T value) {
(*(T *)GetBuffer(m_pos, +sizeof(T))) = value;
m_pos += sizeof(T);
}
inline
std::ostream & operator <<(std::ostream &out, const PacketWriter &packet) {
out << packet.ToString();
return out;
}
inline
std::string PacketWriter::ToString() const {
std::string ret;
if (GetSize() > 0) {
std::stringstream out;
const unsigned char *p = GetBuffer();
size_t buflen = GetSize() - 1;
for (size_t i = 0; i <= buflen; i++) {
out << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast<int16_t>(p[i]);
if (i < buflen) {
out << " ";
}
}
ret = out.str();
}
return ret;
}
inline
unsigned char * PacketWriter::GetBuffer(int pos, int len) {
if (m_length < pos + len) {
// Buffer is not large enough
while (m_length < pos + len) {
m_length *= 2; // Double the capacity each time the buffer is full
}
unsigned char *newBuffer = new unsigned char[m_length];
memcpy(newBuffer, m_buffer, pos);
m_buffer = newBuffer;
}
return m_buffer + pos;
}
inline
void PacketWriter::WriteString(const std::string &str, size_t len) {
size_t slen = str.size();
if (len < slen) {
throw std::invalid_argument("WriteString used with a length shorter than string size");
}
strncpy((char *)GetBuffer(m_pos, len), str.c_str(), slen);
for (size_t i = slen; i < len; i++) {
m_buffer[m_pos + i] = 0;
}
m_pos += len;
}
inline
void PacketWriter::WriteWideString(const std::wstring &str, size_t len) {
size_t slen = str.size();
if (len < slen) {
throw std::invalid_argument("WriteString used with a length shorter than string size");
}
wcscpy((wchar_t *)GetBuffer(m_pos, len*2), str.c_str());
m_pos += len*2;
}
inline
void PacketWriter::WriteNoLengthString(const std::string &str) {
WriteString(str, str.size());
}
inline
void PacketWriter::WriteString(const std::string &str) {
size_t len = str.size();
Write<uint16_t>(len);
WriteString(str, str.size());
}
inline
void PacketWriter::WriteZeros(int zeros) {
for (int i = 0; i < zeros; i++)
{
Write<byte>(0);
}
}
template <typename T>
void PacketWriter::Fill(int times) {
for (int i = 0; i < times; i++) {
Write<T>(times);
}
}