diff -r 000000000000 -r 96e5fb8b040d userlibandfileserver/fileserver/shostmassstorage/server/protocol/tblocktransfer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tblocktransfer.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,239 @@ +// Copyright (c) 2008-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: +// + +/** + @file + @internalTechnology +*/ + +#include +#include +#include +#include "msctypes.h" + +#include "mblocktransferprotocol.h" +#include "tblocktransfer.h" +#include "debug.h" +#include "msdebug.h" + + +/** +Manage a read from a block device. + +@param aProtocol A reference to object providing protocol read method +@param aPosition The position to start reading from +@param aLength The length of data to read +@param aBuf Buffer to copy the data to +*/ +void TBlockTransfer::ReadL(MBlockTransferProtocol& aProtocol, + TPos aPosition, + TInt aLength, + TDes8& aBuf) + { + __MSFNLOG + __HOSTPRINT1(_L("blocklen = 0%lx"), iBlockLength); + + TInt copylen = 0; + TInt headlen = 0; + + aBuf.SetLength(0); + TPos headOffset = GetHeadBlockOffset(aPosition); + /**** READ10 HEAD ****/ + if (headOffset) + { + TPos headpos = aPosition - headOffset; + iHeadbuf->Zero(); + headlen = ((headOffset + aLength - 1) / iBlockLength) == 0 ? aLength : (iBlockLength - headOffset); + + __HOSTPRINT2(_L("\tRead head pos = 0%lx length = 0%lx"), + headpos, iBlockLength); + aProtocol.BlockReadL(headpos, *iHeadbuf, iBlockLength); + aBuf.Append(iHeadbuf->Ptr() + headOffset, headlen); + } + + /**** READ10 BODY ****/ + TInt blocksInMain = (aLength - headlen)/iBlockLength; + if (blocksInMain) + { + copylen = blocksInMain * iBlockLength; + __HOSTPRINT2(_L("\tRead main pos = 0%lx length = 0x%x"), + aPosition+headlen, copylen); + aProtocol.BlockReadL(aPosition+headlen, (TDes8 &)aBuf, copylen); + } + + copylen += headlen; + + /**** READ10 TAIL ****/ + TInt tailLen = aLength - copylen; + if ((tailLen) != 0) + { + __HOSTPRINT2(_L("\tRead tail pos = 0%lx length = 0%lx"), + aPosition+copylen, iBlockLength); + iTailbuf->Zero(); + aProtocol.BlockReadL(aPosition+copylen, *iTailbuf, iBlockLength); + aBuf.Append(iTailbuf->Ptr(), tailLen); + } + } + + +/** +Manage a write to a block device + +@param aProtocol A reference to object providing protocol read method +@param aPosition The position to start reading from +@param aLength The length of data to read +@param aBuf Buffer containing the data to write +*/ +void TBlockTransfer::WriteL(MBlockTransferProtocol& aProtocol, + TPos aPosition, + TInt aLength, + TDesC8& aBuf) + { + __MSFNLOG + TInt copylen = 0; + TInt headlen = 0; + + TPos headOffset = GetHeadBlockOffset(aPosition); + /**** WRITE10 HEAD ****/ + if (headOffset) + { + TPos headpos = aPosition - headOffset; + + iHeadbuf->Zero(); + + RBuf8& buf = *iTailbuf; + buf.Zero(); + + headlen = ((headOffset + aLength - 1) / iBlockLength) == 0 ? aLength : (iBlockLength - headOffset); + + __HOSTPRINT2(_L("\tWrite-Read head pos = 0%lx length = 0%lx"), + headpos, iBlockLength); + + aProtocol.BlockReadL(headpos, *iHeadbuf, iBlockLength); + /* get head */ + __HOSTPRINT2(_L("\tcopying read data pos = 0%lx offset = 0%lx"), + headpos, headOffset); + buf.Append(iHeadbuf->Ptr(), headOffset); + + /* get body */ + buf.Append(aBuf.Ptr(), headlen); + + /* Is it a short write and tail exist? */ + TInt headEndOffset = headOffset + headlen; + if (headEndOffset != iBlockLength) + { + TInt len = iBlockLength - headEndOffset; + + __HOSTPRINT2(_L("\t(short write) copying read data pos = 0%lx length = %08x"), + (headpos + headEndOffset), len); + buf.Append(iHeadbuf->Ptr() + headEndOffset, len); + } + + __HOSTPRINT2(_L("\tWrite head pos = 0%lx length = %08x"), + headpos, headlen); + + aProtocol.BlockWriteL(headpos, (TDes8 &)buf, 0, iBlockLength); + } + + /**** WRITE10 BODY ****/ + TPos blocksInMain = (aLength - headlen)/iBlockLength; + if (blocksInMain) + { + copylen = blocksInMain * iBlockLength; + + const TUint64 pos = aPosition + headlen; + __HOSTPRINT2(_L("\tWrite main pos = 0%lx length = %08x"), + pos, copylen); + + /* form the body */ + aProtocol.BlockWriteL(pos, (TDes8 &)aBuf, headlen, copylen); + } + + copylen += headlen; + + /**** WRITE10 TAIL ****/ + TInt tailLen = aLength - copylen;; + if (tailLen != 0) + { + RBuf8& buf = *iHeadbuf; + buf.Zero(); + + iTailbuf->Zero(); + + const TUint64 pos = aPosition + copylen; + + __HOSTPRINT2(_L("\tWrite-Read tail pos = 0%lx length = %08x"), + pos, iBlockLength); + + aProtocol.BlockReadL(pos, *iTailbuf, iBlockLength); + /* get head */ + buf.Append(aBuf.Ptr() + copylen, tailLen); + /* get tail */ + buf.Append(iTailbuf->Ptr() + tailLen, iBlockLength - tailLen); + + aProtocol.BlockWriteL(pos, (TDes8 &)buf, 0, iBlockLength); + } + } + + +void TBlockTransfer::SetCapacityL(TUint32 aBlockLength, TLba aLastLba) + { + __MSFNLOG + iBlockLength = static_cast(aBlockLength); + iLastLba = aLastLba; + + __ASSERT_DEBUG(iHeadbuf, User::Invariant()); + __ASSERT_DEBUG(iTailbuf, User::Invariant()); + + if (iHeadbuf->Length() < iBlockLength) + { + iHeadbuf->ReAllocL(aBlockLength); + iTailbuf->ReAllocL(aBlockLength); + } + } + + +TPos TBlockTransfer::GetHeadBlockOffset(TPos aPos) + { + __MSFNLOG + return (aPos % iBlockLength); + } + +TLba TBlockTransfer::GetHeadBlockLbaL(TPos aPos) + { + __MSFNLOG + TLba lba = I64LOW(aPos / iBlockLength); + if (lba > iLastLba) + User::Leave(KErrArgument); + return lba; + } + +TPos TBlockTransfer::GetTailBlockOffset(TPos aPos, TInt aLen) + { + __MSFNLOG + return ((aPos + aLen) % iBlockLength); + } + +TLba TBlockTransfer::GetTailBlockLbaL(TPos aPos, TInt aLen) + { + __MSFNLOG + TLba lba = I64LOW((aPos + aLen) / iBlockLength); + if (lba > iLastLba) + User::Leave(KErrArgument); + return lba; + } + + +