persistentstorage/store/UMEM/UM_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 //
       
    15 
       
    16 #include "UM_STD.H"
       
    17 
       
    18 EXPORT_C TMemBuf::TMemBuf()
       
    19 	: iBase(NULL)
       
    20 /** Constructs an empty object.
       
    21 
       
    22 Call Set() before using the object. */
       
    23 	{}
       
    24 
       
    25 EXPORT_C void TMemBuf::Set(TUint8* aPtr,TUint8* anEnd,TInt aMode)
       
    26 /** Sets up the stream to use the specified area of plain memory.
       
    27 
       
    28 @param aPtr The start address for the area of plain memory that hosts the 
       
    29 stream and that also acts as the intermediate buffer.
       
    30 @param anEnd The end address for the area of plain memory that hosts the stream 
       
    31 and that also acts as the intermediate buffer. The addressed byte is outside 
       
    32 the memory area.
       
    33 @param aMode The mode in which the stream is to be used. It can be used in 
       
    34 either or both read and write modes, represented by ERead and EWrite.
       
    35 @see MStreamBuf::TRead
       
    36 @see MStreamBuf::TWrite */
       
    37 	{
       
    38 	if (aPtr==NULL && anEnd==NULL)
       
    39 		aPtr=anEnd=(TUint8*)this;	// treat null data as seekable zero-length data
       
    40 	iBase=aPtr;
       
    41 	SetBuf(ERead,(aMode&ERead)?aPtr:NULL,anEnd);
       
    42 	SetBuf(EWrite,(aMode&EWrite)?aPtr:NULL,anEnd);
       
    43 	}
       
    44 
       
    45 EXPORT_C TInt TMemBuf::UnderflowL(TInt)
       
    46 //
       
    47 // The read buffer is empty.
       
    48 //
       
    49 	{
       
    50 	return 0;
       
    51 	}
       
    52 
       
    53 EXPORT_C void TMemBuf::OverflowL()
       
    54 //
       
    55 // Ran out of write buffer.
       
    56 //
       
    57 	{
       
    58 	__LEAVE(KErrOverflow);
       
    59 	}
       
    60 
       
    61 EXPORT_C TStreamPos TMemBuf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset)
       
    62 //
       
    63 // Position the mark(s) indicated by aMark at anOffset from aLocation.
       
    64 //
       
    65 	{
       
    66 	TUint8* ptr=0;
       
    67 	switch (aLocation)
       
    68 		{
       
    69 	case EStreamBeginning:
       
    70 		ptr=Base()+anOffset;
       
    71 		break;
       
    72 	case EStreamMark:
       
    73 		ptr=Ptr(aMark)+anOffset;
       
    74 		break;
       
    75 	case EStreamEnd:
       
    76 		ptr=End()+anOffset;
       
    77 		break;
       
    78 	default:
       
    79 		Panic(EMemLocationInvalid);
       
    80 		break;
       
    81 		}
       
    82 	TInt r=KErrNone;
       
    83 	if (ptr>End())
       
    84 		{
       
    85 		ptr=End();
       
    86 		r=KErrEof;
       
    87 		}
       
    88 	else if (ptr<Base())
       
    89 		{
       
    90 		ptr=Base();
       
    91 		r=KErrEof;
       
    92 		}
       
    93 //
       
    94 	SetPtr(aMark,ptr);
       
    95 	__LEAVE_IF_ERROR(r);
       
    96 	return TStreamPos(ptr-Base());
       
    97 	}
       
    98 
       
    99 EXPORT_C TDesBuf::TDesBuf()
       
   100 	: iDes(NULL)
       
   101 /** Constructs an empty object.
       
   102 
       
   103 Call Set() before using the object. */
       
   104 	{}
       
   105 
       
   106 EXPORT_C void TDesBuf::Set(TDes8& aDes,TInt aMode)
       
   107 /** Sets up the stream to use the specified descriptor.
       
   108 
       
   109 @param aDes The descriptor that hosts the stream and that also acts as the 
       
   110 intermediate buffer.
       
   111 @param aMode The mode in which the buffer is to be used. It can be used in 
       
   112 either or both read and write modes, represented by ERead and EWrite.
       
   113 @see TDes8
       
   114 @see MStreamBuf::TRead
       
   115 @see MStreamBuf::TWrite */
       
   116 	{
       
   117 	iDes=&aDes;
       
   118 	TUint8* ptr=(TUint8*)aDes.Ptr();
       
   119 	SetBuf(ERead,(aMode&ERead)?ptr:NULL,ptr+aDes.Length());
       
   120 	SetBuf(EWrite,(aMode&EWrite)?ptr:NULL,ptr+aDes.MaxLength());
       
   121 	}
       
   122 
       
   123 EXPORT_C TInt TDesBuf::UnderflowL(TInt)
       
   124 //
       
   125 // Check if there's any more to be read.
       
   126 //
       
   127 	{
       
   128 	Consolidate();
       
   129 	return Avail(ERead);
       
   130 	}
       
   131 
       
   132 EXPORT_C void TDesBuf::OverflowL()
       
   133 //
       
   134 // Ran out of write buffer.
       
   135 //
       
   136 	{
       
   137 	__LEAVE(KErrOverflow);
       
   138 	}
       
   139 
       
   140 EXPORT_C void TDesBuf::DoSynchL()
       
   141 //
       
   142 // Synchronise descriptor and stream buffer.
       
   143 //
       
   144 	{
       
   145 	Consolidate();
       
   146 	}
       
   147 
       
   148 EXPORT_C TStreamPos TDesBuf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset)
       
   149 //
       
   150 // Position the mark(s) indicated by aMark at anOffset from aLocation.
       
   151 //
       
   152 	{
       
   153 	Consolidate();
       
   154 	TUint8* ptr=0;
       
   155 	switch (aLocation)
       
   156 		{
       
   157 	case EStreamBeginning:
       
   158 		ptr=Base()+anOffset;
       
   159 		break;
       
   160 	case EStreamMark:
       
   161 		ptr=Ptr(aMark)+anOffset;
       
   162 		break;
       
   163 	case EStreamEnd:
       
   164 		ptr=End(ERead)+anOffset;
       
   165 		break;
       
   166 	default:
       
   167 		Panic(EMemLocationInvalid);
       
   168 		break;
       
   169 		}
       
   170 	TInt r=KErrNone;
       
   171 	if (ptr>End(ERead))
       
   172 		{
       
   173 		ptr=End(ERead);
       
   174 		r=KErrEof;
       
   175 		}
       
   176 	else if (ptr<Base())
       
   177 		{
       
   178 		ptr=Base();
       
   179 		r=KErrEof;
       
   180 		}
       
   181 //
       
   182 	SetPtr(aMark,ptr);
       
   183 	__LEAVE_IF_ERROR(r);
       
   184 	return TStreamPos(ptr-Base());
       
   185 	}
       
   186 
       
   187 void TDesBuf::Consolidate()
       
   188 //
       
   189 // Update the descriptor's length as well as the read limit.
       
   190 //
       
   191 	{
       
   192 	TUint8* ptr=Ptr(EWrite);
       
   193 	if (ptr==NULL)
       
   194 		return;			// ERead only desbuf
       
   195 	TUint8* base=Base();
       
   196 	TInt len=Max(Des().Length(),ptr-base);
       
   197 	Des().SetLength(len);
       
   198 	SetEnd(ERead,base+len);
       
   199 	}
       
   200 
       
   201 EXPORT_C TBufBuf::TBufBuf()
       
   202 	: iBuf(NULL)
       
   203 /** Constructs an empty object.
       
   204 
       
   205 Call Set() before using the object. */
       
   206 	{}
       
   207 
       
   208 EXPORT_C void TBufBuf::Set(CBufBase& aBuf,TInt aPos,TInt aMode)
       
   209 /** Sets up the stream to use the specified dynamic buffer.
       
   210 
       
   211 @param aBuf The dynamic buffer that hosts the stream and that also acts as 
       
   212 the intermediate buffer.
       
   213 @param aPos The offset within the dynamic buffer where the stream starts.
       
   214 @param aMode The mode in which the stream is to be used. It can be used in 
       
   215 either or both read and write modes, represented by ERead and EWrite. In addition, 
       
   216 specify TBufBuf::EInsert to imply insert mode; specify TBufBuf::ETruncate 
       
   217 to imply truncate mode. If neither TBufBuf::EInsert nor TBufBuf::ETruncate 
       
   218 are specified, then overwrite mode is implied. Both TBufBuf::EInsert and TBufBuf::ETruncate 
       
   219 imply EWrite.
       
   220 @see CBufBase
       
   221 @see MStreamBuf::TRead
       
   222 @see MStreamBuf::TWrite */
       
   223 	{
       
   224 	iBuf=&aBuf;
       
   225 	SetPos(ERead|EWrite,aPos);
       
   226 	if (aMode&(ETruncate|EInsert))
       
   227 		aMode|=EWrite; // truncate and insert imply write
       
   228 	iMode=aMode;
       
   229 	//Initialize base class data members.
       
   230 	//The first Read/Write call will reinitialize them with non NULL values.
       
   231 	TStreamBuf::SetBuf(iMode & (EWrite | ERead), NULL, NULL);
       
   232 	}
       
   233 
       
   234 EXPORT_C TInt TBufBuf::UnderflowL(TInt)
       
   235 //
       
   236 // Establish the buffer's read area.
       
   237 //
       
   238 	{
       
   239 	__ASSERT_ALWAYS(iMode&ERead,Panic(EMemCannotRead));
       
   240 	__ASSERT_DEBUG(Ptr(ERead)==End(ERead),User::Invariant());
       
   241 	TInt pos=Pos(ERead);
       
   242 	TPtr8 seg=Buf().Ptr(pos);
       
   243 	TUint8* ptr=(TUint8*)seg.Ptr();
       
   244 	TInt len=seg.Length();
       
   245 	if (iMode&ETruncate)
       
   246 		{
       
   247 		TInt left=Pos(EWrite)-pos;
       
   248 		__ASSERT_DEBUG(left>=0,User::Invariant());
       
   249 		if (left<len)
       
   250 			len=left;
       
   251 		}
       
   252 	SetBuf(ERead,ptr,ptr+len);
       
   253 	SetPos(ERead,pos+len);
       
   254 	return len;
       
   255 	}
       
   256 
       
   257 EXPORT_C void TBufBuf::OverflowL()
       
   258 //
       
   259 // Establish the buffer's write area.
       
   260 //
       
   261 	{
       
   262 	__ASSERT_ALWAYS(iMode&EWrite,Panic(EMemCannotWrite));
       
   263 	__ASSERT_DEBUG(Ptr(EWrite)==End(EWrite)&&Pos(EWrite)<Buf().Size(),User::Invariant());
       
   264 	TInt pos=Pos(EWrite);
       
   265 	TPtr8 seg=Buf().Ptr(pos);
       
   266 	TUint8* ptr=(TUint8*)seg.Ptr();
       
   267 	TInt len=seg.Length();
       
   268 	SetBuf(EWrite,ptr,ptr+len);
       
   269 	SetPos(EWrite,pos+len);
       
   270 	}
       
   271 
       
   272 EXPORT_C void TBufBuf::DoSynchL()
       
   273 //
       
   274 // Synchronise buffer and stream buffer and compress.
       
   275 //
       
   276 	{
       
   277 	Consolidate();
       
   278 	Buf().Compress();
       
   279 	}
       
   280 
       
   281 EXPORT_C void TBufBuf::DoWriteL(const TAny* aPtr,TInt aLength)
       
   282 //
       
   283 // Consume aLength bytes, taking care of any reallocation.
       
   284 //
       
   285 	{
       
   286 	__ASSERT_ALWAYS(iMode&EWrite,Panic(EMemCannotWrite));
       
   287 	__ASSERT_DEBUG(aLength>=0,Panic(EMemWriteLengthNegative));
       
   288 	__ASSERT_DEBUG(aLength>0,Panic(EMemWriteNoTransfer));
       
   289 	TInt len=(iMode&EInsert?0:Min(aLength,Buf().Size()-Mark(EWrite)));
       
   290 	if (len>0)
       
   291 		{
       
   292 		TStreamBuf::DoWriteL(aPtr,len);
       
   293 		aPtr=(TUint8*)aPtr+len;
       
   294 		aLength-=len;
       
   295 		}
       
   296 	if (aLength>0)
       
   297 		{
       
   298 		Consolidate();
       
   299 		TInt pos=Pos(EWrite);
       
   300 		Buf().InsertL(pos,aPtr,aLength);
       
   301 		if (Pos(ERead)>pos)
       
   302 			MovePos(ERead,aLength);
       
   303 		SetPos(EWrite,pos+aLength);
       
   304 		}
       
   305 	}
       
   306 
       
   307 EXPORT_C TStreamPos TBufBuf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset)
       
   308 //
       
   309 // Position the mark(s) indicated by aMark at anOffset from aLocation.
       
   310 //
       
   311 	{
       
   312 	Consolidate();
       
   313 	TInt size=Buf().Size();
       
   314 	switch (aLocation)
       
   315 		{
       
   316 	case EStreamBeginning:
       
   317 		break;
       
   318 	case EStreamMark:
       
   319 		anOffset+=Pos(aMark);
       
   320 		break;
       
   321 	case EStreamEnd:
       
   322 		anOffset+=size;
       
   323 		break;
       
   324 	default:
       
   325 		Panic(EMemLocationInvalid);
       
   326 		break;
       
   327 		}
       
   328 	TInt r=KErrNone;
       
   329 	if (anOffset>size)
       
   330 		{
       
   331 		anOffset=size;
       
   332 		r=KErrEof;
       
   333 		}
       
   334 	else if (anOffset<0)
       
   335 		{
       
   336 		anOffset=0;
       
   337 		r=KErrEof;
       
   338 		}
       
   339 //
       
   340 	SetPos(aMark,anOffset);
       
   341 	__LEAVE_IF_ERROR(r);
       
   342 	return TStreamPos(anOffset);
       
   343 	}
       
   344 
       
   345 void TBufBuf::Consolidate()
       
   346 //
       
   347 // Empty buffer areas and, in truncate mode, cut off at the current write position.
       
   348 //
       
   349 	{
       
   350 	MovePos(ERead,-Avail(ERead));
       
   351 	MovePos(EWrite,-Avail(EWrite));
       
   352 	SetBuf(ERead|EWrite,NULL,NULL);
       
   353 	if (iMode&ETruncate)
       
   354 		{
       
   355 		Buf().Delete(Pos(EWrite),Buf().Size()-Pos(EWrite));
       
   356 		iMode&=~ETruncate;
       
   357 		}
       
   358 	}
       
   359 
       
   360 void TBufBuf::SetPos(TMark aMark,TInt aPos)
       
   361 //
       
   362 // Set the buffer position for the mark(s) indicated by aMark
       
   363 //
       
   364 	{
       
   365 	__ASSERT_ALWAYS(!(aMark&~(ERead|EWrite)),Panic(EMemMarkInvalid));
       
   366 	if (aMark&ERead)
       
   367 		SetPos(ERead,aPos);
       
   368 	if (aMark&EWrite)
       
   369 		SetPos(EWrite,aPos);
       
   370 	}
       
   371 
       
   372 TInt TBufBuf::Pos(TMark aMark) const
       
   373 //
       
   374 // Return the buffer position for the mark indicated by aMark.
       
   375 //
       
   376 	{
       
   377 	if (aMark==ERead)
       
   378 		return Pos(ERead);
       
   379 //
       
   380 	__ASSERT_ALWAYS(aMark==EWrite,Panic(EMemMarkInvalid));
       
   381 	return Pos(EWrite);
       
   382 	}
       
   383