os/persistentdata/persistentstorage/store/USTRM/US_FRAME.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
//
sl@0
    15
sl@0
    16
#include "US_STD.H"
sl@0
    17
sl@0
    18
TInt RFrame16Buf::Offset(TStreamPos aBase,TStreamPos aPos)
sl@0
    19
	{
sl@0
    20
	TInt off=aPos-aBase;
sl@0
    21
	__ASSERT_DEBUG(off>=0,Panic(EStreamPosInvalid));
sl@0
    22
	TInt n=off/(KFrameFullLength16+KSizeFrameDes16);
sl@0
    23
		// number of full frames from base
sl@0
    24
	off-=n<<KShiftFrameDes16;
sl@0
    25
		// target offset in frame coordinates
sl@0
    26
	TInt over=off-(n<<KShiftFrameLength16)-KFrameFullLength16;
sl@0
    27
		// adjust for overshoot into the frame descriptor
sl@0
    28
	__ASSERT_DEBUG(over>=-KFrameFullLength16&&over<TInt(KSizeFrameDes16),User::Invariant());
sl@0
    29
	if (over>0)
sl@0
    30
		off-=over;
sl@0
    31
	return off;
sl@0
    32
	}
sl@0
    33
sl@0
    34
TStreamPos RFrame16Buf::Position(TStreamPos aBase,TInt anOffset)
sl@0
    35
	{
sl@0
    36
	return aBase+(anOffset+(anOffset>>KShiftFrameLength16<<KShiftFrameDes16));
sl@0
    37
	}
sl@0
    38
sl@0
    39
RFrame16Buf::RFrame16Buf(TStreamPos aBase)
sl@0
    40
	: iBase(aBase),iHost(NULL),iExt(KFrameNonexistent16)
sl@0
    41
	{
sl@0
    42
	__ASSERT_DEBUG(aBase>=KStreamBeginning+KSizeFrameDes16,Panic(EStreamPosInvalid));
sl@0
    43
	}
sl@0
    44
sl@0
    45
TInt RFrame16Buf::ExtendL(TStreamExchange& aHost,TInt anExtent,TInt aMode)
sl@0
    46
	{
sl@0
    47
	__ASSERT_DEBUG(anExtent>=0,Panic(EStreamExtentNegative));
sl@0
    48
	__ASSERT_DEBUG((KMaskFrameType16&aMode)!=EFrameContinuation16,Panic(EStreamTypeInvalid));
sl@0
    49
	TFrameDes16 des[2]={0,TFrameDes16(KMaskFrameType16&aMode|KFrameOpen16)};
sl@0
    50
	TUint8* ptr=(TUint8*)&des[1];
sl@0
    51
	TInt len=KSizeFrameDes16;
sl@0
    52
	TStreamPos pos=Position(anExtent);
sl@0
    53
	TInt off=anExtent;
sl@0
    54
	anExtent&=KMaskFrameLength16;
sl@0
    55
	if (anExtent==0)
sl@0
    56
		pos-=KSizeFrameDes16;
sl@0
    57
	else
sl@0
    58
		{
sl@0
    59
		anExtent=KFrameFullLength16-anExtent;
sl@0
    60
		if (anExtent>KSizeFrameDes16)
sl@0
    61
			off+=KSizeFrameDes16;
sl@0
    62
		else
sl@0
    63
			{
sl@0
    64
			ptr-=anExtent;
sl@0
    65
			len+=anExtent;
sl@0
    66
			off+=anExtent;
sl@0
    67
			}
sl@0
    68
		}
sl@0
    69
//
sl@0
    70
	TStreamMark mark(pos);
sl@0
    71
	mark.WriteL(aHost,ptr,len); // platform dependency
sl@0
    72
	mark.Withdraw(aHost);
sl@0
    73
	Set(aHost,off,0,aMode);
sl@0
    74
	return off;
sl@0
    75
	}
sl@0
    76
