about summary refs log tree commit diff
path: root/src/engine/e_packer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/e_packer.cpp')
-rw-r--r--src/engine/e_packer.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/engine/e_packer.cpp b/src/engine/e_packer.cpp
new file mode 100644
index 00000000..0d8aeab3
--- /dev/null
+++ b/src/engine/e_packer.cpp
@@ -0,0 +1,155 @@
+/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
+#include <stdlib.h> /* rand() */
+#include <base/system.h>
+
+#include "e_packer.h"
+#include "e_compression.h"
+#include "e_engine.h"
+#include "e_config.h"
+
+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;
+		
+	/* make sure that we have space enough */
+	if(m_pEnd - m_pCurrent < 6)
+	{
+		dbg_break();
+		m_Error = 1;
+	}
+	else
+		m_pCurrent = vint_pack(m_pCurrent, i);
+}
+
+void CPacker::AddString(const char *pStr, int Limit)
+{
+	if(m_Error)
+		return;
+	
+	/* */
+	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;
+	}
+}
+
+void CPacker::AddRaw(const unsigned char *pData, int Size)
+{
+	if(m_Error)
+		return;
+		
+	if(m_pCurrent+Size >= m_pEnd)
+	{
+		m_Error = 1;
+		return;
+	}
+	
+	while(Size)
+	{
+		*m_pCurrent++ = *pData++;
+		Size--;
+	}
+}
+
+
+void CUnpacker::Reset(const unsigned char *pData, int Size)
+{
+	m_Error = 0;
+	m_pStart = pData;
+	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;
+	m_pCurrent = vint_unpack(m_pCurrent, &i);
+	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;
+	while(*m_pCurrent) /* skip the string */
+	{
+		m_pCurrent++;
+		if(m_pCurrent == m_pEnd)
+		{
+			m_Error = 1;;
+			return "";
+		}
+	}
+	m_pCurrent++;
+	
+	/* sanitize all strings */
+	str_sanitize(pPtr);
+	return pPtr;
+}
+
+const unsigned char *CUnpacker::GetRaw(int Size)
+{
+	const unsigned char *pPtr = m_pCurrent;
+	if(m_Error)
+		return 0;
+	
+	/* check for nasty sizes */
+	if(Size < 0 || m_pCurrent+Size > m_pEnd)
+	{
+		m_Error = 1;
+		return 0;
+	}
+
+	/* "unpack" the data */	
+	m_pCurrent += Size;
+	return pPtr;
+}