Moved stream reading/writing protocol to common
Allow this to be used anywhere within the engine, especially for internal network handling.
This commit is contained in:
parent
b40af0c923
commit
f513e3de99
5 changed files with 478 additions and 399 deletions
|
|
@ -38,368 +38,6 @@
|
|||
#include "cmdlib.h"
|
||||
#include "serializer.h"
|
||||
|
||||
// Unchecked stream functions.
|
||||
// Use the checked versions instead unless you're checking the stream size yourself!
|
||||
|
||||
char* UncheckedReadString(uint8_t **stream)
|
||||
{
|
||||
char *string = *((char **)stream);
|
||||
|
||||
*stream += strlen(string) + 1;
|
||||
return copystring(string);
|
||||
}
|
||||
|
||||
const char* UncheckedReadStringConst(uint8_t **stream)
|
||||
{
|
||||
const char *string = *((const char **)stream);
|
||||
*stream += strlen(string) + 1;
|
||||
return string;
|
||||
}
|
||||
|
||||
uint8_t UncheckedReadInt8(uint8_t **stream)
|
||||
{
|
||||
uint8_t v = **stream;
|
||||
*stream += 1;
|
||||
return v;
|
||||
}
|
||||
|
||||
int16_t UncheckedReadInt16(uint8_t **stream)
|
||||
{
|
||||
int16_t v = (((*stream)[0]) << 8) | (((*stream)[1]));
|
||||
*stream += 2;
|
||||
return v;
|
||||
}
|
||||
|
||||
int32_t UncheckedReadInt32(uint8_t **stream)
|
||||
{
|
||||
int32_t v = (((*stream)[0]) << 24) | (((*stream)[1]) << 16) | (((*stream)[2]) << 8) | (((*stream)[3]));
|
||||
*stream += 4;
|
||||
return v;
|
||||
}
|
||||
|
||||
int64_t UncheckedReadInt64(uint8_t **stream)
|
||||
{
|
||||
int64_t v = (int64_t((*stream)[0]) << 56) | (int64_t((*stream)[1]) << 48) | (int64_t((*stream)[2]) << 40) | (int64_t((*stream)[3]) << 32)
|
||||
| (int64_t((*stream)[4]) << 24) | (int64_t((*stream)[5]) << 16) | (int64_t((*stream)[6]) << 8) | (int64_t((*stream)[7]));
|
||||
*stream += 8;
|
||||
return v;
|
||||
}
|
||||
|
||||
float UncheckedReadFloat(uint8_t **stream)
|
||||
{
|
||||
union
|
||||
{
|
||||
int32_t i;
|
||||
float f;
|
||||
} fakeint;
|
||||
fakeint.i = UncheckedReadInt32(stream);
|
||||
return fakeint.f;
|
||||
}
|
||||
|
||||
double UncheckedReadDouble(uint8_t **stream)
|
||||
{
|
||||
union
|
||||
{
|
||||
int64_t i;
|
||||
double f;
|
||||
} fakeint;
|
||||
fakeint.i = UncheckedReadInt64(stream);
|
||||
return fakeint.f;
|
||||
}
|
||||
|
||||
void UncheckedWriteString(const char *string, uint8_t **stream)
|
||||
{
|
||||
char *p = *((char **)stream);
|
||||
|
||||
while (*string) {
|
||||
*p++ = *string++;
|
||||
}
|
||||
|
||||
*p++ = 0;
|
||||
*stream = (uint8_t *)p;
|
||||
}
|
||||
|
||||
void UncheckedWriteInt8(uint8_t v, uint8_t **stream)
|
||||
{
|
||||
**stream = v;
|
||||
*stream += 1;
|
||||
}
|
||||
|
||||
void UncheckedWriteInt16(int16_t v, uint8_t **stream)
|
||||
{
|
||||
(*stream)[0] = v >> 8;
|
||||
(*stream)[1] = v & 255;
|
||||
*stream += 2;
|
||||
}
|
||||
|
||||
void UncheckedWriteInt32(int32_t v, uint8_t **stream)
|
||||
{
|
||||
(*stream)[0] = v >> 24;
|
||||
(*stream)[1] = (v >> 16) & 255;
|
||||
(*stream)[2] = (v >> 8) & 255;
|
||||
(*stream)[3] = v & 255;
|
||||
*stream += 4;
|
||||
}
|
||||
|
||||
void UncheckedWriteInt64(int64_t v, uint8_t **stream)
|
||||
{
|
||||
(*stream)[0] = v >> 56;
|
||||
(*stream)[1] = (v >> 48) & 255;
|
||||
(*stream)[2] = (v >> 40) & 255;
|
||||
(*stream)[3] = (v >> 32) & 255;
|
||||
(*stream)[4] = (v >> 24) & 255;
|
||||
(*stream)[5] = (v >> 16) & 255;
|
||||
(*stream)[6] = (v >> 8) & 255;
|
||||
(*stream)[7] = v & 255;
|
||||
*stream += 8;
|
||||
}
|
||||
|
||||
void UncheckedWriteFloat(float v, uint8_t **stream)
|
||||
{
|
||||
union
|
||||
{
|
||||
int32_t i;
|
||||
float f;
|
||||
} fakeint;
|
||||
fakeint.f = v;
|
||||
UncheckedWriteInt32(fakeint.i, stream);
|
||||
}
|
||||
|
||||
void UncheckedWriteDouble(double v, uint8_t **stream)
|
||||
{
|
||||
union
|
||||
{
|
||||
int64_t i;
|
||||
double f;
|
||||
} fakeint;
|
||||
fakeint.f = v;
|
||||
UncheckedWriteInt64(fakeint.i, stream);
|
||||
}
|
||||
|
||||
void AdvanceStream(TArrayView<uint8_t>& stream, size_t bytes)
|
||||
{
|
||||
assert(bytes <= stream.Size());
|
||||
stream = TArrayView(stream.Data() + bytes, stream.Size() - bytes);
|
||||
}
|
||||
|
||||
// Checked stream functions
|
||||
|
||||
char* ReadString(TArrayView<uint8_t>& stream)
|
||||
{
|
||||
char *string = (char*)stream.Data();
|
||||
size_t len = strnlen(string, stream.Size());
|
||||
if (len == stream.Size())
|
||||
{
|
||||
I_Error("Attempted to read past end of stream");
|
||||
}
|
||||
AdvanceStream(stream, len + 1);
|
||||
return copystring(string);
|
||||
}
|
||||
|
||||
const char* ReadStringConst(TArrayView<uint8_t>& stream)
|
||||
{
|
||||
const char* string = (const char*)stream.Data();
|
||||
size_t len = strnlen(string, stream.Size());
|
||||
if (len == stream.Size())
|
||||
{
|
||||
I_Error("Attempted to read past end of stream");
|
||||
}
|
||||
AdvanceStream(stream, len + 1);
|
||||
return string;
|
||||
}
|
||||
|
||||
void ReadBytes(TArrayView<uint8_t>& dst, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (dst.Size() > stream.Size())
|
||||
{
|
||||
I_Error("Attempted to read past end of stream");
|
||||
}
|
||||
if (dst.Size())
|
||||
{
|
||||
memcpy(dst.Data(), stream.Data(), dst.Size());
|
||||
AdvanceStream(stream, dst.Size());
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ReadInt8(TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (stream.Size() < 1)
|
||||
{
|
||||
I_Error("Attempted to read past end of stream");
|
||||
}
|
||||
uint8_t v = stream[0];
|
||||
AdvanceStream(stream, 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
int16_t ReadInt16(TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (stream.Size() < 2)
|
||||
{
|
||||
I_Error("Attempted to read past end of stream");
|
||||
}
|
||||
int16_t v = ((stream[0]) << 8) | stream[1];
|
||||
AdvanceStream(stream, 2);
|
||||
return v;
|
||||
}
|
||||
|
||||
int32_t ReadInt32(TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (stream.Size() < 4)
|
||||
{
|
||||
I_Error("Attempted to read past end of stream");
|
||||
}
|
||||
int32_t v = (stream[0] << 24) | (stream[1] << 16) | (stream[2] << 8) | stream[3];
|
||||
AdvanceStream(stream, 4);
|
||||
return v;
|
||||
}
|
||||
|
||||
int64_t ReadInt64(TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (stream.Size() < 8)
|
||||
{
|
||||
I_Error("Attempted to read past end of stream");
|
||||
}
|
||||
int64_t v = (int64_t(stream[0]) << 56) | (int64_t(stream[1]) << 48) | (int64_t(stream[2]) << 40) | (int64_t(stream[3]) << 32)
|
||||
| (int64_t(stream[4]) << 24) | (int64_t(stream[5]) << 16) | (int64_t(stream[6]) << 8) | int64_t(stream[7]);
|
||||
AdvanceStream(stream, 8);
|
||||
return v;
|
||||
}
|
||||
|
||||
float ReadFloat(TArrayView<uint8_t>& stream)
|
||||
{
|
||||
union
|
||||
{
|
||||
int32_t i;
|
||||
float f;
|
||||
} fakeint;
|
||||
fakeint.i = ReadInt32 (stream);
|
||||
return fakeint.f;
|
||||
}
|
||||
|
||||
double ReadDouble(TArrayView<uint8_t>& stream)
|
||||
{
|
||||
union
|
||||
{
|
||||
int64_t i;
|
||||
double f;
|
||||
} fakeint;
|
||||
fakeint.i = ReadInt64(stream);
|
||||
return fakeint.f;
|
||||
}
|
||||
|
||||
void WriteString(const char *string, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
char *p = (char *)stream.Data();
|
||||
unsigned int remaining = stream.Size();
|
||||
|
||||
while (*string) {
|
||||
if (remaining-- == 0)
|
||||
{
|
||||
I_Error("Attempted to write past end of stream");
|
||||
}
|
||||
*p++ = *string++;
|
||||
}
|
||||
|
||||
if (remaining == 0)
|
||||
{
|
||||
I_Error("Attempted to write past end of stream");
|
||||
}
|
||||
*p++ = 0;
|
||||
AdvanceStream(stream, p - (char*)stream.Data());
|
||||
}
|
||||
|
||||
void WriteBytes(const TArrayView<uint8_t>& source, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (source.Size() > stream.Size())
|
||||
{
|
||||
I_Error("Attempted to write past end of stream");
|
||||
}
|
||||
if (source.Size())
|
||||
{
|
||||
memcpy(stream.Data(), source.Data(), source.Size());
|
||||
AdvanceStream(stream, source.Size());
|
||||
}
|
||||
}
|
||||
|
||||
void WriteFString(FString& string, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
WriteBytes(string.GetTArrayView(), stream);
|
||||
}
|
||||
|
||||
void WriteInt8(uint8_t v, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (stream.Size() < 1)
|
||||
{
|
||||
I_Error("Attempted to write past end of stream");
|
||||
}
|
||||
stream[0] = v;
|
||||
AdvanceStream(stream, 1);
|
||||
}
|
||||
|
||||
void WriteInt16(int16_t v, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (stream.Size() < 2)
|
||||
{
|
||||
I_Error("Attempted to write past end of stream");
|
||||
}
|
||||
stream[0] = v >> 8;
|
||||
stream[1] = v & 255;
|
||||
AdvanceStream(stream, 2);
|
||||
}
|
||||
|
||||
void WriteInt32(int32_t v, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (stream.Size() < 4)
|
||||
{
|
||||
I_Error("Attempted to write past end of stream");
|
||||
}
|
||||
stream[0] = v >> 24;
|
||||
stream[1] = (v >> 16) & 255;
|
||||
stream[2] = (v >> 8) & 255;
|
||||
stream[3] = v & 255;
|
||||
AdvanceStream(stream, 4);
|
||||
}
|
||||
|
||||
void WriteInt64(int64_t v, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
if (stream.Size() < 8)
|
||||
{
|
||||
I_Error("Attempted to write past end of stream");
|
||||
}
|
||||
stream[0] = v >> 56;
|
||||
stream[1] = (v >> 48) & 255;
|
||||
stream[2] = (v >> 40) & 255;
|
||||
stream[3] = (v >> 32) & 255;
|
||||
stream[4] = (v >> 24) & 255;
|
||||
stream[5] = (v >> 16) & 255;
|
||||
stream[6] = (v >> 8) & 255;
|
||||
stream[7] = v & 255;
|
||||
AdvanceStream(stream, 8);
|
||||
}
|
||||
|
||||
void WriteFloat(float v, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
union
|
||||
{
|
||||
int32_t i;
|
||||
float f;
|
||||
} fakeint;
|
||||
fakeint.f = v;
|
||||
WriteInt32 (fakeint.i, stream);
|
||||
}
|
||||
|
||||
void WriteDouble(double v, TArrayView<uint8_t>& stream)
|
||||
{
|
||||
union
|
||||
{
|
||||
int64_t i;
|
||||
double f;
|
||||
} fakeint;
|
||||
fakeint.f = v;
|
||||
WriteInt64(fakeint.i, stream);
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* key, usercmd_t& cmd, usercmd_t* def)
|
||||
{
|
||||
// This used packed data with the old serializer but that's totally counterproductive when
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue