diff -r 000000000000 -r 83f4b4db085c toolsandutils/wintunnel/src_beech/d_cbuf.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolsandutils/wintunnel/src_beech/d_cbuf.cpp Tue Feb 02 01:39:43 2010 +0200 @@ -0,0 +1,425 @@ +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + + +#include "d_comm.h" + +CCommTxBuf::CCommTxBuf() + : CCirBuffer() + {} + + +TInt CCommTxBuf::ClientRead(DComm* aDriver, DThread* aThread, const TAny* aPtr, TInt& aTxLength, TInt& aTxOffset, TInt aMode) +// +// Copy from client to buffer. +// + { + TInt offset = aTxOffset; + TInt length = aTxLength; + if (length==0) + return KErrNone; + + TPtr8 des(NULL,0); + + aDriver->DisableInterrupts(); + TInt count = iCount; + TInt space = iLength-count; + if (space==0) + { + aDriver->EnableInterrupts(); + return KErrOverflow; + } + TInt maxcopy = Min(space,length); + aDriver->EnableInterrupts(); + + TInt copylen = Min(maxcopy, iPtrE-iHead); + des.Set(iHead, copylen, copylen); + aThread->Read(aPtr, &des, offset, aMode); + length -= copylen; + offset += copylen; + + copylen = maxcopy-copylen; + if (copylen>0) + { + des.Set(iPtr, copylen, copylen); + aThread->Read(aPtr, &des, offset, aMode); + length -= copylen; + offset += copylen; + } + + iHead += maxcopy; + if (iHead>=iPtrE) + iHead -= iLength; + + aDriver->DisableInterrupts(); + iCount += maxcopy; + aDriver->EnableInterrupts(); + + aTxLength = length; + aTxOffset = offset; + return KErrNone; + } + + +CCommRxBuf::CCommRxBuf() +// +// +// + { + __DECLARE_NAME(_S("CCommRxBuf")); + } + +CCommRxBuf::~CCommRxBuf() +// +// +// + { + User::Free(iCharPtr); + } + +void CCommRxBuf::SetLengthL(TInt aLength) +// +// ReAlloc - Resets all the buffer pointers +// + { + __ASSERT_ALWAYS(aLength>0,User::Panic(_L("DCOMBUF"),0/*ECircSetLengthNegative*/)); + aLength = Align4(aLength); + iCharPtr=(TUint8 *)User::ReAllocL(iCharPtr, aLength<<1); + iLength = aLength; + iInfoPtr = iCharPtr+aLength; + Reset(); + } + +void CCommRxBuf::Reset() +// +// Reset the buffer pointers +// + { + iCount = 0; + iInsP = 0; + iRemP = 0; + iInsSeqNum = 0; + iRemSeqNum = iInsSeqNum; + iLastSeqNum = iInsSeqNum; + } + + +TInt CCommRxBuf::ClientWrite(TUint& aStatus, DComm* aDriver, DThread* aThread, const TAny* aPtr, TInt& aRxLength, TInt& aRxOffset, TInt aMode) +// +// Copy to client's buffer +// if aCount==0 then do as much as possible, and only return completed +// if the clients buffer is full. Normally, aCount would be the count +// returned by GetInfo(). +// + { + if (iCount==0) + return KErrUnderflow; + + TInt blocksz; + TUint state = iInfoPtr[iRemP]; + + TInt p; + if ((state & 0x0f)==0x0f) + { + p = (iRemP+0x4)&~0x3; + if (p>=iLength) + p = 0; + blocksz = *((TInt*)(iInfoPtr+p)); + } + else + blocksz = state & 0x0f; + + p = iRemP+blocksz; + if (blocksz>0) + p -= 1; + if (p>=iLength) + p-=iLength; + aStatus = (iInfoPtr[p] << KReceiveIsrShift) & KReceiveIsrMaskComplete; + + TInt length = aRxLength; + TInt offset = aRxOffset; + + if (blocksz>0 && blockszDisableInterrupts(); + TInt count = iCount; + // The number of bytes will will extract in total + TInt maxcopy = Min(length, count); + // Pre-empt the recv int handler so that the sequence + // spaces dont clash + iRemSeqNum += maxcopy; + if (iRemSeqNum > iLastSeqNum) + iLastSeqNum = iRemSeqNum; + aDriver->EnableInterrupts(); + + TInt copylen; + TPtrC8 des; + copylen = Min(maxcopy, iLength-iRemP); + des.Set(iCharPtr+iRemP, copylen); + aThread->Write(aPtr, &des, offset, aMode); + offset += copylen; + length -= copylen; + count -= copylen; + + copylen = Min(length, count); + if (copylen>0) + { + des.Set(iCharPtr, copylen); + aThread->Write(aPtr, &des, offset, aMode); + length -= copylen; + count -= copylen; + offset += copylen; + } + + aDriver->DisableInterrupts(); + iRemP += maxcopy; + + if (iRemP >= iLength) + iRemP -= iLength; + + iCount -= maxcopy; + + aDriver->EnableInterrupts(); + + if (blocksz>maxcopy) + { + TInt ptr = iRemP; + TInt count = blocksz-maxcopy; + if (count<0x0f) + iInfoPtr[ptr] = (TUint8)((iInfoPtr[ptr] & 0xf0) | count); + else + { + iInfoPtr[ptr] = (TUint8)((iInfoPtr[ptr] & 0xf0) | 0x0f); + // Word align buffer offset and wrap if needed + // so a full count can be written + ptr = (ptr+0x4)&~0x3; + if (ptr>=iLength) + ptr = 0; + *((TInt*)(iInfoPtr+ptr)) = count; + } + } + + aRxOffset = offset; + aRxLength = length; + + if (blocksz>0) + return (blocksz-maxcopy)==0 || aRxLength==0; + + return aRxLength==0; + } + + +TInt CCommRxBuf::PutChar(TUint aChar) +// +// Add char to receive buffer +// Return true if this character should complete +// a Read(). +// + { + if (iCount>=iLength) + return KErrOverflow; + + iCharPtr[iInsP] = (TUint8)(aChar & 0xff); + iInfoPtr[iInsP] = (TUint8)(aChar >> KReceiveIsrShift); + if (++iInsP >= iLength) + iInsP = 0; + ++iCount; + ++iInsSeqNum; // Pre-Inc is more efficient for a C++ object + + // Check if we have to write a new event offset into + // the info buffer + if (aChar & KReceiveIsrMaskComplete) + { + TInt count = iInsSeqNum - iLastSeqNum; + TInt ptr = iInsP-count; + if (ptr<0) + ptr += iLength; + + if (count<0x0f) + iInfoPtr[ptr] = (TUint8)((iInfoPtr[ptr] & 0xf0) | count); + else + { + iInfoPtr[ptr] = (TUint8)((iInfoPtr[ptr] & 0xf0) | 0x0f); + // Word align buffer offset and wrap if needed + // so a full count can be written + ptr = (ptr+0x4)&~0x3; + if (ptr>=iLength) + ptr = 0; + *((TInt*)(iInfoPtr+ptr)) = count; + } + iLastSeqNum = iInsSeqNum; + return 1; + } + + return 0; + } + + +TBool CCommRxBuf::RescanTerminators(DComm* aDriver, TInt aTermCount, TText8* aTermChars) + { + aDriver->DisableInterrupts(); + + TCommSeqNum _rem = iRemSeqNum; + + // 1. Move last event point to the current insert pointer + // This protects from interrupts + iLastSeqNum = iInsSeqNum; + TCommSeqNum endseq = iLastSeqNum; + + // 2. Remove all count information, and terminator flags + + TInt ptr = iRemP; + TCommSeqNum seq = iRemSeqNum; + + while (seq=iLength) + p = 0; + len = *((TInt*)(iInfoPtr+p)); + *((TInt*)(iInfoPtr+p)) = 0; + } + else + { + iInfoPtr[p] &= 0xf0; + len = s & 0x0f; + } + + ptr += len; + p = ptr; + + if (len>0) + p -= 1; + if (p>=iLength) + p-=iLength; + + iInfoPtr[p] &= ~(KReceiveIsrTermChar>>KReceiveIsrShift); + + if (ptr>=iLength) + ptr -= iLength; + seq += len; + } + + // 3. Now create a new set of counts and events exactly as if inserting the + // characters for the first time. + + TBool complete = EFalse; + TInt lstptr; + TCommSeqNum lstseq; + + ptr = iRemP; + seq = iRemSeqNum; + + lstseq = seq; + lstptr = ptr; + + while (seq>KReceiveIsrShift); + break; + } + } + + if (iInfoPtr[ptr] & (KReceiveIsrMaskComplete>>KReceiveIsrShift)) + { + TInt len = seq-lstseq; + if (len<0x0f) + iInfoPtr[lstptr] = (TUint8)((iInfoPtr[lstptr] & 0xf0) | len); + else + { + iInfoPtr[lstptr] = (TUint8)((iInfoPtr[lstptr] & 0xf0) | 0x0f); + // Word align buffer offset and wrap if needed + // so a full count can be written + TInt p = (lstptr+0x4)&~0x3; + if (p>=iLength) + p = 0; + *((TInt*)(iInfoPtr+p)) = len; + } + lstptr = ptr+1; + if (lstptr>=iLength) + lstptr -= iLength; + lstseq = seq; + complete = ETrue; + } + if (++ptr>=iLength) + ptr -= iLength; + } + + // 4. Tie into new location of event seq pointer that may have been moved + // as a result of receive interrupts inserting new events + if (iLastSeqNum==endseq) + { + // No interrupts have occurred that resulted in a new event. + iLastSeqNum = lstseq; + } + else + { + // New event was generated by the interrupt handler + // So extract and zero the inserted count + TInt p = ptr; + TInt len; + TUint s = iInfoPtr[p]; + + if (s==0) + len = endseq-seq; + else if ((s & 0x0f)==0x0f) + { + p = (ptr+0x4)&~0x3; + if (p>=iLength) + p = 0; + len = *((TInt*)(iInfoPtr+p)); + *((TInt*)(iInfoPtr+p)) = 0; + } + else + { + iInfoPtr[p] &= 0xf0; + len = s & 0x0f; + } + // And in the offset for the last event in the re-scan + len += seq-lstseq; + // Insert the count into the re-scanned section + if (len<0x0f) + iInfoPtr[lstptr] = (TUint8)((iInfoPtr[lstptr] & 0xf0) | len); + else + { + iInfoPtr[lstptr] = (TUint8)((iInfoPtr[lstptr] & 0xf0) | 0x0f); + // Word align buffer offset and wrap if needed + // so a full count can be written + p = (lstptr+0x4)&~0x3; + if (p>=iLength) + p = 0; + *((TInt*)(iInfoPtr+p)) = len; + } + complete = ETrue; + } + + aDriver->EnableInterrupts(); + return complete; + }