sl@0
    77
void RFrame16Buf::OpenL(TStreamExchange& aHost,TInt anOffset,TInt aMode)
sl@0
    78
	{
sl@0
    79
	__ASSERT_DEBUG(anOffset>=0,Panic(EStreamOffsetNegative));
sl@0
    80
	__ASSERT_DEBUG((KMaskFrameType16&aMode)!=EFrameContinuation16,Panic(EStreamTypeInvalid));
sl@0
    81
	TStreamMark mark(Position(anOffset)-KSizeFrameDes16);
sl@0
    82
	TFrameDes16 des;
sl@0
    83
	TInt frame=mark.ReadL(aHost,&des,KSizeFrameDes16);
sl@0
    84
		// platform dependency
sl@0
    85
	mark.Withdraw(aHost);
sl@0
    86
	__ASSERT_DEBUG(frame>=0&&frame<=KSizeFrameDes16,Panic(EStreamReadInBreach));
sl@0
    87
	if (frame<KSizeFrameDes16)
sl@0
    88
		__LEAVE(KErrEof);
sl@0
    89
//
sl@0
    90
	frame=des;
sl@0
    91
	if ((frame^aMode)&KMaskFrameType16)
sl@0
    92
		__LEAVE(KErrCorrupt);
sl@0
    93
//
sl@0
    94
	TInt in=anOffset&KMaskFrameLength16;
sl@0
    95
	frame&=KMaskFrameLength16;
sl@0
    96
	if (frame==KFrameOpen16)
sl@0
    97
		frame=KFrameFullLength16-in;
sl@0
    98
	if (in+frame>KFrameFullLength16)
sl@0
    99
		__LEAVE(KErrCorrupt);
sl@0
   100
//
sl@0
   101
	Set(aHost,anOffset,anOffset+frame,aMode);
sl@0
   102
	}
sl@0
   103
sl@0
   104
void RFrame16Buf::Set(TStreamExchange& aHost,TInt anOffset,TInt anExtent,TInt aMode)
sl@0
   105
	{
sl@0
   106
	__ASSERT_DEBUG(anOffset>=0||anOffset==anExtent,Panic(EStreamOffsetNegative));
sl@0
   107
	__ASSERT_DEBUG(anExtent>=0||anOffset==anExtent,Panic(EStreamExtentNegative));
sl@0
   108
	iHost=&aHost;
sl@0
   109
	iOff=anOffset;
sl@0
   110
	iExt=anExtent;
sl@0
   111
	TInt lim;
sl@0
   112
	if (anOffset<0)
sl@0
   113
		lim=anExtent;
sl@0
   114
	else
sl@0
   115
		{
sl@0
   116
		TStreamPos start=Position(anOffset);
sl@0
   117
		if (aMode&ERead)
sl@0
   118
			iRMark=start;
sl@0
   119
		else
sl@0
   120
			iRMark.Clear();
sl@0
   121
		if (aMode&EWrite)
sl@0
   122
			iWMark=start;
sl@0
   123
		else
sl@0
   124
			iWMark.Clear();
sl@0
   125
		lim=(anOffset&~KMaskFrameLength16)+KFrameFullLength16;
sl@0
   126
		if (anExtent>0&&lim>anExtent)
sl@0
   127
			lim=anExtent;
sl@0
   128
		}
sl@0
   129
	iRAvail=iWAvail=lim-anOffset;
sl@0
   130
	iRLim=iWLim=lim;
sl@0
   131
	iMode=aMode;
sl@0
   132
	}
sl@0
   133
sl@0
   134
void RFrame16Buf::CommitL()
sl@0
   135
	{
sl@0
   136
	__ASSERT_DEBUG(!IsCommitted(),Panic(EStreamCommitted));
sl@0
   137
	TInt ext=Host().SizeL()-Base().Offset();
sl@0
   138
	if (ext<0)
sl@0
   139
		__LEAVE(KErrCorrupt);
sl@0
   140
//
sl@0
   141
	TInt n=ext/(KFrameFullLength16+KSizeFrameDes16);
sl@0
   142
		// number of full frames from base
sl@0
   143
	ext-=n<<KShiftFrameDes16;
sl@0
   144
		// end in frame coordinates
sl@0
   145
	TInt off=Offset();
sl@0
   146
	if (ext==off)
sl@0
   147
		{ // committing an empty stream
sl@0
   148
		iOff=iExt=KFrameNonexistent16;
sl@0
   149
		return;
sl@0
   150
		}
sl@0
   151
//
sl@0
   152
	TInt frame=ext-(n<<KShiftFrameLength16);
sl@0
   153
		// size of final frame (remainder of the division above)
sl@0
   154
	__ASSERT_DEBUG(frame>=0&&frame<KFrameFullLength16+KSizeFrameDes16,User::Invariant());
sl@0
   155
	if (ext<off||frame==0||frame>KFrameFullLength16)
sl@0
   156
		__LEAVE(KErrCorrupt); // bad offset, empty frame or partial frame descriptor
sl@0
   157
//
sl@0
   158
	if (frame<KFrameFullLength16)
sl@0
   159
		{
sl@0
   160
		TFrameDes16 des;
sl@0
   161
		if ((off^ext)&~KMaskFrameLength16)
sl@0
   162
			{ // in a different frame from the one we started in
sl@0
   163
			off=ext&~KMaskFrameLength16;
sl@0
   164
			des=TFrameDes16(EFrameContinuation16|frame);
sl@0
   165
			}
sl@0
   166
		else
sl@0
   167
			{
sl@0
   168
			frame-=off&KMaskFrameLength16;
sl@0
   169
			__ASSERT_DEBUG(frame>0&&frame<KFrameFullLength16,User::Invariant());
sl@0
   170
			des=TFrameDes16(iMode&KMaskFrameType16|frame);
sl@0
   171
			}
sl@0
   172
		TStreamMark mark(Position(off)-KSizeFrameDes16);
sl@0
   173
		mark.WriteL(Host(),&des,KSizeFrameDes16);
sl@0
   174
		mark.Withdraw(Host());
sl@0
   175
		}
sl@0
   176
	iExt=ext;
sl@0
   177
	}
sl@0
   178
sl@0
   179
void RFrame16Buf::DoRelease()
sl@0
   180
	{
sl@0
   181
	if (iHost!=NULL)
sl@0
   182
		{
sl@0
   183
		iRMark.Withdraw(*iHost);
sl@0
   184
		iWMark.Withdraw(*iHost);
sl@0
   185
		iHost=NULL;
sl@0
   186
		iExt=KFrameNonexistent16;
sl@0
   187
		}
sl@0
   188
	}
sl@0
   189
sl@0
   190
void RFrame16Buf::DoSynchL()
sl@0
   191
	{
sl@0
   192
	if (IsCommitted())
sl@0
   193
		return;
sl@0
   194
//
sl@0
   195
	CommitL();
sl@0
   196
	}
sl@0
   197
sl@0
   198
