[Tutor] [Fwd: Re: Consistant Overhead Byte Stuffing (COBS) algorithm help]

Kent Johnson kent37 at tds.net
Wed Oct 5 14:59:05 CEST 2005


Forwarding to the list

-------- Original Message --------
Subject: Re: [Tutor] Consistant Overhead Byte Stuffing (COBS) algorithm help
Date: Tue, 4 Oct 2005 13:20:18 -0700 (PDT)
From: Michael Cotherman <mjcother at yahoo.com>
To: Kent Johnson <kent37 at tds.net>

Thanks for the response, the .NET code is really a
cluster, the whole cobs.cpp is below if needed. I
would think just by following the spec I could write a
cleaner program..



I am a noob to converting pointers in C++ to arrays in
python, although the first time I see it done, I will
have no problem. Can you help converting the below
(what I think is the 'decoder' section) to python?


even just comments to what is going on at each line...


-mike



UINT CCobsPackets::UnStuffData(unsigned char *src,
unsigned char *dst, UINT length)
{
	unsigned char *dstStart = dst;
	unsigned char *end = src + length;

	while (src < end)
	{
		int i, code = *src++;

		for (i=1; i<code; i++) 
		{
			*dst++ = *src++;
		}
		
		if (code < 0xFF) 
		{
			*dst++ = 0;
		}
	}

	return (UINT)(dst - dstStart);
}












/////////////////////////////////////////////////////////////////////////////
// includes
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CobsPackets.h"




/////////////////////////////////////////////////////////////////////////////
// defines
/////////////////////////////////////////////////////////////////////////////



/////////////////////////////////////////////////////////////////////////////
// global data
/////////////////////////////////////////////////////////////////////////////


// Register the standard CCobsPackets COM message
const UINT CCobsPackets::mg_nDefaultCobsMsg =
::RegisterWindowMessage(_T("CCobsPackets_DefaultCobsMsg"));

	
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// class CCobsPackets
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

CCobsPackets::CCobsPackets()
{
	m_hMsgWnd = 0;
	m_nCobsMsg = 0;
	m_lParam   = 0;
	m_nMaxPacketSize = 0;

	m_pInPacketData = NULL;
	m_nInPacketPos = 0;
}

CCobsPackets::~CCobsPackets()
{
	if (m_pInPacketData){
		delete []m_pInPacketData;
		m_pInPacketData = NULL;
	}


	while (!m_InPacketList.IsEmpty())
	{
		ListPacket *delPacket = (ListPacket
*)m_InPacketList.RemoveTail();

		if (delPacket)
		{
			if (delPacket->packetData){
				delete [](delPacket->packetData);
				delPacket->packetData = NULL;
			}

			delete delPacket;
		}
	}

	while (!m_OutPacketList.IsEmpty())
	{
		ListPacket *delPacket = (ListPacket
*)m_OutPacketList.RemoveTail();

		if (delPacket)
		{
			if (delPacket->packetData){
				delete [](delPacket->packetData);
				delPacket->packetData = NULL;
			}


			delete delPacket;
		}
	}
}

bool CCobsPackets::Init(HWND hwndDest, UINT nCobsMsg,
LPARAM lParam, UINT nMaxPacketSize)
{
	m_hMsgWnd = hwndDest;
	m_nCobsMsg = nCobsMsg?nCobsMsg:mg_nDefaultCobsMsg;
	m_lParam   = lParam;
	m_nMaxPacketSize = nMaxPacketSize;

	m_nInPacketPos = 0;

	if (m_pInPacketData){
		delete []m_pInPacketData;
		m_pInPacketData = NULL;
	}

	m_pInPacketData = new unsigned
char[m_nMaxPacketSize];
	//TRACE0("create m_pInPacketData\n");

	if (!m_pInPacketData)
		return false;

	return true;
}

ListPacket* CCobsPackets::NewPacket()
{
	ListPacket *newPacket = NULL;

	if (m_nMaxPacketSize)
	{
		newPacket = new ListPacket;
		if (newPacket)
		{
			newPacket->packetData = new unsigned
char[m_nMaxPacketSize];

			if (newPacket->packetData)
			{
				newPacket->packetLength = 0;
				memset(newPacket->packetData, 0x00,
m_nMaxPacketSize);

			}
			else
			{
				delete newPacket;
				newPacket = NULL;
			}
		}
	}

	return newPacket;
}

