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