persistentstorage/dbms/sdbms/SD_BUF.CPP
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 1998-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 "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 // DBMS server stream buffer classes
       
    15 // 
       
    16 //
       
    17 
       
    18 
       
    19 
       
    20 #include "SD_STD.H"
       
    21 
       
    22 HDbsBuf* HDbsBuf::NewLC(const RDbsObject& aObject,TDbsFunction aFunction,TIpcArgs& aArgs)
       
    23 	{
       
    24 	HDbsBuf* self=new(ELeave) HDbsBuf;
       
    25 	self->PushL();
       
    26 	self->ConstructL(aObject,aFunction,aArgs);
       
    27 	return self;
       
    28 	}
       
    29 
       
    30 HDbsBuf* HDbsBuf::NewL(const RDbsObject& aObject,TDbsFunction aFunction,TIpcArgs& aArgs)
       
    31 	{
       
    32 	HDbsBuf* self=NewLC(aObject,aFunction,aArgs);
       
    33 	CleanupStack::Pop();
       
    34 	return self;
       
    35 	}
       
    36 
       
    37 void HDbsBuf::ConstructL(const RDbsObject& aObject,TDbsFunction aFunction,TIpcArgs& aArgs)
       
    38 	{
       
    39 	TPckg<TDbsStreamBuf> pckg(iBuf);
       
    40 	aArgs.Set(3,&pckg);
       
    41 	iIpc.OpenL(aObject,aFunction,aArgs);
       
    42 	TUint8* base=iBuf.iData;
       
    43 	// if reading we already have one buffer-full of data
       
    44 	TInt avail=Max(0,Min(iBuf.iExt,KDbsStreamBufSize));
       
    45 	SetBuf(ERead,base,base+avail);
       
    46 	SetPos(ERead,avail);
       
    47 	SetBuf(EWrite,base,base);
       
    48 	SetPos(EWrite,0);
       
    49 	}
       
    50 
       
    51 TInt HDbsBuf::UnderflowL(TInt)
       
    52 //
       
    53 // Fill the buffer's read area.
       
    54 //
       
    55 	{
       
    56 	// when handle is null there is no data to read from server
       
    57 	if(!iIpc.Handle())
       
    58 		return 0;
       
    59 
       
    60 	__ASSERT(Avail(ERead)==0);
       
    61 	TUint8* base=iBuf.iData;
       
    62 	IpcWriteL(base,Lag(EWrite));
       
    63 	SetBuf(EWrite,base,base);
       
    64 //
       
    65 	TInt len=IpcReadL(base,iBuf.ESize);
       
    66 	SetBuf(ERead,base,base+len);
       
    67 	return len;
       
    68 	}
       
    69 
       
    70 void HDbsBuf::OverflowL()
       
    71 //
       
    72 // Set up the buffer's write area.
       
    73 //
       
    74 	{
       
    75 	__ASSERT(Avail(EWrite)==0);
       
    76 	TUint8* base=iBuf.iData;
       
    77 	MovePos(ERead,Lag(ERead));
       
    78 	SetBuf(ERead,base,base);
       
    79 //
       
    80 	IpcWriteL(base,Lag(EWrite));
       
    81 	SetBuf(EWrite,base,base+iBuf.ESize);
       
    82 	}
       
    83 
       
    84 void HDbsBuf::DoRelease()
       
    85 	{
       
    86 	delete this;
       
    87 	}
       
    88 
       
    89 void HDbsBuf::DoSynchL()
       
    90 //
       
    91 // Synchronise this buffer with its file, giving up on outstanding writes in case of failure.
       
    92 //
       
    93 	{
       
    94 	TUint8* base=iBuf.iData;
       
    95 	MovePos(ERead,Lag(ERead));
       
    96 	TInt lag=Lag(EWrite);
       
    97 	SetBuf(ERead|EWrite,base,base);
       
    98 	iBuf.iExt=-1;
       
    99 	IpcWriteL(base,lag);
       
   100 	iIpc.SendReceiveL(EDbsStreamSynch);
       
   101 	}
       
   102 
       
   103 TInt HDbsBuf::DoReadL(TAny* aPtr,TInt aMaxLength)
       
   104 //
       
   105 // Read direct from ipc if asked to transfer more than a bufferful.
       
   106 //
       
   107 	{
       
   108 	__ASSERT(aMaxLength>=0);
       
   109 	__ASSERT(aMaxLength>0);
       
   110 	TInt avail=Avail(ERead);
       
   111 	__ASSERT(avail>=0&&Avail(EWrite)>=0);
       
   112 	if (avail>0)
       
   113 		{
       
   114 		TInt len=Min(aMaxLength,avail);
       
   115 		TUint8* ptr=Ptr(ERead);
       
   116 		aPtr=Mem::Copy(aPtr,ptr,len);
       
   117 		SetPtr(ERead,ptr+len);
       
   118 		aMaxLength-=len;
       
   119 		if (aMaxLength==0)
       
   120 			return len; // that's it
       
   121 		}
       
   122 	__ASSERT(Avail(ERead)==0);
       
   123 	if (aMaxLength<iBuf.ESize)
       
   124 		return avail+TStreamBuf::DoReadL(aPtr,aMaxLength);
       
   125 //
       
   126 	// when handle is null there is no more data to read from server
       
   127 	if(!iIpc.Handle())
       
   128 		return avail;
       
   129 
       
   130 	TUint8* base=iBuf.iData;
       
   131 	IpcWriteL(base,Lag(EWrite));
       
   132 	SetBuf(ERead|EWrite,base,base);
       
   133 	return avail+IpcReadL(aPtr,aMaxLength);
       
   134 	}
       
   135 
       
   136 void HDbsBuf::DoWriteL(const TAny* aPtr,TInt aLength)
       
   137 //
       
   138 // Write direct to ipc if asked to transfer more than a bufferful.
       
   139 //
       
   140 	{
       
   141 	__ASSERT(aLength>=0);
       
   142 	__ASSERT(aLength>0);
       
   143 	TInt avail=Avail(EWrite);
       
   144 	__ASSERT(Avail(ERead)>=0&&avail>=0);
       
   145 	if (avail>0)
       
   146 		{
       
   147 		TInt len=Min(aLength,avail);
       
   148 		SetPtr(EWrite,Mem::Copy(Ptr(EWrite),aPtr,len));
       
   149 		aLength-=len;
       
   150 		if (aLength==0)
       
   151 			return; // done
       
   152 //
       
   153 		aPtr=(TUint8*)aPtr+len;
       
   154 		}
       
   155 	__ASSERT(Avail(EWrite)==0);
       
   156 	if (aLength<iBuf.ESize)
       
   157 		TStreamBuf::DoWriteL(aPtr,aLength);
       
   158 	else
       
   159 		{
       
   160 		TUint8* base=iBuf.iData;
       
   161 		IpcWriteL(base,Lag(EWrite));
       
   162 		MovePos(ERead,Lag(ERead));
       
   163 		SetBuf(ERead|EWrite,base,base);
       
   164 		IpcWriteL(aPtr,aLength);
       
   165 		}
       
   166 	}
       
   167 
       
   168 TStreamPos HDbsBuf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset)
       
   169 //
       
   170 // Position the mark(s) indicated by aMark at anOffset from aLocation.
       
   171 //
       
   172 	{
       
   173 	TUint8* base=iBuf.iData;
       
   174 	TInt end=EndL();
       
   175 //
       
   176 	switch (aLocation)
       
   177 		{
       
   178 	case EStreamBeginning:
       
   179 		break;
       
   180 	case EStreamMark:
       
   181 		switch (aMark)
       
   182 			{
       
   183 		case ERead:
       
   184 			anOffset+=Mark(ERead);
       
   185 			break;
       
   186 		case EWrite:
       
   187 			anOffset+=Mark(EWrite);
       
   188 			break;
       
   189 		default:
       
   190 			Panic(EDbsStreamMarkInvalid);
       
   191 			break;
       
   192 			}
       
   193 		break;
       
   194 	case EStreamEnd:
       
   195 		anOffset+=end;
       
   196 		break;
       
   197 	default:
       
   198 		Panic(EDbsStreamLocationInvalid);
       
   199 		break;
       
   200 		}
       
   201 	TInt r=KErrNone;
       
   202 	if (anOffset<0)
       
   203 		{
       
   204 		anOffset=0;
       
   205 		r=KErrEof;
       
   206 		}
       
   207 	else if (anOffset>end)
       
   208 		{
       
   209 		anOffset=end;
       
   210 		r=KErrEof;
       
   211 		}
       
   212 //
       
   213 	__ASSERT_ALWAYS(!(aMark&~(ERead|EWrite)),Panic(EDbsStreamMarkInvalid));
       
   214 	if (aMark&ERead)
       
   215 		{
       
   216 		TInt lag=anOffset-Pos(ERead);
       
   217 		if (lag>=base-End(ERead)&&lag<=0)
       
   218 			SetPtr(ERead,End(ERead)+lag);
       
   219 		else
       
   220 			{
       
   221 			SetPos(ERead,anOffset);
       
   222 			SetBuf(ERead,base,base);
       
   223 			}
       
   224 		}
       
   225 	if (aMark&EWrite&&anOffset!=Mark(EWrite))
       
   226 		{
       
   227 		IpcWriteL(base,Lag(EWrite));
       
   228 		SetPos(EWrite,anOffset);
       
   229 		SetBuf(EWrite,base,base);
       
   230 		}
       
   231 	__LEAVE_IF_ERROR(r);
       
   232 	return TStreamPos(anOffset);
       
   233 	}
       
   234 
       
   235 TInt HDbsBuf::IpcReadL(TAny* aPtr,TInt aMaxLength)
       
   236 //
       
   237 // Read from the server at the current read position.
       
   238 //
       
   239 	{
       
   240 	__ASSERT(aMaxLength>=0);
       
   241 	if (aMaxLength==0)
       
   242 		return 0;
       
   243 //
       
   244 	TPtr8 des((TUint8*)aPtr,aMaxLength);
       
   245 	TInt pos=Pos(ERead);
       
   246 		
       
   247 	TInt len=iIpc.SendReceiveL(EDbsStreamRead,TIpcArgs(pos,&des,aMaxLength));
       
   248 	pos+=len;
       
   249 	if (len<aMaxLength)
       
   250 		iBuf.iExt=pos; // end-of-file encountered
       
   251 	SetPos(ERead,pos);
       
   252 	return len;
       
   253 	}
       
   254 
       
   255 void HDbsBuf::IpcWriteL(const TAny* aPtr,TInt aLength)
       
   256 //
       
   257 // Write to the server at the current write position.
       
   258 //
       
   259 	{
       
   260 	__ASSERT(aLength>=0);
       
   261 	if (aLength==0)
       
   262 		return;
       
   263 //
       
   264 	TPtrC8 ptr((TUint8*)aPtr,aLength);
       
   265 	TInt ext=iBuf.iExt;
       
   266 	iBuf.iExt=-1;
       
   267 	TInt pos=Pos(EWrite);
       
   268 	iIpc.SendReceiveL(EDbsStreamWrite,TIpcArgs(pos,&ptr));
       
   269 	pos+=aLength;
       
   270 	if (ext>=0&&pos>ext)
       
   271 		iBuf.iExt=pos;
       
   272 	SetPos(EWrite,pos);
       
   273 	}
       
   274 
       
   275 TInt HDbsBuf::EndL()
       
   276 //
       
   277 // Determine the end of the stream
       
   278 //
       
   279 	{
       
   280 	TInt ext=iBuf.iExt;
       
   281 	if (ext<0)
       
   282 		iBuf.iExt=ext=iIpc.SendReceiveL(EDbsStreamSize);
       
   283 	return Max(ext,Mark(EWrite));
       
   284 	}
       
   285 
       
   286 // Class HDbsReadBuf
       
   287 
       
   288 inline HDbsReadBuf::HDbsReadBuf(const TDesC8& aDes)
       
   289 	{
       
   290 	TUint8* ptr=CONST_CAST(TUint8*,aDes.Ptr());
       
   291 	Set(ptr,ptr+aDes.Length(),ERead);
       
   292 	}
       
   293 
       
   294 HDbsReadBuf* HDbsReadBuf::NewL(const TDesC8& aDes)
       
   295 	{
       
   296 	return new(ELeave) HDbsReadBuf(aDes);
       
   297 	}
       
   298 
       
   299 void HDbsReadBuf::DoRelease()
       
   300 	{
       
   301 	delete this;
       
   302 	}
       
   303 
       
   304 // Class HDbsStream
       
   305 TInt HDbsStream::ReadL(const RMessage2& aMessage)
       
   306 	{
       
   307 	TInt pos=aMessage.Int0();
       
   308 	if (pos!=iRPos)
       
   309 		iHost.SeekL(iHost.ERead,EStreamBeginning,pos);
       
   310 	iRPos=-1;
       
   311 	TInt len=aMessage.Int2();
       
   312 	pos+=len;
       
   313 	TInt tfr=len;
       
   314 	for (;;)
       
   315 		{
       
   316 		TUint8 buf[KDbsStreamIoSize];
       
   317 		TInt read=iHost.ReadL(buf,Min(tfr,KDbsStreamIoSize));
       
   318 		if (read==0)
       
   319 			break;
       
   320 		aMessage.WriteL(1,TPtrC8(buf,read),len-tfr);
       
   321 		tfr-=read;
       
   322 		if (tfr==0)
       
   323 			break;
       
   324 		if (read<KDbsStreamIoSize)
       
   325 			break;
       
   326 		}
       
   327 	iRPos=pos-tfr;
       
   328 	return len-tfr;
       
   329 	}
       
   330 
       
   331 void HDbsStream::WriteL(const RMessage2& aMessage)
       
   332 	{
       
   333 	TInt pos=aMessage.Int0();
       
   334 	if (pos!=iWPos)
       
   335 		iHost.SeekL(iHost.EWrite,EStreamBeginning,pos);
       
   336 	iWPos=-1;
       
   337 	TInt offset=0;
       
   338 	TBuf8<KDbsStreamIoSize> buf;
       
   339 	for (;;)
       
   340 		{
       
   341 		aMessage.ReadL(1,buf,offset);
       
   342 		TInt len=buf.Length();
       
   343 		if (len==0)
       
   344 			break;
       
   345 		iHost.WriteL(buf.Ptr(),len);
       
   346 		offset+=len;
       
   347 		if (len<KDbsStreamIoSize)
       
   348 			break;
       
   349 		}
       
   350 	iWPos=pos+offset;
       
   351 	}
       
   352 
       
   353 // Class HBufBuf
       
   354 
       
   355 void HBufBuf::DoRelease()
       
   356 	{
       
   357 	delete this;
       
   358 	}
       
   359 
       
   360 HBufBuf* HBufBuf::NewLC()
       
   361 	{
       
   362 	HBufBuf* self=new(ELeave) HBufBuf;
       
   363 	self->PushL();
       
   364 	self->iBuf=CBufSeg::NewL(EGranularity);
       
   365 	self->Set(*self->iBuf,0,ERead|EWrite);
       
   366 	return self;
       
   367 	}
       
   368