TInt RFrame16Buf::DoReadL(TAny* aPtr,TInt aMaxLength)
sl@0
   199
	{
sl@0
   200
	__ASSERT_DEBUG(aMaxLength>=0,Panic(EStreamReadLengthNegative));
sl@0
   201
	__ASSERT_DEBUG(aMaxLength>0,Panic(EStreamReadNoTransfer));
sl@0
   202
	TInt left=aMaxLength;
sl@0
   203
	TInt avail=iRAvail;
sl@0
   204
	if (avail==0)
sl@0
   205
		goto underflow; // we'd used up the whole frame
sl@0
   206
//
sl@0
   207
	do
sl@0
   208
		{
sl@0
   209
		__ASSERT_DEBUG(left>0&&avail>0,User::Invariant());
sl@0
   210
		{
sl@0
   211
		TInt len=iRMark.ReadL(Host(),aPtr,Min(left,avail));
sl@0
   212
		__ASSERT_DEBUG(len>=0&&len<=left&&len<=avail,Panic(EStreamReadInBreach));
sl@0
   213
		iRAvail=avail-=len;
sl@0
   214
		left-=len;
sl@0
   215
		if (left==0)
sl@0
   216
			return aMaxLength; // that's it
sl@0
   217
//
sl@0
   218
		aPtr=(TUint8*)aPtr+len;
sl@0
   219
		}
sl@0
   220
		if (avail>0)
sl@0
   221
			{ // we've run out of host 
sl@0
   222
			if ((Extent()&KMaskFrameLength16)==KFrameOpen16)
sl@0
   223
				break; // all's well, provided we're open-ended
sl@0
   224
//
sl@0
   225
			iRMark.Withdraw(Host());
sl@0
   226
			__LEAVE(KErrCorrupt);
sl@0
   227
			}
sl@0
   228
//
sl@0
   229
	underflow:
sl@0
   230
		avail=UnderflowL();
sl@0
   231
		} while (avail>0);
sl@0
   232
	return aMaxLength-left;
sl@0
   233
	}
sl@0
   234
sl@0
   235
TInt RFrame16Buf::DoReadL(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
sl@0
   236
//
sl@0
   237
// Read up to aMaxLength bytes asynchronously.
sl@0
   238
//
sl@0
   239
	{
sl@0
   240
//#pragma message( __FILE__ " : 'RFrame16Buf::DoReadL(TDes8&,TInt,TRequestStatus&)' not implemented" )
sl@0
   241
	__ASSERT_DEBUG(aMaxLength<=aDes.MaxLength(),Panic(EStreamReadBeyondEnd));
sl@0
   242
	aDes.SetLength(DoReadL((TUint8*)aDes.Ptr(),aMaxLength));
sl@0
   243
	TRequestStatus* stat=&aStatus;
sl@0
   244
	User::RequestComplete(stat,KErrNone);
sl@0
   245
	return aMaxLength;
sl@0
   246
	}
sl@0
   247
sl@0
   248
TStreamTransfer RFrame16Buf::DoReadL(MStreamInput& anInput,TStreamTransfer aTransfer)
sl@0
   249
	{
sl@0
   250
	__ASSERT_DEBUG(aTransfer>0,Panic(EStreamReadNoTransfer));
sl@0
   251
	if (iRAvail>0)
sl@0
   252
		{
sl@0
   253
		TInt len=iRMark.ReadL(Host(),anInput,aTransfer[iRAvail]);
sl@0
   254
		aTransfer-=len;
sl@0
   255
		iRAvail-=len;
sl@0
   256
		}
sl@0
   257
	if (aTransfer>0)
sl@0
   258
		return anInput.ReadFromL(*this,aTransfer);
sl@0
   259
//
sl@0
   260
	return aTransfer;
sl@0
   261
	}
sl@0
   262
sl@0
   263
void RFrame16Buf::DoWriteL(const TAny* aPtr,TInt aLength)
sl@0
   264
	{
sl@0
   265
	__ASSERT_DEBUG(aLength>=0,Panic(EStreamWriteLengthNegative));
sl@0
   266
	__ASSERT_DEBUG(aLength>0,Panic(EStreamWriteNoTransfer));
sl@0
   267
	TInt avail=iWAvail;
sl@0
   268
	if (avail==0)
sl@0
   269
		goto overflow; // we'd used up the whole frame
sl@0
   270
//
sl@0
   271
	for (;;)
sl@0
   272
		{
sl@0
   273
		__ASSERT_DEBUG(aLength>0&&avail>0,User::Invariant());
sl@0
   274
		{
sl@0
   275
		TInt len=Min(aLength,avail);
sl@0
   276
		iWMark.WriteL(Host(),aPtr,len);
sl@0
   277
		iWAvail=avail-len;
sl@0
   278
		aLength-=len;
sl@0
   279
		if (aLength==0)
sl@0
   280
			return; // won't worry about the next frame just yet
sl@0
   281
//
sl@0
   282
		aPtr=(TUint8*)aPtr+len;
sl@0
   283
		}
sl@0
   284
	overflow:
sl@0
   285
		OverflowL();
sl@0
   286
		avail=iWAvail;
sl@0
   287
		};
sl@0
   288
	}
sl@0
   289
sl@0
   290
TInt RFrame16Buf::DoWriteL(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
sl@0
   291
//
sl@0
   292
// Write up to aMaxLength bytes asynchronously.
sl@0
   293
//
sl@0
   294
	{
sl@0
   295
//#pragma message( __FILE__ " : 'RFrame16Buf::DoWriteL(const TDesC8&,TInt,TRequestStatus&)' not implemented" )
sl@0
   296
	__ASSERT_DEBUG(aMaxLength<=aDes.Length(),Panic(EStreamWriteBeyondEnd));
sl@0
   297
	DoWriteL(aDes.Ptr(),aMaxLength);
sl@0
   298
	TRequestStatus* stat=&aStatus;
sl@0
   299
	User::RequestComplete(stat,KErrNone);
sl@0
   300
	return aMaxLength;
sl@0
   301
	}
sl@0
   302
sl@0
   303
TStreamTransfer RFrame16Buf::DoWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer)
sl@0
   304
	{
sl@0
   305
	__ASSERT_DEBUG(aTransfer>0,Panic(EStreamWriteNoTransfer));
sl@0
   306
	if (iWAvail>0)
sl@0
   307
		{
sl@0
   308
		TInt len=iWMark.WriteL(Host(),anOutput,aTransfer[iWAvail]);
sl@0
   309
		aTransfer-=len;
sl@0
   310
		iWAvail-=len;
sl@0
   311
		}
sl@0
   312
	if (aTransfer>0)
sl@0
   313
		return anOutput.WriteToL(*this,aTransfer);
sl@0
   314
//
sl@0
   315
	return aTransfer;
sl@0
   316
	}
sl@0
   317
sl@0
   318
TStreamPos RFrame16Buf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset)
sl@0
   319
