2010-05-29 07:25:38 +00:00
|
|
|
// copyright (c) 2007 magnus auvinen, see licence.txt for more info
|
2009-10-27 14:38:53 +00:00
|
|
|
#include <base/system.h>
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "packer.h"
|
|
|
|
#include "compression.h"
|
|
|
|
#include "engine.h"
|
|
|
|
#include "config.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;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
//
|
2009-10-27 14:38:53 +00:00
|
|
|
if(Limit > 0)
|
|
|
|
{
|
|
|
|
while(*pStr && Limit != 0)
|
|
|
|
{
|
|
|
|
*m_pCurrent++ = *pStr++;
|
|
|
|
Limit--;
|
|
|
|
|
|
|
|
if(m_pCurrent >= m_pEnd)
|
|
|
|
{
|
|
|
|
m_Error = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*m_pCurrent++ = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while(*pStr)
|
|
|
|
{
|
|
|
|
*m_pCurrent++ = *pStr++;
|
|
|
|
|
|
|
|
if(m_pCurrent >= m_pEnd)
|
|
|
|
{
|
|
|
|
m_Error = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*m_pCurrent++ = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
if(m_pCurrent >= m_pEnd)
|
|
|
|
{
|
|
|
|
m_Error = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *CUnpacker::GetString()
|
|
|
|
{
|
|
|
|
if(m_Error || m_pCurrent >= m_pEnd)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
m_Error = 1;;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_pCurrent++;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// sanitize all strings
|
2009-10-27 14:38:53 +00:00
|
|
|
str_sanitize(pPtr);
|
|
|
|
return pPtr;
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2009-10-27 14:38:53 +00:00
|
|
|
if(Size < 0 || m_pCurrent+Size > m_pEnd)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|