mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-10-12 18:38:10 +00:00
General AMF cleanup (#663)
* General AMF cleanup Proper memory management as well as style cleanup * General optimizations Fix AMFArray so values are properly deleted when you leave the scope it was created in. Add bounds check for deletion so you don't double delete. Remove all AMFdeletions that are contained in an array since the array now manages its own memory and deletes it when it is no longer needed. * Better tests and fix de-serialize Fix de-serialize to be correct and implement a test to check this * Update AMFDeserializeTests.cpp * Update AMFFormat.cpp
This commit is contained in:
@@ -3,269 +3,248 @@
|
||||
// Writes an AMFValue pointer to a RakNet::BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFValue*>(AMFValue* value) {
|
||||
if (value != nullptr) {
|
||||
AMFValueType type = value->GetValueType();
|
||||
|
||||
switch (type) {
|
||||
case AMFUndefined: {
|
||||
AMFUndefinedValue* v = (AMFUndefinedValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFNull: {
|
||||
AMFNullValue* v = (AMFNullValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFFalse: {
|
||||
AMFFalseValue* v = (AMFFalseValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFTrue: {
|
||||
AMFTrueValue* v = (AMFTrueValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFInteger: {
|
||||
AMFIntegerValue* v = (AMFIntegerValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFString: {
|
||||
AMFStringValue* v = (AMFStringValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFXMLDoc: {
|
||||
AMFXMLDocValue* v = (AMFXMLDocValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFDate: {
|
||||
AMFDateValue* v = (AMFDateValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFArray: {
|
||||
AMFArrayValue* v = (AMFArrayValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value != nullptr) {
|
||||
AMFValueType type = value->GetValueType();
|
||||
|
||||
switch (type) {
|
||||
case AMFUndefined: {
|
||||
AMFUndefinedValue* v = (AMFUndefinedValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFNull: {
|
||||
AMFNullValue* v = (AMFNullValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFFalse: {
|
||||
AMFFalseValue* v = (AMFFalseValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFTrue: {
|
||||
AMFTrueValue* v = (AMFTrueValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFInteger: {
|
||||
AMFIntegerValue* v = (AMFIntegerValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFDouble: {
|
||||
AMFDoubleValue* v = (AMFDoubleValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFString: {
|
||||
AMFStringValue* v = (AMFStringValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFXMLDoc: {
|
||||
AMFXMLDocValue* v = (AMFXMLDocValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFDate: {
|
||||
AMFDateValue* v = (AMFDateValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFArray: {
|
||||
this->Write((AMFArrayValue*)value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A private function to write an value to a RakNet::BitStream
|
||||
/**
|
||||
* A private function to write an value to a RakNet::BitStream
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteUInt29(RakNet::BitStream* bs, uint32_t v) {
|
||||
unsigned char b4 = (unsigned char)v;
|
||||
if (v < 0x00200000) {
|
||||
b4 = b4 & 0x7F;
|
||||
if (v > 0x7F) {
|
||||
unsigned char b3;
|
||||
v = v >> 7;
|
||||
b3 = ((unsigned char)(v)) | 0x80;
|
||||
if (v > 0x7F) {
|
||||
unsigned char b2;
|
||||
v = v >> 7;
|
||||
b2 = ((unsigned char)(v)) | 0x80;
|
||||
bs->Write(b2);
|
||||
}
|
||||
|
||||
bs->Write(b3);
|
||||
}
|
||||
} else {
|
||||
unsigned char b1;
|
||||
unsigned char b2;
|
||||
unsigned char b3;
|
||||
|
||||
v = v >> 8;
|
||||
b3 = ((unsigned char)(v)) | 0x80;
|
||||
v = v >> 7;
|
||||
b2 = ((unsigned char)(v)) | 0x80;
|
||||
v = v >> 7;
|
||||
b1 = ((unsigned char)(v)) | 0x80;
|
||||
|
||||
bs->Write(b1);
|
||||
bs->Write(b2);
|
||||
bs->Write(b3);
|
||||
}
|
||||
|
||||
bs->Write(b4);
|
||||
unsigned char b4 = (unsigned char)v;
|
||||
if (v < 0x00200000) {
|
||||
b4 = b4 & 0x7F;
|
||||
if (v > 0x7F) {
|
||||
unsigned char b3;
|
||||
v = v >> 7;
|
||||
b3 = ((unsigned char)(v)) | 0x80;
|
||||
if (v > 0x7F) {
|
||||
unsigned char b2;
|
||||
v = v >> 7;
|
||||
b2 = ((unsigned char)(v)) | 0x80;
|
||||
bs->Write(b2);
|
||||
}
|
||||
|
||||
bs->Write(b3);
|
||||
}
|
||||
} else {
|
||||
unsigned char b1;
|
||||
unsigned char b2;
|
||||
unsigned char b3;
|
||||
|
||||
v = v >> 8;
|
||||
b3 = ((unsigned char)(v)) | 0x80;
|
||||
v = v >> 7;
|
||||
b2 = ((unsigned char)(v)) | 0x80;
|
||||
v = v >> 7;
|
||||
b1 = ((unsigned char)(v)) | 0x80;
|
||||
|
||||
bs->Write(b1);
|
||||
bs->Write(b2);
|
||||
bs->Write(b3);
|
||||
}
|
||||
|
||||
bs->Write(b4);
|
||||
}
|
||||
|
||||
// Writes a flag number to a RakNet::BitStream
|
||||
/**
|
||||
* Writes a flag number to a RakNet::BitStream
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) {
|
||||
v = (v << 1) | 0x01;
|
||||
WriteUInt29(bs, v);
|
||||
v = (v << 1) | 0x01;
|
||||
WriteUInt29(bs, v);
|
||||
}
|
||||
|
||||
// Writes an AMFString to a RakNet::BitStream
|
||||
/**
|
||||
* Writes an AMFString to a RakNet::BitStream
|
||||
*
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteAMFString(RakNet::BitStream* bs, const std::string& str) {
|
||||
WriteFlagNumber(bs, (uint32_t)str.size());
|
||||
bs->Write(str.c_str(), (uint32_t)str.size());
|
||||
WriteFlagNumber(bs, (uint32_t)str.size());
|
||||
bs->Write(str.c_str(), (uint32_t)str.size());
|
||||
}
|
||||
|
||||
// Writes an AMF U16 to a RakNet::BitStream
|
||||
/**
|
||||
* Writes an U16 to a bitstream
|
||||
*
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) {
|
||||
unsigned char b2;
|
||||
b2 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
bs->Write((unsigned char)value);
|
||||
bs->Write(b2);
|
||||
bs->Write(value);
|
||||
}
|
||||
|
||||
// Writes an AMF U32 to RakNet::BitStream
|
||||
/**
|
||||
* Writes an U32 to a bitstream
|
||||
*
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) {
|
||||
unsigned char b2;
|
||||
unsigned char b3;
|
||||
unsigned char b4;
|
||||
|
||||
b4 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b3 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b2 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
|
||||
bs->Write((unsigned char)value);
|
||||
bs->Write(b2);
|
||||
bs->Write(b3);
|
||||
bs->Write(b4);
|
||||
bs->Write(value);
|
||||
}
|
||||
|
||||
// Writes an AMF U64 to RakNet::BitStream
|
||||
/**
|
||||
* Writes an U64 to a bitstream
|
||||
*
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) {
|
||||
unsigned char b2;
|
||||
unsigned char b3;
|
||||
unsigned char b4;
|
||||
unsigned char b5;
|
||||
unsigned char b6;
|
||||
unsigned char b7;
|
||||
unsigned char b8;
|
||||
|
||||
b8 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b7 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b6 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b5 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b4 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b3 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b2 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
|
||||
bs->Write((unsigned char)value);
|
||||
bs->Write(b2);
|
||||
bs->Write(b3);
|
||||
bs->Write(b4);
|
||||
bs->Write(b5);
|
||||
bs->Write(b6);
|
||||
bs->Write(b7);
|
||||
bs->Write(b8);
|
||||
bs->Write(value);
|
||||
}
|
||||
|
||||
|
||||
// Writes an AMFUndefinedValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFUndefinedValue>(AMFUndefinedValue value) {
|
||||
this->Write(AMFUndefined);
|
||||
this->Write(AMFUndefined);
|
||||
}
|
||||
|
||||
// Writes an AMFNullValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFNullValue>(AMFNullValue value) {
|
||||
this->Write(AMFNull);
|
||||
this->Write(AMFNull);
|
||||
}
|
||||
|
||||
// Writes an AMFFalseValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFFalseValue>(AMFFalseValue value) {
|
||||
this->Write(AMFFalse);
|
||||
this->Write(AMFFalse);
|
||||
}
|
||||
|
||||
// Writes an AMFTrueValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFTrueValue>(AMFTrueValue value) {
|
||||
this->Write(AMFTrue);
|
||||
this->Write(AMFTrue);
|
||||
}
|
||||
|
||||
// Writes an AMFIntegerValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFIntegerValue>(AMFIntegerValue value) {
|
||||
this->Write(AMFInteger);
|
||||
WriteUInt29(this, value.GetIntegerValue());
|
||||
this->Write(AMFInteger);
|
||||
WriteUInt29(this, value.GetIntegerValue());
|
||||
}
|
||||
|
||||
// Writes an AMFDoubleValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFDoubleValue>(AMFDoubleValue value) {
|
||||
this->Write(AMFDouble);
|
||||
double d = value.GetDoubleValue();
|
||||
WriteAMFU64(this, *((unsigned long long*)&d));
|
||||
this->Write(AMFDouble);
|
||||
double d = value.GetDoubleValue();
|
||||
WriteAMFU64(this, *((unsigned long long*)&d));
|
||||
}
|
||||
|
||||
// Writes an AMFStringValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFStringValue>(AMFStringValue value) {
|
||||
this->Write(AMFString);
|
||||
std::string v = value.GetStringValue();
|
||||
WriteAMFString(this, v);
|
||||
this->Write(AMFString);
|
||||
std::string v = value.GetStringValue();
|
||||
WriteAMFString(this, v);
|
||||
}
|
||||
|
||||
// Writes an AMFXMLDocValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFXMLDocValue>(AMFXMLDocValue value) {
|
||||
this->Write(AMFXMLDoc);
|
||||
std::string v = value.GetXMLDocValue();
|
||||
WriteAMFString(this, v);
|
||||
this->Write(AMFXMLDoc);
|
||||
std::string v = value.GetXMLDocValue();
|
||||
WriteAMFString(this, v);
|
||||
}
|
||||
|
||||
// Writes an AMFDateValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFDateValue>(AMFDateValue value) {
|
||||
this->Write(AMFDate);
|
||||
uint64_t date = value.GetDateValue();
|
||||
WriteAMFU64(this, date);
|
||||
this->Write(AMFDate);
|
||||
uint64_t date = value.GetDateValue();
|
||||
WriteAMFU64(this, date);
|
||||
}
|
||||
|
||||
// Writes an AMFArrayValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFArrayValue>(AMFArrayValue value) {
|
||||
this->Write(AMFArray);
|
||||
uint32_t denseSize = value.GetDenseValueSize();
|
||||
WriteFlagNumber(this, denseSize);
|
||||
|
||||
_AMFArrayMap_::iterator it = value.GetAssociativeIteratorValueBegin();
|
||||
_AMFArrayMap_::iterator end = value.GetAssociativeIteratorValueEnd();
|
||||
|
||||
while (it != end) {
|
||||
WriteAMFString(this, it->first);
|
||||
this->Write(it->second);
|
||||
it++;
|
||||
}
|
||||
|
||||
this->Write(AMFNull);
|
||||
|
||||
if (denseSize > 0) {
|
||||
_AMFArrayList_::iterator it2 = value.GetDenseIteratorBegin();
|
||||
_AMFArrayList_::iterator end2 = value.GetDenseIteratorEnd();
|
||||
|
||||
while (it2 != end2) {
|
||||
this->Write(*it2);
|
||||
it2++;
|
||||
}
|
||||
}
|
||||
void RakNet::BitStream::Write<AMFArrayValue*>(AMFArrayValue* value) {
|
||||
this->Write(AMFArray);
|
||||
uint32_t denseSize = value->GetDenseValueSize();
|
||||
WriteFlagNumber(this, denseSize);
|
||||
|
||||
_AMFArrayMap_::iterator it = value->GetAssociativeIteratorValueBegin();
|
||||
_AMFArrayMap_::iterator end = value->GetAssociativeIteratorValueEnd();
|
||||
|
||||
while (it != end) {
|
||||
WriteAMFString(this, it->first);
|
||||
this->Write(it->second);
|
||||
it++;
|
||||
}
|
||||
|
||||
this->Write(AMFNull);
|
||||
|
||||
if (denseSize > 0) {
|
||||
_AMFArrayList_::iterator it2 = value->GetDenseIteratorBegin();
|
||||
_AMFArrayList_::iterator end2 = value->GetDenseIteratorEnd();
|
||||
|
||||
while (it2 != end2) {
|
||||
this->Write(*it2);
|
||||
it2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user