userlibandfileserver/fileserver/shostmassstorage/server/protocol/tblocktransfer.cpp
changeset 43 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 43:96e5fb8b040d
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalTechnology
       
    19 */
       
    20 
       
    21 #include <e32def.h>
       
    22 #include <e32std.h>
       
    23 #include <e32base.h>
       
    24 #include "msctypes.h"
       
    25 
       
    26 #include "mblocktransferprotocol.h"
       
    27 #include "tblocktransfer.h"
       
    28 #include "debug.h"
       
    29 #include "msdebug.h"
       
    30 
       
    31 
       
    32 /**
       
    33 Manage a read from a block device.
       
    34 
       
    35 @param aProtocol A reference to object providing protocol read method
       
    36 @param aPosition The position to start reading from
       
    37 @param aLength The length of data to read
       
    38 @param aBuf Buffer to copy the data to
       
    39 */
       
    40 void TBlockTransfer::ReadL(MBlockTransferProtocol& aProtocol,
       
    41                            TPos aPosition,
       
    42                            TInt aLength,
       
    43                            TDes8& aBuf)
       
    44     {
       
    45     __MSFNLOG
       
    46 	__HOSTPRINT1(_L("blocklen = 0%lx"), iBlockLength);
       
    47 
       
    48 	TInt copylen = 0;
       
    49     TInt headlen = 0;
       
    50 
       
    51 	aBuf.SetLength(0);
       
    52     TPos headOffset = GetHeadBlockOffset(aPosition);
       
    53 	/**** READ10 HEAD ****/
       
    54 	if (headOffset)
       
    55         {
       
    56 		TPos headpos = aPosition - headOffset;
       
    57         iHeadbuf->Zero();
       
    58 		headlen = ((headOffset + aLength - 1) / iBlockLength) == 0 ? aLength : (iBlockLength - headOffset);
       
    59 
       
    60 		__HOSTPRINT2(_L("\tRead head pos = 0%lx length = 0%lx"),
       
    61                      headpos, iBlockLength);
       
    62 		aProtocol.BlockReadL(headpos, *iHeadbuf, iBlockLength);
       
    63 		aBuf.Append(iHeadbuf->Ptr() + headOffset, headlen);		
       
    64         }
       
    65 
       
    66 	/**** READ10 BODY ****/
       
    67     TInt blocksInMain = (aLength - headlen)/iBlockLength;
       
    68 	if (blocksInMain)
       
    69         {
       
    70 		copylen = blocksInMain * iBlockLength;
       
    71 		__HOSTPRINT2(_L("\tRead main pos = 0%lx length = 0x%x"),
       
    72                      aPosition+headlen, copylen);
       
    73 		aProtocol.BlockReadL(aPosition+headlen, (TDes8 &)aBuf, copylen);
       
    74         }
       
    75 
       
    76 	copylen += headlen;
       
    77 
       
    78 	/**** READ10 TAIL ****/
       
    79     TInt tailLen = aLength - copylen;
       
    80 	if ((tailLen) != 0)
       
    81         {
       
    82 		__HOSTPRINT2(_L("\tRead tail pos = 0%lx length = 0%lx"),
       
    83                      aPosition+copylen, iBlockLength);
       
    84         iTailbuf->Zero();    
       
    85 		aProtocol.BlockReadL(aPosition+copylen, *iTailbuf, iBlockLength);
       
    86 		aBuf.Append(iTailbuf->Ptr(), tailLen);
       
    87         }
       
    88     }
       
    89 
       
    90 
       
    91 /**
       
    92 Manage a write to a block device
       
    93 
       
    94 @param aProtocol A reference to object providing protocol read method
       
    95 @param aPosition The position to start reading from
       
    96 @param aLength The length of data to read
       
    97 @param aBuf Buffer containing the data to write
       
    98 */
       
    99 void TBlockTransfer::WriteL(MBlockTransferProtocol& aProtocol,
       
   100                             TPos aPosition,
       
   101                             TInt aLength,
       
   102                             TDesC8& aBuf)
       
   103     {
       
   104     __MSFNLOG
       
   105 	TInt copylen = 0;
       
   106     TInt headlen = 0;
       
   107 
       
   108     TPos headOffset = GetHeadBlockOffset(aPosition);
       
   109 	/**** WRITE10 HEAD ****/
       
   110 	if (headOffset)
       
   111         {
       
   112 		TPos headpos = aPosition - headOffset;
       
   113 
       
   114         iHeadbuf->Zero();
       
   115 
       
   116         RBuf8& buf = *iTailbuf;
       
   117         buf.Zero();
       
   118 
       
   119 		headlen = ((headOffset + aLength - 1) / iBlockLength) == 0 ? aLength : (iBlockLength - headOffset);
       
   120 
       
   121 		__HOSTPRINT2(_L("\tWrite-Read head pos = 0%lx length = 0%lx"),
       
   122                      headpos, iBlockLength);
       
   123 
       
   124 		aProtocol.BlockReadL(headpos, *iHeadbuf, iBlockLength);
       
   125 		/* get head */
       
   126 		__HOSTPRINT2(_L("\tcopying read data pos = 0%lx offset = 0%lx"),
       
   127                      headpos, headOffset);
       
   128 		buf.Append(iHeadbuf->Ptr(), headOffset);
       
   129 
       
   130 		/* get body */
       
   131 		buf.Append(aBuf.Ptr(), headlen);
       
   132 
       
   133 		/* Is it a short write and tail exist? */
       
   134         TInt headEndOffset = headOffset + headlen;
       
   135 		if (headEndOffset != iBlockLength)
       
   136             {
       
   137             TInt len = iBlockLength - headEndOffset;
       
   138 
       
   139 			__HOSTPRINT2(_L("\t(short write) copying read data pos = 0%lx length = %08x"),
       
   140                          (headpos + headEndOffset), len);
       
   141 			buf.Append(iHeadbuf->Ptr() + headEndOffset, len);
       
   142             }
       
   143 
       
   144 		__HOSTPRINT2(_L("\tWrite head pos = 0%lx length = %08x"),
       
   145                      headpos, headlen);
       
   146 
       
   147 		aProtocol.BlockWriteL(headpos, (TDes8 &)buf, 0, iBlockLength);
       
   148         }
       
   149 
       
   150 	/**** WRITE10 BODY ****/
       
   151     TPos blocksInMain = (aLength - headlen)/iBlockLength;
       
   152 	if (blocksInMain)
       
   153         {
       
   154 		copylen = blocksInMain * iBlockLength;
       
   155 
       
   156         const TUint64 pos = aPosition + headlen;
       
   157 		__HOSTPRINT2(_L("\tWrite main pos = 0%lx length = %08x"),
       
   158                      pos, copylen);
       
   159 
       
   160 		/* form the body */
       
   161 		aProtocol.BlockWriteL(pos, (TDes8 &)aBuf, headlen, copylen);
       
   162         }
       
   163 
       
   164 	copylen += headlen;
       
   165 
       
   166 	/**** WRITE10 TAIL ****/
       
   167     TInt tailLen = aLength - copylen;;
       
   168 	if (tailLen != 0)
       
   169         {
       
   170         RBuf8& buf = *iHeadbuf;
       
   171         buf.Zero();
       
   172 
       
   173         iTailbuf->Zero();
       
   174 
       
   175         const TUint64 pos = aPosition + copylen;
       
   176 
       
   177 		__HOSTPRINT2(_L("\tWrite-Read tail pos = 0%lx length = %08x"),
       
   178                      pos, iBlockLength);
       
   179 
       
   180 		aProtocol.BlockReadL(pos, *iTailbuf, iBlockLength);
       
   181 		/* get head */
       
   182 		buf.Append(aBuf.Ptr() + copylen, tailLen);
       
   183 		/* get tail */
       
   184 		buf.Append(iTailbuf->Ptr() + tailLen, iBlockLength - tailLen);
       
   185 
       
   186 		aProtocol.BlockWriteL(pos, (TDes8 &)buf, 0, iBlockLength);
       
   187         }
       
   188     }
       
   189 
       
   190 
       
   191 void TBlockTransfer::SetCapacityL(TUint32 aBlockLength, TLba aLastLba)
       
   192     {
       
   193     __MSFNLOG
       
   194     iBlockLength = static_cast<TInt64>(aBlockLength);
       
   195     iLastLba = aLastLba;
       
   196 
       
   197     __ASSERT_DEBUG(iHeadbuf, User::Invariant());
       
   198     __ASSERT_DEBUG(iTailbuf, User::Invariant());
       
   199 
       
   200     if (iHeadbuf->Length() < iBlockLength)
       
   201         {
       
   202         iHeadbuf->ReAllocL(aBlockLength);
       
   203         iTailbuf->ReAllocL(aBlockLength);
       
   204         }    
       
   205     }
       
   206 
       
   207 
       
   208 TPos TBlockTransfer::GetHeadBlockOffset(TPos aPos)
       
   209     {
       
   210     __MSFNLOG
       
   211 	return (aPos % iBlockLength);
       
   212     }
       
   213 
       
   214 TLba TBlockTransfer::GetHeadBlockLbaL(TPos aPos)
       
   215     {
       
   216     __MSFNLOG
       
   217     TLba lba = I64LOW(aPos / iBlockLength);
       
   218     if (lba > iLastLba)
       
   219         User::Leave(KErrArgument);
       
   220     return lba;
       
   221     }
       
   222 
       
   223 TPos TBlockTransfer::GetTailBlockOffset(TPos aPos, TInt aLen)
       
   224     {
       
   225     __MSFNLOG
       
   226     return ((aPos + aLen) % iBlockLength);
       
   227     }
       
   228 
       
   229 TLba TBlockTransfer::GetTailBlockLbaL(TPos aPos, TInt aLen)
       
   230     {
       
   231     __MSFNLOG
       
   232     TLba lba = I64LOW((aPos + aLen) / iBlockLength);
       
   233     if (lba > iLastLba)
       
   234         User::Leave(KErrArgument);
       
   235     return lba;
       
   236     }
       
   237 
       
   238 
       
   239