sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // DBMS server stream buffer classes sl@0: // sl@0: // sl@0: sl@0: sl@0: sl@0: #include "SD_STD.H" sl@0: sl@0: HDbsBuf* HDbsBuf::NewLC(const RDbsObject& aObject,TDbsFunction aFunction,TIpcArgs& aArgs) sl@0: { sl@0: HDbsBuf* self=new(ELeave) HDbsBuf; sl@0: self->PushL(); sl@0: self->ConstructL(aObject,aFunction,aArgs); sl@0: return self; sl@0: } sl@0: sl@0: HDbsBuf* HDbsBuf::NewL(const RDbsObject& aObject,TDbsFunction aFunction,TIpcArgs& aArgs) sl@0: { sl@0: HDbsBuf* self=NewLC(aObject,aFunction,aArgs); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: void HDbsBuf::ConstructL(const RDbsObject& aObject,TDbsFunction aFunction,TIpcArgs& aArgs) sl@0: { sl@0: TPckg<TDbsStreamBuf> pckg(iBuf); sl@0: aArgs.Set(3,&pckg); sl@0: iIpc.OpenL(aObject,aFunction,aArgs); sl@0: TUint8* base=iBuf.iData; sl@0: // if reading we already have one buffer-full of data sl@0: TInt avail=Max(0,Min(iBuf.iExt,KDbsStreamBufSize)); sl@0: SetBuf(ERead,base,base+avail); sl@0: SetPos(ERead,avail); sl@0: SetBuf(EWrite,base,base); sl@0: SetPos(EWrite,0); sl@0: } sl@0: sl@0: TInt HDbsBuf::UnderflowL(TInt) sl@0: // sl@0: // Fill the buffer's read area. sl@0: // sl@0: { sl@0: // when handle is null there is no data to read from server sl@0: if(!iIpc.Handle()) sl@0: return 0; sl@0: sl@0: __ASSERT(Avail(ERead)==0); sl@0: TUint8* base=iBuf.iData; sl@0: IpcWriteL(base,Lag(EWrite)); sl@0: SetBuf(EWrite,base,base); sl@0: // sl@0: TInt len=IpcReadL(base,iBuf.ESize); sl@0: SetBuf(ERead,base,base+len); sl@0: return len; sl@0: } sl@0: sl@0: void HDbsBuf::OverflowL() sl@0: // sl@0: // Set up the buffer's write area. sl@0: // sl@0: { sl@0: __ASSERT(Avail(EWrite)==0); sl@0: TUint8* base=iBuf.iData; sl@0: MovePos(ERead,Lag(ERead)); sl@0: SetBuf(ERead,base,base); sl@0: // sl@0: IpcWriteL(base,Lag(EWrite)); sl@0: SetBuf(EWrite,base,base+iBuf.ESize); sl@0: } sl@0: sl@0: void HDbsBuf::DoRelease() sl@0: { sl@0: delete this; sl@0: } sl@0: sl@0: void HDbsBuf::DoSynchL() sl@0: // sl@0: // Synchronise this buffer with its file, giving up on outstanding writes in case of failure. sl@0: // sl@0: { sl@0: TUint8* base=iBuf.iData; sl@0: MovePos(ERead,Lag(ERead)); sl@0: TInt lag=Lag(EWrite); sl@0: SetBuf(ERead|EWrite,base,base); sl@0: iBuf.iExt=-1; sl@0: IpcWriteL(base,lag); sl@0: iIpc.SendReceiveL(EDbsStreamSynch); sl@0: } sl@0: sl@0: TInt HDbsBuf::DoReadL(TAny* aPtr,TInt aMaxLength) sl@0: // sl@0: // Read direct from ipc if asked to transfer more than a bufferful. sl@0: // sl@0: { sl@0: __ASSERT(aMaxLength>=0); sl@0: __ASSERT(aMaxLength>0); sl@0: TInt avail=Avail(ERead); sl@0: __ASSERT(avail>=0&&Avail(EWrite)>=0); sl@0: if (avail>0) sl@0: { sl@0: TInt len=Min(aMaxLength,avail); sl@0: TUint8* ptr=Ptr(ERead); sl@0: aPtr=Mem::Copy(aPtr,ptr,len); sl@0: SetPtr(ERead,ptr+len); sl@0: aMaxLength-=len; sl@0: if (aMaxLength==0) sl@0: return len; // that's it sl@0: } sl@0: __ASSERT(Avail(ERead)==0); sl@0: if (aMaxLength<iBuf.ESize) sl@0: return avail+TStreamBuf::DoReadL(aPtr,aMaxLength); sl@0: // sl@0: // when handle is null there is no more data to read from server sl@0: if(!iIpc.Handle()) sl@0: return avail; sl@0: sl@0: TUint8* base=iBuf.iData; sl@0: IpcWriteL(base,Lag(EWrite)); sl@0: SetBuf(ERead|EWrite,base,base); sl@0: return avail+IpcReadL(aPtr,aMaxLength); sl@0: } sl@0: sl@0: void HDbsBuf::DoWriteL(const TAny* aPtr,TInt aLength) sl@0: // sl@0: // Write direct to ipc if asked to transfer more than a bufferful. sl@0: // sl@0: { sl@0: __ASSERT(aLength>=0); sl@0: __ASSERT(aLength>0); sl@0: TInt avail=Avail(EWrite); sl@0: __ASSERT(Avail(ERead)>=0&&avail>=0); sl@0: if (avail>0) sl@0: { sl@0: TInt len=Min(aLength,avail); sl@0: SetPtr(EWrite,Mem::Copy(Ptr(EWrite),aPtr,len)); sl@0: aLength-=len; sl@0: if (aLength==0) sl@0: return; // done sl@0: // sl@0: aPtr=(TUint8*)aPtr+len; sl@0: } sl@0: __ASSERT(Avail(EWrite)==0); sl@0: if (aLength<iBuf.ESize) sl@0: TStreamBuf::DoWriteL(aPtr,aLength); sl@0: else sl@0: { sl@0: TUint8* base=iBuf.iData; sl@0: IpcWriteL(base,Lag(EWrite)); sl@0: MovePos(ERead,Lag(ERead)); sl@0: SetBuf(ERead|EWrite,base,base); sl@0: IpcWriteL(aPtr,aLength); sl@0: } sl@0: } sl@0: sl@0: TStreamPos HDbsBuf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset) sl@0: // sl@0: // Position the mark(s) indicated by aMark at anOffset from aLocation. sl@0: // sl@0: { sl@0: TUint8* base=iBuf.iData; sl@0: TInt end=EndL(); sl@0: // sl@0: switch (aLocation) sl@0: { sl@0: case EStreamBeginning: sl@0: break; sl@0: case EStreamMark: sl@0: switch (aMark) sl@0: { sl@0: case ERead: sl@0: anOffset+=Mark(ERead); sl@0: break; sl@0: case EWrite: sl@0: anOffset+=Mark(EWrite); sl@0: break; sl@0: default: sl@0: Panic(EDbsStreamMarkInvalid); sl@0: break; sl@0: } sl@0: break; sl@0: case EStreamEnd: sl@0: anOffset+=end; sl@0: break; sl@0: default: sl@0: Panic(EDbsStreamLocationInvalid); sl@0: break; sl@0: } sl@0: TInt r=KErrNone; sl@0: if (anOffset<0) sl@0: { sl@0: anOffset=0; sl@0: r=KErrEof; sl@0: } sl@0: else if (anOffset>end) sl@0: { sl@0: anOffset=end; sl@0: r=KErrEof; sl@0: } sl@0: // sl@0: __ASSERT_ALWAYS(!(aMark&~(ERead|EWrite)),Panic(EDbsStreamMarkInvalid)); sl@0: if (aMark&ERead) sl@0: { sl@0: TInt lag=anOffset-Pos(ERead); sl@0: if (lag>=base-End(ERead)&&lag<=0) sl@0: SetPtr(ERead,End(ERead)+lag); sl@0: else sl@0: { sl@0: SetPos(ERead,anOffset); sl@0: SetBuf(ERead,base,base); sl@0: } sl@0: } sl@0: if (aMark&EWrite&&anOffset!=Mark(EWrite)) sl@0: { sl@0: IpcWriteL(base,Lag(EWrite)); sl@0: SetPos(EWrite,anOffset); sl@0: SetBuf(EWrite,base,base); sl@0: } sl@0: __LEAVE_IF_ERROR(r); sl@0: return TStreamPos(anOffset); sl@0: } sl@0: sl@0: TInt HDbsBuf::IpcReadL(TAny* aPtr,TInt aMaxLength) sl@0: // sl@0: // Read from the server at the current read position. sl@0: // sl@0: { sl@0: __ASSERT(aMaxLength>=0); sl@0: if (aMaxLength==0) sl@0: return 0; sl@0: // sl@0: TPtr8 des((TUint8*)aPtr,aMaxLength); sl@0: TInt pos=Pos(ERead); sl@0: sl@0: TInt len=iIpc.SendReceiveL(EDbsStreamRead,TIpcArgs(pos,&des,aMaxLength)); sl@0: pos+=len; sl@0: if (len<aMaxLength) sl@0: iBuf.iExt=pos; // end-of-file encountered sl@0: SetPos(ERead,pos); sl@0: return len; sl@0: } sl@0: sl@0: void HDbsBuf::IpcWriteL(const TAny* aPtr,TInt aLength) sl@0: // sl@0: // Write to the server at the current write position. sl@0: // sl@0: { sl@0: __ASSERT(aLength>=0); sl@0: if (aLength==0) sl@0: return; sl@0: // sl@0: TPtrC8 ptr((TUint8*)aPtr,aLength); sl@0: TInt ext=iBuf.iExt; sl@0: iBuf.iExt=-1; sl@0: TInt pos=Pos(EWrite); sl@0: iIpc.SendReceiveL(EDbsStreamWrite,TIpcArgs(pos,&ptr)); sl@0: pos+=aLength; sl@0: if (ext>=0&&pos>ext) sl@0: iBuf.iExt=pos; sl@0: SetPos(EWrite,pos); sl@0: } sl@0: sl@0: TInt HDbsBuf::EndL() sl@0: // sl@0: // Determine the end of the stream sl@0: // sl@0: { sl@0: TInt ext=iBuf.iExt; sl@0: if (ext<0) sl@0: iBuf.iExt=ext=iIpc.SendReceiveL(EDbsStreamSize); sl@0: return Max(ext,Mark(EWrite)); sl@0: } sl@0: sl@0: // Class HDbsReadBuf sl@0: sl@0: inline HDbsReadBuf::HDbsReadBuf(const TDesC8& aDes) sl@0: { sl@0: TUint8* ptr=CONST_CAST(TUint8*,aDes.Ptr()); sl@0: Set(ptr,ptr+aDes.Length(),ERead); sl@0: } sl@0: sl@0: HDbsReadBuf* HDbsReadBuf::NewL(const TDesC8& aDes) sl@0: { sl@0: return new(ELeave) HDbsReadBuf(aDes); sl@0: } sl@0: sl@0: void HDbsReadBuf::DoRelease() sl@0: { sl@0: delete this; sl@0: } sl@0: sl@0: // Class HDbsStream sl@0: TInt HDbsStream::ReadL(const RMessage2& aMessage) sl@0: { sl@0: TInt pos=aMessage.Int0(); sl@0: if (pos!=iRPos) sl@0: iHost.SeekL(iHost.ERead,EStreamBeginning,pos); sl@0: iRPos=-1; sl@0: TInt len=aMessage.Int2(); sl@0: pos+=len; sl@0: TInt tfr=len; sl@0: for (;;) sl@0: { sl@0: TUint8 buf[KDbsStreamIoSize]; sl@0: TInt read=iHost.ReadL(buf,Min(tfr,KDbsStreamIoSize)); sl@0: if (read==0) sl@0: break; sl@0: aMessage.WriteL(1,TPtrC8(buf,read),len-tfr); sl@0: tfr-=read; sl@0: if (tfr==0) sl@0: break; sl@0: if (read<KDbsStreamIoSize) sl@0: break; sl@0: } sl@0: iRPos=pos-tfr; sl@0: return len-tfr; sl@0: } sl@0: sl@0: void HDbsStream::WriteL(const RMessage2& aMessage) sl@0: { sl@0: TInt pos=aMessage.Int0(); sl@0: if (pos!=iWPos) sl@0: iHost.SeekL(iHost.EWrite,EStreamBeginning,pos); sl@0: iWPos=-1; sl@0: TInt offset=0; sl@0: TBuf8<KDbsStreamIoSize> buf; sl@0: for (;;) sl@0: { sl@0: aMessage.ReadL(1,buf,offset); sl@0: TInt len=buf.Length(); sl@0: if (len==0) sl@0: break; sl@0: iHost.WriteL(buf.Ptr(),len); sl@0: offset+=len; sl@0: if (len<KDbsStreamIoSize) sl@0: break; sl@0: } sl@0: iWPos=pos+offset; sl@0: } sl@0: sl@0: // Class HBufBuf sl@0: sl@0: void HBufBuf::DoRelease() sl@0: { sl@0: delete this; sl@0: } sl@0: sl@0: HBufBuf* HBufBuf::NewLC() sl@0: { sl@0: HBufBuf* self=new(ELeave) HBufBuf; sl@0: self->PushL(); sl@0: self->iBuf=CBufSeg::NewL(EGranularity); sl@0: self->Set(*self->iBuf,0,ERead|EWrite); sl@0: return self; sl@0: } sl@0: