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