//
sl@0
   320
// Position the mark(s) indicated by aMark at anOffset from aLocation.
sl@0
   321
//
sl@0
   322
	{
sl@0
   323
	switch (aLocation)
sl@0
   324
		{
sl@0
   325
	case EStreamBeginning:
sl@0
   326
		anOffset+=Offset();
sl@0
   327
		break;
sl@0
   328
	case EStreamMark:
sl@0
   329
		if (aMark==ERead)
sl@0
   330
			anOffset+=iRLim-iRAvail;
sl@0
   331
		else
sl@0
   332
			{
sl@0
   333
			__ASSERT_ALWAYS(aMark==EWrite,Panic(EStreamMarkInvalid));
sl@0
   334
			anOffset+=iWLim-iWAvail;
sl@0
   335
			}
sl@0
   336
		break;
sl@0
   337
	case EStreamEnd:
sl@0
   338
		anOffset+=EndL();
sl@0
   339
		break;
sl@0
   340
	default:
sl@0
   341
		Panic(EStreamLocationInvalid);
sl@0
   342
		break;
sl@0
   343
		}
sl@0
   344
	TInt r=KErrNone;
sl@0
   345
	if (anOffset<Offset())
sl@0
   346
		{
sl@0
   347
		anOffset=Offset();
sl@0
   348
		r=KErrEof;
sl@0
   349
		}
sl@0
   350
	else if (anOffset>=0&&!ReachL(anOffset))
sl@0
   351
		{
sl@0
   352
		__ASSERT_DEBUG(Extent()!=0,User::Invariant());
sl@0
   353
		anOffset=Extent();
sl@0
   354
		r=KErrEof;
sl@0
   355
		}
sl@0
   356
//
sl@0
   357
	if (aMark&&anOffset>=0)
sl@0
   358
		{
sl@0
   359
		__ASSERT_ALWAYS(!(aMark&~(ERead|EWrite)),Panic(EStreamMarkInvalid));
sl@0
   360
		TInt in=anOffset&KMaskFrameLength16;
sl@0
   361
		TInt off=anOffset-in;
sl@0
   362
		__ASSERT_DEBUG(Extent()==0||anOffset<=Extent(),User::Invariant());
sl@0
   363
		if (in==0&&off>Offset()&&(Extent()==0||off==Extent()))
sl@0
   364
			{ // positioning at the start of a frame that may not exist
sl@0
   365
			in=KFrameFullLength16;
sl@0
   366
			off-=in;
sl@0
   367
			}
sl@0
   368
		TStreamPos pos=Base()+(off+(off>>KShiftFrameLength16<<KShiftFrameDes16))+in;
sl@0
   369
		TInt lim=off+KFrameFullLength16;
sl@0
   370
		if (Extent()>0&&lim>Extent())
sl@0
   371
			lim=Extent();
sl@0
   372
		TInt left=lim-anOffset;
sl@0
   373
		__ASSERT_DEBUG(left>=0&&left<=KFrameFullLength16,User::Invariant());
sl@0
   374
//
sl@0
   375
		if (aMark&ERead)
sl@0
   376
			{
sl@0
   377
			if (iMode&ERead)
sl@0
   378
				iRMark.SeekL(Host(),pos);
sl@0
   379
			iRAvail=left;
sl@0
   380
			iRLim=lim;
sl@0
   381
			}
sl@0
   382
		if (aMark&EWrite)
sl@0
   383
			{
sl@0
   384
			if (iMode&EWrite)
sl@0
   385
				iWMark.SeekL(Host(),pos);
sl@0
   386
			iWAvail=left;
sl@0
   387
			iWLim=lim;
sl@0
   388
			}
sl@0
   389
		}
sl@0
   390
	__LEAVE_IF_ERROR(r);
sl@0
   391
	return TStreamPos(anOffset-Offset());
sl@0
   392
	}
