[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