ddnet/src/engine/shared/packer.cpp

175 lines
2.8 KiB
C++
Raw Normal View History

2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2009-10-27 14:38:53 +00:00
#include <base/system.h>
2010-05-29 07:25:38 +00:00
#include "compression.h"
#include "config.h"
#include "packer.h"
2009-10-27 14:38:53 +00:00
void CPacker::Reset()
{
m_Error = 0;
m_pCurrent = m_aBuffer;
m_pEnd = m_pCurrent + PACKER_BUFFER_SIZE;
}
void CPacker::AddInt(int i)
{
if(m_Error)
return;
2010-05-29 07:25:38 +00:00
// make sure that we have space enough
2009-10-27 14:38:53 +00:00
if(m_pEnd - m_pCurrent < 6)
{
dbg_break();
m_Error = 1;
}
else
2010-05-29 07:25:38 +00:00
m_pCurrent = CVariableInt::Pack(m_pCurrent, i);
2009-10-27 14:38:53 +00:00
}
void CPacker::AddString(const char *pStr, int Limit)
{
if(m_Error)
return;
2020-09-03 16:50:23 +00:00
if(Limit <= 0)
2009-10-27 14:38:53 +00:00
{
2020-09-03 16:50:23 +00:00
Limit = PACKER_BUFFER_SIZE;
2009-10-27 14:38:53 +00:00
}
2020-09-03 16:50:23 +00:00
while(*pStr && Limit != 0)
2009-10-27 14:38:53 +00:00
{
2020-09-03 16:50:23 +00:00
int Codepoint = str_utf8_decode(&pStr);
if(Codepoint == -1)
2009-10-27 14:38:53 +00:00
{
2020-09-03 16:50:23 +00:00
Codepoint = 0xfffd; // Unicode replacement character.
}
char aGarbage[4];
int Length = str_utf8_encode(aGarbage, Codepoint);
if(Limit < Length)
{
break;
}
// Ensure space for the null termination.
if(m_pEnd - m_pCurrent < Length + 1)
{
m_Error = 1;
break;
2009-10-27 14:38:53 +00:00
}
2020-09-03 16:50:23 +00:00
Length = str_utf8_encode((char *)m_pCurrent, Codepoint);
m_pCurrent += Length;
Limit -= Length;
2009-10-27 14:38:53 +00:00
}
2020-09-03 16:50:23 +00:00
*m_pCurrent++ = 0;
2009-10-27 14:38:53 +00:00
}
2010-05-29 07:25:38 +00:00
void CPacker::AddRaw(const void *pData, int Size)
2009-10-27 14:38:53 +00:00
{
if(m_Error)
return;
if(m_pCurrent + Size >= m_pEnd)
2009-10-27 14:38:53 +00:00
{
m_Error = 1;
return;
}
2010-05-29 07:25:38 +00:00
const unsigned char *pSrc = (const unsigned char *)pData;
2009-10-27 14:38:53 +00:00
while(Size)
{
2010-05-29 07:25:38 +00:00
*m_pCurrent++ = *pSrc++;
2009-10-27 14:38:53 +00:00
Size--;
}
}
2010-05-29 07:25:38 +00:00
void CUnpacker::Reset(const void *pData, int Size)
2009-10-27 14:38:53 +00:00
{
m_Error = 0;
2010-05-29 07:25:38 +00:00
m_pStart = (const unsigned char *)pData;
2009-10-27 14:38:53 +00:00
m_pEnd = m_pStart + Size;
m_pCurrent = m_pStart;
}
int CUnpacker::GetInt()
{
if(m_Error)
return 0;
2009-10-27 14:38:53 +00:00
if(m_pCurrent >= m_pEnd)
{
m_Error = 1;
return 0;
}
2009-10-27 14:38:53 +00:00
int i;
2010-05-29 07:25:38 +00:00
m_pCurrent = CVariableInt::Unpack(m_pCurrent, &i);
2009-10-27 14:38:53 +00:00
if(m_pCurrent > m_pEnd)
{
m_Error = 1;
return 0;
}
return i;
}
2020-04-16 08:46:43 +00:00
int CUnpacker::GetIntOrDefault(int Default)
{
if(m_Error)
{
return 0;
}
if(m_pCurrent == m_pEnd)
{
return Default;
}
return GetInt();
}
const char *CUnpacker::GetString(int SanitizeType)
2009-10-27 14:38:53 +00:00
{
if(m_Error)
2009-10-27 14:38:53 +00:00
return "";
if(m_pCurrent >= m_pEnd)
{
m_Error = 1;
return "";
}
2009-10-27 14:38:53 +00:00
char *pPtr = (char *)m_pCurrent;
2010-05-29 07:25:38 +00:00
while(*m_pCurrent) // skip the string
2009-10-27 14:38:53 +00:00
{
m_pCurrent++;
if(m_pCurrent == m_pEnd)
{
2016-05-03 22:24:54 +00:00
m_Error = 1;
2009-10-27 14:38:53 +00:00
return "";
}
}
m_pCurrent++;
2010-05-29 07:25:38 +00:00
// sanitize all strings
if(SanitizeType & SANITIZE)
str_sanitize(pPtr);
else if(SanitizeType & SANITIZE_CC)
str_sanitize_cc(pPtr);
return SanitizeType & SKIP_START_WHITESPACES ? str_utf8_skip_whitespaces(pPtr) : pPtr;
2009-10-27 14:38:53 +00:00
}
const unsigned char *CUnpacker::GetRaw(int Size)
{
const unsigned char *pPtr = m_pCurrent;
if(m_Error)
return 0;
2010-05-29 07:25:38 +00:00
// check for nasty sizes
if(Size < 0 || m_pCurrent + Size > m_pEnd)
2009-10-27 14:38:53 +00:00
{
m_Error = 1;
return 0;
}
2010-05-29 07:25:38 +00:00
// "unpack" the data
2009-10-27 14:38:53 +00:00
m_pCurrent += Size;
return pPtr;
}