sl@0
   393
sl@0
   394
TInt RFrame16Buf::UnderflowL()
sl@0
   395
	{
sl@0
   396
	__ASSERT_DEBUG(iRAvail==0,User::Invariant());
sl@0
   397
	if ((iRLim&KMaskFrameLength16)!=KFrameOpen16)
sl@0
   398
		{
sl@0
   399
		__ASSERT_DEBUG(iExt==iRLim,User::Invariant());
sl@0
   400
		return 0; // we've used up the closing, partial frame
sl@0
   401
		}
sl@0
   402
//
sl@0
   403
	__ASSERT_DEBUG(iRLim>0&&(iExt>0&&iRLim<=iExt||iExt==0),User::Invariant());
sl@0
   404
		// let's see if there's a continuation frame
sl@0
   405
	TFrameDes16 des;
sl@0
   406
	TInt frame=iRMark.ReadL(Host(),&des,KSizeFrameDes16);
sl@0
   407
		// platform dependency
sl@0
   408
	__ASSERT_DEBUG(frame>=0&&frame<=KSizeFrameDes16,Panic(EStreamReadInBreach));
sl@0
   409
	if (frame==KSizeFrameDes16)
sl@0
   410
		{
sl@0
   411
		frame=des;
sl@0
   412
		if ((frame&KMaskFrameType16)==EFrameContinuation16)
sl@0
   413
			{ // we have a continuation frame, prepare ourselves for it
sl@0
   414
			frame&=KMaskFrameLength16;
sl@0
   415
			if (frame==KFrameOpen16)
sl@0
   416
				frame=KFrameFullLength16;
sl@0
   417
			iRAvail=frame;
sl@0
   418
			TInt lim=iRLim;
sl@0
   419
			iRLim=lim+frame;
sl@0
   420
			if (iExt==lim)
sl@0
   421
				iExt=iRLim;
sl@0
   422
			return frame;
sl@0
   423
			}
sl@0
   424
		iRMark.SeekL(Host(),-KSizeFrameDes16);
sl@0
   425
		frame=0;
sl@0
   426
		}
sl@0
   427
//
sl@0
   428
	if (frame>0||iRLim<iExt)
sl@0
   429
		{ // we'd definitely seen a continuation frame here before
sl@0
   430
		iRMark.Withdraw(Host());
sl@0
   431
		__LEAVE(KErrCorrupt);
sl@0
   432
		}
sl@0
   433
	return 0;
sl@0
   434
	}