void CCobsPackets::SendEvent (EEvent eEvent, EError
eError)
{
	// Post message to the client window

::PostMessage(m_hMsgWnd,m_nCobsMsg,MAKEWPARAM(eEvent,eError),LPARAM(m_lParam));
}

void CCobsPackets::DataReceived(unsigned char *src,
UINT length)
{
	while (m_pInPacketData && length)
	{
		if (m_nInPacketPos < m_nMaxPacketSize)
		{
			if (*src == 0x00)
			{
				if (m_nInPacketPos)
				{
					ListPacket *decodePacket = NewPacket();

					if (decodePacket)
					{
						decodePacket->packetLength =
UnStuffData(m_pInPacketData, decodePacket->packetData,
m_nInPacketPos);
						m_InPacketList.AddTail(decodePacket);
						decodePacket->packetCommand =
*(decodePacket->packetData);
						SendEvent(EEventReceivedPacket);
					}
					else
					{
						// Unable to decode Packet Error
						SendEvent(EEventPacketError,
EErrorPacketDecode);
					}
				}
				else
				{
					// throw away zero-byte packets
				}
				memset(m_pInPacketData, 0x00, m_nMaxPacketSize);
				m_nInPacketPos = 0;
			}
			else
			{
				m_pInPacketData[m_nInPacketPos++] = *src;
			}

			src++;
		}
		else
		{
			// Packet Overrun Error
			SendEvent(EEventPacketError, EErrorPacketOverrun);

			memset(m_pInPacketData, 0x00, m_nMaxPacketSize);
			m_nInPacketPos = 0;

			return;
		}

		length--;
	}
}

void CCobsPackets::SendPacket(unsigned char *src, UINT
length)
{
	ListPacket *encodePacket = NewPacket();

	if (encodePacket)
	{
		encodePacket->packetCommand = *src;
		encodePacket->packetLength = StuffData(src,
encodePacket->packetData, length);
		m_OutPacketList.AddTail(encodePacket);
		SendEvent(EEventSendPacket);
	}
	else
	{
		// Unable to decode Packet Error
		SendEvent(EEventPacketError, EErrorPacketDecode);
	}
}

BYTE CCobsPackets::GetPacket(EEvent eEvent, unsigned
char *data, UINT *length)
{
	ListPacket *pPacket = NULL;
	BYTE packetCommand = 0;


	switch (eEvent)
	{
	case EEventReceivedPacket:
		if (!m_InPacketList.IsEmpty())
			pPacket = (ListPacket *)
m_InPacketList.RemoveHead();
		break;
	case EEventSendPacket:
		if (!m_OutPacketList.IsEmpty())
			pPacket = (ListPacket *)
m_OutPacketList.RemoveHead();
		break;
	}

	if (pPacket)
	{
		packetCommand = pPacket->packetCommand;

		if (pPacket->packetData)
		{
			if (data && *length && pPacket->packetLength)
			{
				*length = (*length < pPacket->packetLength) ?
*length : pPacket->packetLength;
				memcpy(data, pPacket->packetData, *length);
			}
			else
			{
				*length = 0;
			}

			delete [](pPacket->packetData);
			pPacket->packetData = NULL;

		}
		else
		{
			*length = 0;
		}

		delete pPacket;
	}

	return packetCommand;
}


#define FinishBlock(_x_) (*code_ptr = (_x_),   \
	                     code_ptr = dst++, \
						 code = 0x01       )
UINT CCobsPackets::StuffData(unsigned char *src,
unsigned char *dst, UINT length)
{
	unsigned char *dstStart = dst;
	unsigned char *end = src + length;
	unsigned char *code_ptr = dst++;
	unsigned char code = 0x01;

	while (src < end)
	{
		if (*src == 0) FinishBlock(code);
		else
		{
			*dst++ = *src;
			code++;
			if (code == 0xFF) FinishBlock(code);
		}
		src++;
	}
	FinishBlock(code);

	return (UINT)(dst - dstStart);
}

UINT CCobsPackets::UnStuffData(unsigned char *src,
unsigned char *dst, UINT length)
{
	unsigned char *dstStart = dst;
	unsigned char *end = src + length;

	while (src < end)
	{
		int i, code = *src++;

		for (i=1; i<code; i++) 
		{
			*dst++ = *src++;
		}
		
		if (code < 0xFF) 
		{
			*dst++ = 0;
		}
	}

	return (UINT)(dst - dstStart);
}



	
		
______________________________________________________ 
Yahoo! for Good 
Donate to the Hurricane Katrina relief effort. 
http://store.yahoo.com/redcross-donate3/ 






More information about the Tutor mailing list