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