sl@0
   435
sl@0
   436
void RFrame16Buf::OverflowL()
sl@0
   437
	{
sl@0
   438
	__ASSERT_DEBUG(iWAvail==0,User::Invariant());
sl@0
   439
	if ((iWLim&KMaskFrameLength16)!=KFrameOpen16)
sl@0
   440
		{ // filled the closing, partial frame
sl@0
   441
		__ASSERT_DEBUG(iExt==iWLim,User::Invariant());
sl@0
   442
	overflow:
sl@0
   443
		iWMark.Withdraw(Host());
sl@0
   444
		__LEAVE(KErrOverflow);
sl@0
   445
		}
sl@0
   446
//
sl@0
   447
	__ASSERT_DEBUG(iWLim>0&&(iExt>0&&iWLim<=iExt||iExt==0),User::Invariant());
sl@0
   448
	if (iWLim==iExt)
sl@0
   449
		{ // let's see if this carries on
sl@0
   450
		TFrameDes16 des;
sl@0
   451
		TInt frame=iWMark.ReadL(Host(),&des,KSizeFrameDes16);
sl@0
   452
			// platform dependency
sl@0
   453
		__ASSERT_DEBUG(frame>=0&&frame<=KSizeFrameDes16,Panic(EStreamReadInBreach));
sl@0
   454
		if (frame==0)
sl@0
   455
			iExt=0; // end-of-host, let's start extending
sl@0
   456
		else
sl@0
   457
			{
sl@0
   458
			if (frame==KSizeFrameDes16)
sl@0
   459
				{
sl@0
   460
				frame=des;
sl@0
   461
				if ((frame&KMaskFrameType16)==EFrameContinuation16)
sl@0
   462
					{ // there's more, set up for the next frame
sl@0
   463
					frame&=KMaskFrameLength16;
sl@0
   464
					if (frame==KFrameOpen16)
sl@0
   465
						frame=KFrameFullLength16;
sl@0
   466
					iWAvail=frame;
sl@0
   467
					iExt=iWLim+=frame;
sl@0
   468
					return;
sl@0
   469
					}
sl@0
   470
				goto overflow;
sl@0
   471
				}
sl@0
   472
//
sl@0
   473
			iWMark.Withdraw(Host());
sl@0
   474
			__LEAVE(KErrCorrupt);
sl@0
   475
			}
sl@0
   476
		}
sl@0
   477
//
sl@0
   478
	__ASSERT_DEBUG(iWLim<iExt||iExt==0,User::Invariant());
sl@0
   479
		// calculate the frame descriptor to be written
sl@0
   480
	TInt frame=iExt&KMaskFrameLength16;
sl@0
   481
	if (iWLim<iExt-frame)
sl@0
   482
		frame=KFrameOpen16;
sl@0
   483
	TFrameDes16 des=TFrameDes16(EFrameContinuation16|frame);
sl@0
   484
	if (frame==KFrameOpen16)
sl@0
   485
		frame=KFrameFullLength16;
sl@0
   486
	iWMark.WriteL(Host(),&des,KSizeFrameDes16);
sl@0
   487
		// platform dependency
sl@0
   488
	iWAvail=frame;
sl@0
   489
	iWLim+=frame;
sl@0
   490
	}
