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 <[EMAIL PROTECTED]>
To: Kent Johnson <[EMAIL PROTECTED]>

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/ 




_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to