sl@0
   491
sl@0
   492
TBool RFrame16Buf::ReachL(TInt anOffset)
sl@0
   493
	{
sl@0
   494
	if (iExt<=0)
sl@0
   495
		return iExt==0;
sl@0
   496
//
sl@0
   497
	TStreamMark mark(Base());
sl@0
   498
	TInt frame=(iExt+(iExt>>KShiftFrameLength16<<KShiftFrameDes16))-KSizeFrameDes16;
sl@0
   499
	while (iExt<anOffset)
sl@0
   500
		{
sl@0
   501
		if ((iExt&KMaskFrameLength16)!=KFrameOpen16)
sl@0
   502
			{
sl@0
   503
			mark.Withdraw(Host());
sl@0
   504
			return EFalse;
sl@0
   505
			}
sl@0
   506
//
sl@0
   507
		TFrameDes16 des;
sl@0
   508
		mark.SeekL(Host(),EStreamMark,frame);
sl@0
   509
		frame=mark.ReadL(Host(),&des,KSizeFrameDes16);
sl@0
   510
			// platform dependency
sl@0
   511
		__ASSERT_DEBUG(frame>=0&&frame<=KSizeFrameDes16,Panic(EStreamReadInBreach));
sl@0
   512
		if (frame==KSizeFrameDes16)
sl@0
   513
			{
sl@0
   514
			frame=des;
sl@0
   515
			if ((frame&KMaskFrameType16)==EFrameContinuation16)
sl@0
   516
				{ // we have a continuation frame, boost upper
sl@0
   517
				frame&=KMaskFrameLength16;
sl@0
   518
				if (frame==KFrameOpen16)
sl@0
   519
					frame=KFrameFullLength16;
sl@0
   520
				iExt+=frame;
sl@0
   521
				continue;
sl@0
   522
				}
sl@0
   523
			frame=0;
sl@0
   524
			}
sl@0
   525
//
sl@0
   526
		mark.Withdraw(Host());
sl@0
   527
		if (frame>0)
sl@0
   528
			__LEAVE(KErrCorrupt);
sl@0
   529
//
sl@0
   530
		return EFalse;
sl@0
   531
		}
sl@0
   532
	mark.Withdraw(Host());
sl@0
   533
	return ETrue;
sl@0
   534
	}
sl@0
   535
sl@0
   536
TInt RFrame16Buf::EndL()
sl@0
   537
	{
sl@0
   538
	TInt ext=Host().SizeL()-Base().Offset();
sl@0
   539
	if (ext<0)
sl@0
   540
		__LEAVE(KErrCorrupt);
sl@0
   541
//
sl@0
   542
	TInt n=ext/(KFrameFullLength16+KSizeFrameDes16);
sl@0
   543
		// number of full frames from base
sl@0
   544
	ext-=n<<KShiftFrameDes16;
sl@0
   545
		// end in frame coordinates
sl@0
   546
	TInt frame=ext-(n<<KShiftFrameLength16);
sl@0
   547
		// size of final frame (remainder of the division above)
sl@0
   548
	__ASSERT_DEBUG(frame>=0&&frame<KFrameFullLength16+KSizeFrameDes16,User::Invariant());
sl@0
   549
	if (ext<Offset()||frame>KFrameFullLength16)
sl@0
   550
		__LEAVE(KErrCorrupt); // bad offset or partial frame descriptor
sl@0
   551
//
sl@0
   552
	if (!ReachL(ext))
sl@0
   553
		{
sl@0
   554
		__ASSERT_DEBUG(Extent()!=0,User::Invariant());
sl@0
   555
		return Extent();
sl@0
   556
		}
sl@0
   557
//
sl@0
   558
	return ext;
sl@0
   559
	}
sl@0
   560