backupandrestore/backupengine/src/sbebufferhandler.cpp
changeset 0 d0791faffa3f
child 12 523717cdb0ad
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2004-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 // Implementation of CBufferFileWriter and CBufferReader
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 
       
    23 #include "sbebufferhandler.h"
       
    24 #include "sblog.h"
       
    25 #include <connect/panic.h>
       
    26 
       
    27 namespace conn
       
    28 	{
       
    29 	template<class T>
       
    30 	TBool ReadFromBufferF(T& aT, TUint8*& appCurrent, const TUint8* apEnd)
       
    31 	/** Template class to read flat structures from the buffer
       
    32 	
       
    33 	@param aT on return the flat structure.
       
    34 	@param appCurrent The current point into the buffer.
       
    35 	@param apEnd The end of the buffer.
       
    36 	@return ETrue if read succesfully. EFalse if a retry is needed.
       
    37 	*/
       
    38 		{
       
    39 		static TBuf8<sizeof(T)> SBuffer; // Static buffer used for buffering!
       
    40 		TBool ret = EFalse;
       
    41 		
       
    42 		// Is there anything already in the buffer?
       
    43 		TUint8* ptr = NULL;
       
    44 		if (SBuffer.Size() > 0)
       
    45 			{
       
    46 			TInt size = SBuffer.Size();
       
    47 			SBuffer.Append(appCurrent, sizeof(T) - size);
       
    48 			ptr = const_cast<TUint8*>(SBuffer.Ptr());
       
    49 			
       
    50 			appCurrent += sizeof(T) - size;
       
    51 			
       
    52 			ret = ETrue;
       
    53 			} // if
       
    54 		else
       
    55 			{
       
    56 			// Is there enough room in current
       
    57 			if ((apEnd - appCurrent) < static_cast<TInt>(sizeof(T)))
       
    58 				{
       
    59 				// Need to buffer
       
    60 				SBuffer.Copy(appCurrent, apEnd - appCurrent);
       
    61 				} // if
       
    62 			else
       
    63 				{
       
    64 				ptr = appCurrent;
       
    65 				appCurrent += sizeof(T);
       
    66 				ret = ETrue;
       
    67 				} // else
       
    68 			} // else
       
    69 			
       
    70 		if (ret)
       
    71 			{
       
    72 			// Use a loop to copy to avoid alignment issues
       
    73 			TUint8* ptrOut = reinterpret_cast<TUint8*>(&aT);
       
    74 			for (TUint x = 0; x < sizeof(T); x++)
       
    75 				{
       
    76 				*ptrOut++ = *ptr++;
       
    77 				} // for
       
    78 			
       
    79 			SBuffer.SetLength(0);
       
    80 			}
       
    81 			
       
    82 		return ret;
       
    83 		}
       
    84 
       
    85 	template TBool ReadFromBufferF<TFileFixedHeader>(TFileFixedHeader&, TUint8*&, const TUint8*);
       
    86 	template TBool ReadFromBufferF<TSnapshot>(TSnapshot&, TUint8*&, const TUint8*);
       
    87 	
       
    88 	template<class T>
       
    89 	TBool WriteToBufferF(T& aT, TPtr8& aPtr)
       
    90 	/** Writes flat structures to the buffer.
       
    91 	
       
    92 	NOTE: This should _ONLY_ be used to write T classes to the buffer.
       
    93 	
       
    94 	@param aT The flat structure to write to the buffer.
       
    95 	@param ptr The buffer to write to.
       
    96 	@return ETrue on success. EFalse on failure.
       
    97 	*/
       
    98 		{
       
    99 		TBool ret = EFalse;
       
   100 		
       
   101 		if ((aPtr.MaxSize() - aPtr.Size()) >= static_cast<TInt>(sizeof(T)))
       
   102 			{
       
   103 			aPtr.Append(reinterpret_cast<TUint8*>(&aT), sizeof(T));
       
   104 			ret = ETrue;
       
   105 			} // if
       
   106 		
       
   107 		return ret;
       
   108 		}
       
   109 		
       
   110 	TBool ReadFromBufferV(TPtr8& aT, TInt aSize, TUint8*& appCurrent, const TUint8* apEnd)
       
   111 	/** Reads from the buffer.
       
   112 	
       
   113 	@param aT on return the data read.
       
   114 	@param aSize size of the data to read.
       
   115 	@param appCurrent Pointer to read from.
       
   116 	@param apEnd the end of the data.
       
   117 	@return ETrue on success. EFalse on failure.
       
   118 	*/
       
   119 		{
       
   120 		TBool ret = EFalse;
       
   121 		
       
   122 		// Does into already contain data?
       
   123 		if (aT.Size() > 0)
       
   124 			{
       
   125 			TInt tocopy = aSize - aT.Size();
       
   126 			aT.Append(appCurrent, tocopy);
       
   127 			appCurrent += tocopy;
       
   128 			ret = ETrue;
       
   129 			} // if
       
   130 		else
       
   131 			{
       
   132 			// Is there enough data?
       
   133 			if ((apEnd - appCurrent) < aSize)
       
   134 				{
       
   135 				aT.Copy(appCurrent, apEnd - appCurrent);
       
   136 				appCurrent = const_cast<TUint8*>(apEnd);
       
   137 				} // if
       
   138 			else
       
   139 				{
       
   140 				aT.Copy(appCurrent, aSize);
       
   141 				appCurrent += aSize;
       
   142 				ret = ETrue;
       
   143 				} // else
       
   144 			} // else
       
   145 		
       
   146 		return ret;
       
   147 		}
       
   148 		
       
   149 	TBool WriteToBufferV(const TPtr8& aPtr, TInt aSize, TPtr8& aBuffer)
       
   150 	/** Writes some vairable data to the buffer.
       
   151 	
       
   152 	NOTE: This should _ONLY_ be used to write T classes to the buffer.
       
   153 	
       
   154 	@param aPtr buffer to read from.
       
   155 	@param aSize size of the data to write.
       
   156 	@param aBuffer the buffer to write to.
       
   157 	@return ETrue on success. EFalse on failure.
       
   158 	*/
       
   159 		{
       
   160 		TBool ret = EFalse;
       
   161 		
       
   162 		if ((aBuffer.MaxSize() - aBuffer.Size()) >= aSize)
       
   163 			{
       
   164 			aBuffer.Append(aPtr.Ptr(), aSize);
       
   165 			ret = ETrue;
       
   166 			} // if
       
   167 		
       
   168 		
       
   169 		return ret;
       
   170 		}
       
   171 		
       
   172 	CBufferFileWriter* CBufferFileWriter::NewL(RFs& aFs, CDesCArray* aFileNames)
       
   173 	/** Symbain constructor
       
   174 	
       
   175 	@param aFs Handle to the Symbian Fs file server
       
   176 	@param aFileNames list of files to write ownership transfer
       
   177 	@return a CBufferFileWriter.
       
   178 	*/
       
   179 		{
       
   180 		CBufferFileWriter* self = new(ELeave) CBufferFileWriter(aFs, aFileNames);
       
   181 		CleanupStack::PushL(self);
       
   182 		self->ConstructL();
       
   183 		CleanupStack::Pop(self);
       
   184 		
       
   185 		return self;
       
   186 		} // NewL
       
   187 		
       
   188 	CBufferFileWriter::CBufferFileWriter(RFs& aFs, CDesCArray* aFileNames) :
       
   189 		iFs(aFs), iFileNames(aFileNames)
       
   190 	/** Standard C++ constructor
       
   191 	
       
   192 	@param aFs an RFS to use in this class.
       
   193 	*/
       
   194 		{
       
   195 		} // CBufferFileWriter
       
   196 		
       
   197 	CBufferFileWriter::~CBufferFileWriter()
       
   198 	/** Standard C++ destructor
       
   199 	*/
       
   200 		{
       
   201 		delete iFileNames;
       
   202 		iFileHandle.Close();
       
   203 		}
       
   204 		
       
   205 	void CBufferFileWriter::ConstructL()
       
   206 	/** Symbain second phase constructor
       
   207 	
       
   208 	@param aFileNames list of files to write
       
   209 	*/
       
   210 		{
       
   211 		#if defined(SBE_LOGGING_ENABLED)
       
   212 		if (iFileNames)
       
   213 			{
       
   214 			TUint count = iFileNames->Count();
       
   215 			while(count--)
       
   216 				{
       
   217 				const TDesC& fileName = (*iFileNames)[count];
       
   218             	__LOG2("CBufferFileWriter::ConstructL() - file[%04d] is: %S", count, &fileName);
       
   219 				}
       
   220 			}
       
   221 		
       
   222 		#endif
       
   223 		}
       
   224 		
       
   225 	void CBufferFileWriter::StartL(TPtr8& aBuffer, TBool& aCompleted)
       
   226 	/** Start writing the files to the buffer
       
   227 	
       
   228 	@param aBuffer The buffer to write to.
       
   229 	@param aCompleted on return if we have finished.
       
   230 	*/
       
   231 		{
       
   232         __LOG("CBufferFileWriter::StartL() - START");
       
   233 		WriteToBufferL(aBuffer, aCompleted);
       
   234         __LOG("CBufferFileWriter::StartL() - END");
       
   235 		} // StartL
       
   236 		
       
   237 	void CBufferFileWriter::ContinueL(TPtr8& aBuffer, TBool& aCompleted)
       
   238 	/** Continue writing the files to the buffer
       
   239 	
       
   240 	@param aBuffer The buffer to write to.
       
   241 	@param aCompleted on return if we have finished.
       
   242 	*/
       
   243 		{
       
   244         __LOG("CBufferFileWriter::ContinueL() - START");
       
   245 		WriteToBufferL(aBuffer, aCompleted);
       
   246         __LOG("CBufferFileWriter::ContinueL() - END");
       
   247 		}
       
   248 
       
   249 	void CBufferFileWriter::WriteToBufferL(TPtr8& aBuffer, TBool& aCompleted)
       
   250 	/** Writes files to the buffer
       
   251 	
       
   252 	@param aBuffer The buffer to write to.
       
   253 	@param aCompleted on return if we have finished.
       
   254 	*/
       
   255 		{
       
   256 		aCompleted = EFalse;
       
   257 		
       
   258 		const TUint count = iFileNames->Count();
       
   259 		while (iCurrentFile < count)
       
   260 			{
       
   261             const TDesC& name = (*iFileNames)[iCurrentFile];
       
   262 			
       
   263 			_LIT( KTrailingBackSlash, "\\" );
       
   264             if (name.Right(1) == KTrailingBackSlash() )
       
   265             	{
       
   266              	// Directory entry
       
   267  	           	__LOG1("CBufferFileWriter::WriteToBufferL() - empty directory: %S ", &name);
       
   268  	           	if(!iHeaderWritten)
       
   269  	        	   {
       
   270  	        	   TFileFixedHeader header(name.Length(), 0, 0, 0);
       
   271  	        	   if (WriteToBufferF(header, aBuffer) == EFalse)
       
   272  	        		   {
       
   273  	        		   __LOG("CBufferFileReader::WriteToBufferL() - WriteToBufferF() returned False so breaking!");
       
   274  	        		   break;
       
   275  	        		   }
       
   276  	        	   iHeaderWritten = ETrue;
       
   277  	        	   } // if
       
   278  	           	
       
   279 				TPtr8 ptr(reinterpret_cast<TUint8*>(const_cast<TUint16*>(name.Ptr())), name.Size(), name.Size());
       
   280 				
       
   281 				if (WriteToBufferV(ptr, ptr.Size(), aBuffer) == EFalse)
       
   282 					{
       
   283 					__LOG("CBufferFileReader::WriteToBufferL() - WriteToBufferV() returned False so breaking!");
       
   284 					break;
       
   285 					}
       
   286 
       
   287  	           	iHeaderWritten = EFalse;
       
   288  	           	iFileNameWritten = EFalse;
       
   289             	}
       
   290             else
       
   291             	{
       
   292 				if (!iFileOpen) // File needs to be opened
       
   293 					{
       
   294 	                __LOG1("CBufferFileWriter::WriteToBufferL() - trying to open: %S for reading", &name);
       
   295 					const TInt error = iFileHandle.Open(iFs, name, EFileRead | EFileShareReadersOnly);
       
   296 	                if  (error != KErrNone)
       
   297 	                    {
       
   298 	                    __LOG2("CBufferFileWriter::WriteToBufferL() - opening: %S for reading failed with error: %d", &name, error);
       
   299 	                    User::Leave(error);
       
   300 	                    }
       
   301 
       
   302 					iFileOpen = ETrue;
       
   303 					} // if
       
   304 					
       
   305 				if (iFileOpen && !iHeaderWritten)
       
   306 					{
       
   307 					// File size
       
   308 					TInt size;
       
   309 					TInt err = iFileHandle.Size(size);
       
   310 	                __LOG2("CBufferFileWriter::WriteToBufferL() - size of file is: %d (err: %d)", size, err);
       
   311 					TUint att;
       
   312 					err = iFileHandle.Att(att);
       
   313 					__LOG2("CBufferFileWriter::WriteToBufferL() - attributes: %d (err: %d)", size, err);
       
   314 					TTime modified;
       
   315 					err = iFileHandle.Modified(modified);
       
   316 					__LOG2("CBufferFileWriter::WriteToBufferL() - modified: %d (err: %d)", size, err);
       
   317 					TFileFixedHeader header((*iFileNames)[iCurrentFile].Length(), size, att, modified.Int64());
       
   318 					if (WriteToBufferF(header, aBuffer) == EFalse)
       
   319 						{
       
   320 						__LOG("CBufferFileReader::WriteToBufferL() - WriteToBufferF() returned False so breaking!");
       
   321 						break;
       
   322 						}
       
   323 						
       
   324 					iHeaderWritten = ETrue;
       
   325 					} // if
       
   326 					
       
   327 				// Write filename
       
   328 				if (!iFileNameWritten)
       
   329 					{
       
   330 					
       
   331 					TPtr8 ptr(reinterpret_cast<TUint8*>(const_cast<TUint16*>(name.Ptr())), name.Size(), name.Size());
       
   332 					
       
   333 					if (WriteToBufferV(ptr, ptr.Size(), aBuffer) == EFalse)
       
   334 						{
       
   335 						__LOG("CBufferFileReader::WriteToBufferV() - WriteToBufferF() returned False so breaking!");
       
   336 						break;
       
   337 						}
       
   338 					iFileNameWritten = ETrue;
       
   339 					}
       
   340 
       
   341 	            __LOG1("CBufferFileWriter::WriteToBufferL() - buffer is of length: %d", aBuffer.Length());
       
   342 					
       
   343 				TInt bufferLeft = aBuffer.MaxSize() - aBuffer.Size();
       
   344 				TPtr8 ptr(const_cast<TUint8*>(aBuffer.Ptr()) + aBuffer.Size(), bufferLeft);
       
   345 				TInt fileSize = 0;
       
   346 				iFileHandle.Size(fileSize);
       
   347 				TInt fileLeft = fileSize - iOffset;
       
   348 				if (bufferLeft < fileLeft)
       
   349 					{
       
   350 	                __LOG("CBufferFileWriter::WriteToBufferL() - buffer space available is less than file size!");
       
   351 
       
   352 	                // Write buffer size
       
   353 					User::LeaveIfError(iFileHandle.Read(iOffset, ptr, bufferLeft)); // TODO: Is this correct?
       
   354 					aBuffer.SetLength(aBuffer.Length() + bufferLeft);
       
   355 					iOffset += bufferLeft;
       
   356 					break;
       
   357 					} // if
       
   358 				else
       
   359 					{
       
   360 	                __LOG("CBufferFileWriter::WriteToBufferL() - enough space in buffer for whole file...");
       
   361 
       
   362 	                // Write file size
       
   363 					User::LeaveIfError(iFileHandle.Read(ptr, fileLeft)); // TODO: Is this correct?
       
   364 					aBuffer.SetLength(aBuffer.Length() + fileLeft);
       
   365 					} // else
       
   366 
       
   367 	            __LOG1("CBufferFileWriter::WriteToBufferL() - After read from file, buffer is now of length: %d", aBuffer.Length());
       
   368 	            
       
   369 				iFileHandle.Close();
       
   370 				iFileOpen = EFalse;
       
   371 				iHeaderWritten = EFalse;
       
   372 				iFileNameWritten = EFalse;
       
   373 				iOffset = 0;
       
   374             	} //else
       
   375 			++iCurrentFile;
       
   376 			} // while
       
   377 			
       
   378 		if (iCurrentFile >= count)
       
   379 			{
       
   380 			aCompleted = ETrue;
       
   381 			} // if
       
   382 		} // WriteToBufferL
       
   383 		
       
   384 	CBufferFileReader* CBufferFileReader::NewL(RFs& aFs, RSnapshots* apSnapshots, MValidationHandler* aValidationHandler)
       
   385 	/** Symbian OS constructor
       
   386 	
       
   387 	@param aFs File server to use.
       
   388 	@param apSnapshots list of snapshots.
       
   389 	*/
       
   390 		{
       
   391         __LOG("CBufferFileReader::NewL() - START");
       
   392 		CBufferFileReader* self = new(ELeave) CBufferFileReader(aFs, apSnapshots, aValidationHandler);
       
   393 		
       
   394 		CleanupStack::PushL( self );
       
   395 		
       
   396 	#ifdef SBE_LOGGING_ENABLED
       
   397         if  (apSnapshots)
       
   398             {
       
   399 		    const TInt count = apSnapshots->Count();
       
   400             __LOG1("CBufferFileReader::NewL() - Got %d snapshots to compare against during restore...", count);
       
   401 
       
   402 		    for(TInt x = 0; x < count; ++x)
       
   403 			    {
       
   404                 const TDesC& snapshot = (*apSnapshots)[x]->FileName();
       
   405                 __LOG3("CBufferFileReader::NewL() -    snapshot[%4d/%4d] is: %S", x+1, count, &snapshot);
       
   406 			    } // for x
       
   407 
       
   408 		    }
       
   409 	#endif
       
   410         
       
   411         __LOG("CBufferFileReader::NewL() - END");
       
   412         
       
   413         CleanupStack::Pop( self );
       
   414 		return self;
       
   415 		} // NewL
       
   416 		
       
   417 	CBufferFileReader::CBufferFileReader(RFs& aFs, RSnapshots* apSnapshots, MValidationHandler* aValidationHandler) :
       
   418 		iFs(aFs), iSnapshots(apSnapshots), iValidationHandler(aValidationHandler)
       
   419 	/** C++ constructor
       
   420 	
       
   421 	@param aFs File server to use.
       
   422 	@param apSnapshots list of snapshots.
       
   423 	*/
       
   424 		{
       
   425 		} // CBufferFileReader
       
   426 		
       
   427 	void CBufferFileReader::StartL(const TDesC8& aBuffer, TBool aLastSection)
       
   428 	/** Start reading from the buffer.
       
   429 	
       
   430 	@param aBuffer The buffer to read from.
       
   431 	@param aLastSection Is this the last section?
       
   432 	*/
       
   433 		{
       
   434         __LOG("CBufferFileReader::StartL() - START");
       
   435         if (iSnapshots)
       
   436         	{
       
   437         	iSnapshots->Sort(CSnapshot::Compare);
       
   438         	}
       
   439 		ReadFromBufferL(aBuffer, aLastSection);
       
   440         __LOG("CBufferFileReader::StartL() - END");
       
   441 		} // StartL
       
   442 	
       
   443 	void CBufferFileReader::ContinueL(const TDesC8& aBuffer, TBool aLastSection)
       
   444 	/** Continue reading from the buffer.
       
   445 	
       
   446 	@param aBuffer The buffer to read from.
       
   447 	@param aLastSection Is this the last section?
       
   448 	*/
       
   449 		{
       
   450         __LOG("CBufferFileReader::ContinueL() - START");
       
   451 		ReadFromBufferL(aBuffer, aLastSection);
       
   452         __LOG("CBufferFileReader::ContinueL() - END");
       
   453 		} // ContinueL
       
   454 	
       
   455 	void CBufferFileReader::CheckFileInSnapshotL()
       
   456 	/**
       
   457 	Checks to see if a given file is in a snapshot.
       
   458 	*/
       
   459 		{
       
   460         __LOG2("CBufferFileReader::CheckFileInSnapshot() - START - ipSnapshots: 0x%08x, iSnapshotChecked: %d", iSnapshots, iSnapshotChecked);
       
   461 
       
   462 		iRestore = ETrue;
       
   463 		
       
   464 		if (iSnapshots)
       
   465 			{
       
   466 			CSnapshot* snapshot = CSnapshot::NewLC(TTime().Int64(), iFileName);
       
   467 			TInt res = iSnapshots->Find(snapshot, CSnapshot::Match);
       
   468 			if (res == KErrNotFound)
       
   469 				{
       
   470 				iRestore = EFalse;
       
   471 				}
       
   472 			CleanupStack::PopAndDestroy(snapshot);		
       
   473 			} // if
       
   474 		
       
   475 		iSnapshotChecked = ETrue;
       
   476 
       
   477         __LOG2("CBufferFileReader::CheckFileInSnapshot() - END - iSnapshotChecked: %d, iRestore: %d", iSnapshotChecked, iRestore);
       
   478 		}
       
   479 		
       
   480 	void CBufferFileReader::RecreateDirL()
       
   481 	/**
       
   482 	Recreates a directory path on disk.
       
   483 	*/
       
   484 		{
       
   485         __LOG1("CBufferFileReader::RecreateDirL() - START - iFileName: %S", &iFileName);
       
   486 		// Create the path
       
   487 		TInt err = iFs.MkDirAll(iFileName);
       
   488 		if ((err != KErrNone) && (err != KErrAlreadyExists))
       
   489 			{
       
   490             __LOG1("CBufferFileReader::WriteToFile() - making directory resulted in fatal error: %d", err);
       
   491 			User::Leave(err);
       
   492 			} // if
       
   493         
       
   494         __LOG("CBufferFileReader::RecreateDirL() - END");
       
   495 		}
       
   496 		
       
   497 	
       
   498 	void CBufferFileReader::RecreateFileL()
       
   499 	/**
       
   500 	Recreates a file on disk. Deletes the original if it still exists.
       
   501 	*/
       
   502 		{
       
   503         __LOG1("CBufferFileReader::RecreateFileL() - START - iFileName: %S", &iFileName);
       
   504 		// Create the path
       
   505 		TInt err = iFs.MkDirAll(iFileName);
       
   506 		if ((err != KErrNone) && (err != KErrAlreadyExists))
       
   507 			{
       
   508             __LOG1("CBufferFileReader::WriteToFile() - making directory resulted in fatal error: %d", err);
       
   509 			User::Leave(err);
       
   510 			} // if
       
   511 
       
   512         
       
   513         err = iFileHandle.Replace(iFs, iFileName, EFileWrite);
       
   514         __LOG1("CBufferFileReader::WriteToFile() - replacing file returned err: %d", err);
       
   515         User::LeaveIfError( err );
       
   516 			
       
   517 		iFileOpen = ETrue;
       
   518         __LOG("CBufferFileReader::RecreateFileL() - END");
       
   519 		}
       
   520 	
       
   521 		
       
   522 	TBool CBufferFileReader::WriteToFileL(TUint8*& aCurrent, const TUint8* aEnd)
       
   523 	/**
       
   524 	Writes data to a file.
       
   525 	
       
   526 	@param aCurrent start point of data to write.
       
   527 	@param aEnd end point of data to write.
       
   528 	@return ETrue if write finished. EFalse if there is more data to write.
       
   529 	*/
       
   530 		{
       
   531         __LOG2("CBufferFileReader::WriteToFile() - START - iFileHandle: 0x%08x, iFixedHeader.iFileSize: %d", iFileHandle.SubSessionHandle(), iFixedHeader.iFileSize);
       
   532 		TBool retVal = ETrue;
       
   533 		TInt filesize;
       
   534 		const TInt err1 = iFileHandle.Size(filesize);
       
   535         __LOG2("CBufferFileReader::WriteToFile() - fileSize: %d (err: %d)", filesize, err1);
       
   536 		User::LeaveIfError(err1);
       
   537 		if ((aEnd - aCurrent) >= (iFixedHeader.iFileSize - filesize))
       
   538 			{
       
   539 			TPtr8 ptr(aCurrent, iFixedHeader.iFileSize -filesize, iFixedHeader.iFileSize - filesize);
       
   540 			const TInt err2 = iFileHandle.Write(ptr);
       
   541             __LOG2("CBufferFileReader::WriteToFile() - writing %d bytes returned error: %d", ptr.Length(), err2);
       
   542 			User::LeaveIfError(err2);
       
   543 
       
   544 			// Write the attributes & modified time
       
   545 			const TInt err3 = iFileHandle.Set(iFixedHeader.iModified, 
       
   546 					iFixedHeader.iAttributes, KEntryAttNormal);
       
   547 
       
   548             __LOG1("CBufferFileReader::WriteToFile() - setting attribs returned error: %d", err3);
       
   549 			User::LeaveIfError(err3);
       
   550 			
       
   551 			// Move current along
       
   552 			aCurrent += iFixedHeader.iFileSize - filesize;
       
   553 
       
   554 			// Finished reset state
       
   555 			Reset();
       
   556 			} // if
       
   557 		else
       
   558 			{
       
   559 			TInt size = aEnd - aCurrent;
       
   560 			TPtr8 ptr(aCurrent, size, size);
       
   561 			const TInt err2 = iFileHandle.Write(ptr);
       
   562             __LOG2("CBufferFileReader::WriteToFile() - writing %d bytes returned error: %d", ptr.Length(), err2);
       
   563 
       
   564 			retVal = EFalse;
       
   565 			} // else
       
   566 			
       
   567         __LOG1("CBufferFileReader::WriteToFile() - END - finished: %d", retVal);
       
   568 		return retVal;
       
   569 		}
       
   570 
       
   571 	void CBufferFileReader::ReadFromBufferL(const TDesC8& aBuffer, TBool aLastSection)
       
   572 	/** Reads from the buffer and writes files to disk.
       
   573 	
       
   574 	@param aBuffer The buffer to read from.
       
   575 	@param aLastSection Is this the last section?
       
   576 	@leave KErrUnderflow More data is needed.
       
   577 	*/	
       
   578         {
       
   579         __LOG5("CBufferFileReader::ReadFromBufferL() - START - iFileNameRead: %d, iSnapshotChecked: %d, iRestore: %d, iFileOpen: %d, iFileName: %S", iFileNameRead, iSnapshotChecked, iRestore, iFileOpen, &iFileName);
       
   580 
       
   581         TUint8* current = const_cast<TUint8*>(aBuffer.Ptr());
       
   582 		const TUint8* end = current + aBuffer.Size();
       
   583 		
       
   584 		// Workaround for "dual fixed header in backup" error. Tries to detect the special error case where iFixedHeaderRead=true but filename wasn't read
       
   585 		if(iFixedHeaderRead && !iFileNameRead && !iBytesRead && (end-current) >= 12)
       
   586 			{
       
   587 			// Check the first 12 bytes of the header we already got (the iModified is different between the problematic second header)
       
   588 			const TUint8* tempbuf = (TUint8*)&iFixedHeader;
       
   589 			TBool workAroundNeeded = ETrue;
       
   590 			for(TInt i = 0; i < 12; i++)
       
   591 				{
       
   592 				if(current[i] != tempbuf[i])
       
   593 					{
       
   594 					workAroundNeeded = EFalse;
       
   595 					break;
       
   596 					}
       
   597 				}
       
   598 
       
   599 			if(workAroundNeeded)
       
   600 				{
       
   601 				__LOG("CBufferFileReader::ReadFromBufferL() - Dual header was detected, workaround!!!");
       
   602 				iFixedHeaderRead = EFalse; // Mark that the processing loop reads the fixed header again
       
   603 				}
       
   604 			}
       
   605 		
       
   606 		while (current < end)
       
   607 			{
       
   608             __LOG2("CBufferFileReader::ReadFromBufferL() - iFixedHeaderRead: %d, iLeftToSkip: %d", iFixedHeaderRead, iLeftToSkip);
       
   609 
       
   610 			// Do we have the fixed header?
       
   611 			if (!iFixedHeaderRead)
       
   612 				{
       
   613 				if (ReadFromBufferF(iFixedHeader, current, end) == EFalse)
       
   614 					{
       
   615 					__LOG("CBufferFileReader::ReadFromBufferL() - ReadFromBufferF() returned False so breaking!");
       
   616 					break;
       
   617 					} // if
       
   618 				
       
   619                 __LOG1("CBufferFileReader::ReadFromBufferL() - fixed header - iFileNameLength:  %d", iFixedHeader.iFileNameLength);
       
   620                 __LOG1("CBufferFileReader::ReadFromBufferL() - fixed header - iFileSize:        %d", iFixedHeader.iFileSize);
       
   621                 __LOG1("CBufferFileReader::ReadFromBufferL() - fixed header - iAttributes:      %d", iFixedHeader.iAttributes);
       
   622                 
       
   623                 if ((iFixedHeader.iFileNameLength > KMaxFileName) || (!iFixedHeader.iFileNameLength))
       
   624 					{
       
   625 					__LOG1("CBufferFileReader::ReadFromBufferL() - Leaving - iFileNameLength: %d more then MaxLength", iFixedHeader.iFileNameLength);
       
   626 					User::Leave(KErrOverflow);
       
   627 					}
       
   628                 
       
   629 				iFixedHeaderRead = ETrue;
       
   630 				} // if
       
   631 
       
   632 				
       
   633             __LOG1("CBufferFileReader::ReadFromBufferL() - iFileNameRead: %d", iFileNameRead);
       
   634 			if (!iFileNameRead)
       
   635 				{
       
   636 				TPtr8 ptr(reinterpret_cast<TUint8*>(const_cast<TUint16*>(iFileName.Ptr())), iBytesRead, iFixedHeader.iFileNameLength * KCharWidthInBytes);
       
   637 				
       
   638 				if (ReadFromBufferV(ptr, iFixedHeader.iFileNameLength * KCharWidthInBytes, current, end) == EFalse)
       
   639 					{
       
   640 					iBytesRead = ptr.Size();
       
   641 					__LOG1("CBufferFileReader::ReadFromBufferL() - ReadFromBufferV() returned False - Filename bytes read: %d", iBytesRead);
       
   642 					break;
       
   643 					} // if
       
   644 				
       
   645 				iFileName.SetLength(iFixedHeader.iFileNameLength);
       
   646 				iFileNameRead = ETrue;
       
   647                 __LOG1("CBufferFileReader::ReadFromBufferL() - Got filename: %S", &iFileName);
       
   648 				}
       
   649 			
       
   650 			// Is the file in the snapshot, if not it was deleted in an increment and does not need restoring
       
   651             __LOG1("CBufferFileReader::ReadFromBufferL() - iSnapshotChecked: %d", iSnapshotChecked);
       
   652 			if (!iSnapshotChecked)
       
   653 				{
       
   654 				CheckFileInSnapshotL();
       
   655 				} // if
       
   656 			
       
   657             __LOG2("CBufferFileReader::ReadFromBufferL() - iValidationHandler: 0x%08x, iRestore: %d", iValidationHandler, iRestore);
       
   658 			if (iValidationHandler != NULL)
       
   659 				{
       
   660 				if (iRestore)
       
   661 					{
       
   662 					iRestore = iValidationHandler->ValidFileL(iFileName);
       
   663                     __LOG1("CBufferFileReader::ReadFromBufferL() - validation handler result: %d", iRestore);
       
   664 					}
       
   665 				}
       
   666 			
       
   667 			if (!iRestore && !iLeftToSkip)
       
   668 				{
       
   669                 __LOG1("CBufferFileReader::ReadFromBufferL() - restore not permitted, skipping file data (%d bytes)", iFixedHeader.iFileSize);
       
   670 				iLeftToSkip = iFixedHeader.iFileSize; // So we can skip the bytes
       
   671 				}
       
   672 			
       
   673             __LOG1("CBufferFileReader::ReadFromBufferL() - iFileOpen: %d", iFileOpen);
       
   674 			if (iRestore)
       
   675 				{
       
   676 				// Check if it is a directory or file
       
   677 				_LIT( KTrailingBackSlash, "\\" );
       
   678 				if (iFileName.Right(1) == KTrailingBackSlash())
       
   679 					{
       
   680 					__LOG("CBufferFileReader::ReadFromBufferL() - Attempting to recreate directory path...");
       
   681 					RecreateDirL();
       
   682 					Reset();
       
   683 					}
       
   684 				else 
       
   685 					{
       
   686 					// Have we opened the file?
       
   687 					if (!iFileOpen)
       
   688 						{
       
   689 						__LOG("CBufferFileReader::ReadFromBufferL() - Attempting to recreate file...");
       
   690 						RecreateFileL();		
       
   691 						}
       
   692 					
       
   693 					// Write to the file
       
   694 	                __LOG("CBufferFileReader::ReadFromBufferL() - Attempting to write to file...");
       
   695 					if (!WriteToFileL(current, end))
       
   696 						{
       
   697 						__LOG("CBufferFileReader::ReadFromBufferL() - WriteToFileL() returned False so breaking!");
       
   698 						break;
       
   699 						}	
       
   700 					}//if
       
   701 				} // if
       
   702 			else
       
   703 				{
       
   704 				// We need to skip the bytes in the data
       
   705                 __LOG2("CBufferFileReader::ReadFromBufferL() - We\'re in skip mode. EndPos: %8d, CurrentPos: %8d", end, current);
       
   706 				if ((end - current) >= iLeftToSkip)
       
   707 					{
       
   708 					current += iLeftToSkip;
       
   709 
       
   710 					// Finished reset state
       
   711                     __LOG("CBufferFileReader::ReadFromBufferL() - Finished skipping");
       
   712 					Reset();
       
   713 					} // if
       
   714 				else
       
   715 					{
       
   716                     __LOG1("CBufferFileReader::ReadFromBufferL() - Still more data to skip...: %d bytes", iLeftToSkip);
       
   717 					iLeftToSkip = iLeftToSkip - (end - current);
       
   718 					break;
       
   719 					} // else
       
   720 				} // else
       
   721 			} // while
       
   722 			
       
   723             __LOG3("CBufferFileReader::ReadFromBufferL() - aLastSection: %d, iFileOpen: %d, iLeftToSkip: %d", aLastSection, iFileOpen, iLeftToSkip);
       
   724 
       
   725 			if ((aLastSection && iFileOpen) ||
       
   726 			    (aLastSection && (iLeftToSkip > 0)))
       
   727 				{
       
   728                 __LOG("CBufferFileReader::ReadFromBufferL() - Leaving with KErrUnderflow because not all skipped data was consumed!");
       
   729 				User::Leave(KErrUnderflow);
       
   730 			} // if
       
   731 
       
   732         __LOG("CBufferFileReader::ReadFromBufferL() - END");
       
   733 		} // ReadFromBufferL
       
   734 		
       
   735 	void CBufferFileReader::RedirectMIDletRestorePathL(const TDesC& aOriginal, CDesCArray& aRedirected)
       
   736 	/** Redirects the midlet restore path
       
   737 	
       
   738 	@param aOriginal the original path
       
   739 	@param aRedirected the redirected path
       
   740 	*/
       
   741 		{
       
   742 		TFileName redirectedFilename(KMIDletTempRestorePath);
       
   743 		// Backslash used to isolate the filename from aOriginal's absolute path
       
   744 		const TChar KTCharBackslash('\\');
       
   745 		
       
   746 		// Isolate the filename from aOriginal and Append it to our temp path
       
   747 		redirectedFilename.Append(aOriginal.Mid(aOriginal.LocateReverseF(KTCharBackslash) + 1));
       
   748 		aRedirected.AppendL(redirectedFilename);
       
   749 		}
       
   750 
       
   751 	void CBufferFileReader::ReadMIDletsFromBufferL(const TDesC8& aBuffer, TBool aLastSection, 
       
   752 		CDesCArray& aUnpackedFileNames)
       
   753 	/** Reads from the buffer and writes files to disk.
       
   754 	
       
   755 	@param aBuffer The buffer to read from.
       
   756 	@param aLastSection Is this the last section?
       
   757 	@leave KErrUnderflow More data is needed.
       
   758 	*/	
       
   759 		{
       
   760 		TUint8* current = const_cast<TUint8*>(aBuffer.Ptr());
       
   761 		const TUint8* end = current + aBuffer.Size();
       
   762 		TInt fileIndex = 0;
       
   763 		while (current < end)
       
   764 			{
       
   765 			// Do we have the fixed header?
       
   766 			if (!iFixedHeaderRead)
       
   767 				{
       
   768 				if (ReadFromBufferF(iFixedHeader, current, end) == EFalse)
       
   769 					{
       
   770 					__LOG("CBufferFileReader::ReadMIDletsFromBufferL() - ReadFromBufferF() returned False so breaking!");
       
   771 					break;
       
   772 					} // if
       
   773 				__LOG1("CBufferFileReader::ReadMIDletsFromBufferL() - fixed header - iFileNameLength:  %d", iFixedHeader.iFileNameLength);
       
   774                 __LOG1("CBufferFileReader::ReadMIDletsFromBufferL() - fixed header - iFileSize:        %d", iFixedHeader.iFileSize);
       
   775                 __LOG1("CBufferFileReader::ReadMIDletsFromBufferL() - fixed header - iAttributes:      %d", iFixedHeader.iAttributes);	
       
   776 					
       
   777 				if ((iFixedHeader.iFileNameLength > KMaxFileName) || (!iFixedHeader.iAttributes) || (!iFixedHeader.iFileNameLength))
       
   778 					{
       
   779 					__LOG1("CBufferFileReader::ReadMIDletsFromBufferL() - Leaving - iFileNameLength: %d more then MaxLength", iFixedHeader.iFileNameLength);
       
   780 					User::Leave(KErrOverflow);
       
   781 					}
       
   782 				
       
   783 				iFixedHeaderRead = ETrue;
       
   784 				} // if
       
   785 				
       
   786 			if (!iFileNameRead)
       
   787 				{
       
   788 				TPtr8 ptr(reinterpret_cast<TUint8*>(const_cast<TUint16*>(iFileName.Ptr())), iBytesRead, iFixedHeader.iFileNameLength * KCharWidthInBytes);
       
   789 				
       
   790 				if (ReadFromBufferV(ptr, iFixedHeader.iFileNameLength * KCharWidthInBytes, current, end) == EFalse)
       
   791 					{
       
   792 					iBytesRead = ptr.Size();
       
   793 					__LOG1("CBufferFileReader::ReadMIDletsFromBufferL() - ReadFromBufferV() returned False - Filename bytes read: %d", iBytesRead);
       
   794 					break;
       
   795 					} // if
       
   796 				
       
   797 					
       
   798 				iFileName.SetLength(iFixedHeader.iFileNameLength);
       
   799 				
       
   800 				// Throw away the unpacked filename, as we're now
       
   801 				RedirectMIDletRestorePathL(iFileName, aUnpackedFileNames);
       
   802 				
       
   803 				// We don't need the original filename any more, we're using the one returne by Redirect...
       
   804 				iFileName = aUnpackedFileNames[fileIndex];
       
   805 				
       
   806 				iFileNameRead = ETrue;
       
   807 				
       
   808 				// set the index to the next file in the list
       
   809 				fileIndex++;
       
   810 				}
       
   811 				
       
   812 			// Is the file in the snapshot, if not it was deleted in an increment and does not need restoring
       
   813 			if (!iSnapshotChecked)
       
   814 				{
       
   815 				CheckFileInSnapshotL();
       
   816 				} // if
       
   817 			
       
   818 			if (!iRestore && !iLeftToSkip)
       
   819 				{
       
   820                 __LOG1("CBufferFileReader::ReadMIDletsFromBufferL() - restore not permitted, skipping file data (%d bytes)", iFixedHeader.iFileSize);
       
   821 				iLeftToSkip = iFixedHeader.iFileSize; // So we can skip the bytes
       
   822 				}
       
   823 
       
   824 			if (iRestore)
       
   825 				{
       
   826 				// Have we opened the file?
       
   827 				if (!iFileOpen)
       
   828 					{
       
   829 					RecreateFileL();
       
   830 					}
       
   831 					
       
   832 				// Write to the file
       
   833 				if (!WriteToFileL(current, end))
       
   834 					{
       
   835 					__LOG("CBufferFileReader::ReadMIDletsFromBufferL() - WriteToFileL() returned False so breaking!");
       
   836 					break;
       
   837 					}
       
   838 				} // if
       
   839 			else
       
   840 				{
       
   841 				// We need to skip the bytes in the data
       
   842 				if ((end - current) >= iLeftToSkip)
       
   843 					{
       
   844 					current += iLeftToSkip;
       
   845 
       
   846 					// Finished reset state
       
   847 					Reset();
       
   848 					} // if
       
   849 				else
       
   850 					{
       
   851 					__LOG1("CBufferFileReader::ReadMIDletsFromBufferL() - Still more data to skip...: %d bytes", iLeftToSkip);
       
   852 					iLeftToSkip = iLeftToSkip - (end - current);
       
   853 					break;
       
   854 					} // else
       
   855 				} // else
       
   856 			} // while
       
   857 			
       
   858 			if ((aLastSection && iFileOpen) ||
       
   859 			    (aLastSection && (iLeftToSkip > 0)))
       
   860 				{
       
   861 				User::Leave(KErrUnderflow);
       
   862 				} // if
       
   863 		} // ReadMIDletsFromBufferL
       
   864 		
       
   865 	void CBufferFileReader::Reset()
       
   866 	/** Resets the state of the object.
       
   867 	*/
       
   868 		{
       
   869 		iFileHandle.Close();
       
   870 		iFileOpen = EFalse;
       
   871 		iFileNameRead = EFalse;
       
   872 		iLeftToSkip = 0;
       
   873 		iSnapshotChecked = EFalse;
       
   874 		iFileName.SetLength(0);
       
   875 		iFixedHeaderRead = EFalse;
       
   876 		iBytesRead = 0;
       
   877 		}
       
   878 		
       
   879 	CBufferFileReader::~CBufferFileReader()
       
   880 	/** destructor
       
   881 	*/
       
   882 		{
       
   883 		iFileHandle.Close();
       
   884 		}
       
   885 		
       
   886 	
       
   887 	
       
   888 	CBufferSnapshotWriter* CBufferSnapshotWriter::NewL(RSnapshots* aSnapshots)
       
   889 	/** Symbian OS constructor
       
   890 	
       
   891 	@param aFiles File information to write to the buffer.ownernship transfer
       
   892 	*/
       
   893 		{
       
   894 		CBufferSnapshotWriter* self = new(ELeave) CBufferSnapshotWriter(aSnapshots);
       
   895 		CleanupStack::PushL(self);
       
   896 		self->ConstructL();
       
   897 		CleanupStack::Pop(self);
       
   898 		
       
   899 		return self;
       
   900 		} // NewL
       
   901 		
       
   902 	CBufferSnapshotWriter::CBufferSnapshotWriter(RSnapshots* aSnapshots) : iSnapshots(aSnapshots)
       
   903 	/** Standard C++ constructor
       
   904 	*/
       
   905 		{
       
   906 		}
       
   907 		
       
   908 	void CBufferSnapshotWriter::ConstructL()
       
   909 	/** Symbian second phase constructor
       
   910 
       
   911 	@param aFiles File information to write to the buffer.
       
   912 	*/
       
   913 		{
       
   914 		__ASSERT_DEBUG(iSnapshots, Panic(KErrArgument));
       
   915 		#ifdef SBE_LOGGING_ENABLED
       
   916         const TInt count = iSnapshots->Count();
       
   917         __LOG1("CBufferFileReader::NewL() - Got %d snapshots to compare against during restore...", count);
       
   918 
       
   919 	    for(TInt x = 0; x < count; ++x)
       
   920 		    {
       
   921             const TDesC& snapshot = (*iSnapshots)[x]->FileName();
       
   922             __LOG3("CBufferFileReader::NewL() -    snapshot[%4d/%4d] is: %S", x+1, count, &snapshot);
       
   923 		    } // for x
       
   924 
       
   925 		#endif
       
   926 		} // ConstructL
       
   927 		
       
   928 	CBufferSnapshotWriter::~CBufferSnapshotWriter()
       
   929 	/** Standard C++ destructor
       
   930 	*/
       
   931 		{
       
   932 		if(iSnapshots)
       
   933 			{
       
   934 			iSnapshots->ResetAndDestroy();
       
   935 			delete iSnapshots;
       
   936 			}
       
   937 		} // ~CBufferSnapshotWriter
       
   938 		
       
   939 	void CBufferSnapshotWriter::StartL(TPtr8& aBuffer, TBool& aCompleted)
       
   940 	/** Starts writing to the buffer 
       
   941 	
       
   942 	@param aBuffer The buffer.
       
   943 	@param aCompleted On return if we have finished writing data.
       
   944 	*/
       
   945 		{
       
   946         __LOG("CBufferSnapshotWriter::StartL() - START");
       
   947 		WriteToBufferL(aBuffer, aCompleted);
       
   948         __LOG("CBufferSnapshotWriter::StartL() - END");
       
   949 		} // WriteToBufferL
       
   950 
       
   951 	void CBufferSnapshotWriter::ContinueL(TPtr8& aBuffer, TBool& aCompleted)
       
   952 	/** Continues writing to the buffer 
       
   953 	
       
   954 	@param aBuffer The buffer.
       
   955 	@param aCompleted On return if we have finished writing data.
       
   956 	*/
       
   957 		{
       
   958         __LOG("CBufferSnapshotWriter::ContinueL() - START");
       
   959 		WriteToBufferL(aBuffer, aCompleted);
       
   960         __LOG("CBufferSnapshotWriter::ContinueL() - END");
       
   961 		} // WriteToBufferL
       
   962 		
       
   963 	void CBufferSnapshotWriter::WriteToBufferL(TPtr8& aBuffer, TBool& aCompleted)
       
   964 	/** Writes to the buffer 
       
   965 
       
   966 	@param aBuffer The buffer.
       
   967 	@param aCompleted On return if we have finished writing data.
       
   968 	*/
       
   969 		{
       
   970         __LOG1("CBufferSnapshotWriter::WriteToBufferL() - START - aBuffer length: %d", aBuffer.Length());
       
   971 		aCompleted = EFalse;
       
   972 		
       
   973 		const TUint count = iSnapshots->Count();
       
   974 		while (iCurrentSnapshot < count)
       
   975 			{
       
   976             __LOG1("CBufferSnapshotWriter::WriteToBufferL() - iCurrentSnapshot: %d", iCurrentSnapshot);
       
   977 
       
   978 			// Check there is enough room
       
   979 			if (sizeof(TSnapshot) > static_cast<TUint>(aBuffer.MaxSize() - aBuffer.Size()))
       
   980 				{
       
   981 				__LOG("CBufferSnapshotWriter::WriteToBufferL() - Snapshot size is more than buffer available - break");
       
   982 				break;
       
   983 				} // if
       
   984 				
       
   985 			// Write modified
       
   986 			TSnapshot snapshot;
       
   987 			(*iSnapshots)[iCurrentSnapshot]->Snapshot(snapshot);
       
   988             __LOG1("CBufferSnapshotWriter::WriteToBufferL() - writing snapshot for file: %S", &snapshot.iFileName);
       
   989 
       
   990 			WriteToBufferF(snapshot, aBuffer);
       
   991 			
       
   992 			++iCurrentSnapshot;			
       
   993 			} // while
       
   994 
       
   995 		if (iCurrentSnapshot >= count)
       
   996 			{
       
   997 			aCompleted = ETrue;
       
   998 			} // if
       
   999 
       
  1000         __LOG1("CBufferSnapshotWriter::WriteToBufferL() - END - aCompleted: %d", aCompleted);
       
  1001 		} // WriteToBufferL
       
  1002 	
       
  1003 	CBufferSnapshotReader* CBufferSnapshotReader::NewL(RSnapshots& aSnapshots)
       
  1004 	/** Symbian constructor
       
  1005 	
       
  1006 	@param aFiles Locaton to store files read from buffer.
       
  1007 	*/
       
  1008 		{
       
  1009 		return new (ELeave) CBufferSnapshotReader(aSnapshots);
       
  1010 		}
       
  1011 		
       
  1012 	CBufferSnapshotReader::CBufferSnapshotReader(RSnapshots& aSnapshots) :
       
  1013 		iSnapshots(aSnapshots)
       
  1014 	/** C++ constructor
       
  1015 	
       
  1016 	@param aSnapshots snapshots of files.
       
  1017 	*/
       
  1018 		{
       
  1019 		}
       
  1020 		
       
  1021 	CBufferSnapshotReader::~CBufferSnapshotReader()
       
  1022 	/**
       
  1023 	C++ destructor
       
  1024 	*/
       
  1025 		{
       
  1026 		}
       
  1027 		
       
  1028 	void CBufferSnapshotReader::StartL(const TDesC8& aBuffer, TBool aLastSection)
       
  1029 	/** Starts reading data from the buffer
       
  1030 	
       
  1031 	@param aBuffer buffer to read from.
       
  1032 	@param aLastSection is this the last section.
       
  1033 	*/
       
  1034 		{
       
  1035         __LOG2("CBufferSnapshotReader::StartL() - START - buffer len: %d, aLastSection: %d", aBuffer.Length(), aLastSection);
       
  1036 
       
  1037 		ReadFromBufferL(aBuffer, aLastSection);
       
  1038 
       
  1039         __LOG("CBufferSnapshotReader::StartL() - END");
       
  1040 		}
       
  1041 		
       
  1042 	void CBufferSnapshotReader::ContinueL(const TDesC8& aBuffer, TBool aLastSection)
       
  1043 	/** Continues reading data from the buffer
       
  1044 	
       
  1045 	@param aBuffer buffer to read from.
       
  1046 	@param aLastSection is this the last section.
       
  1047 	*/
       
  1048 		{
       
  1049         __LOG2("CBufferSnapshotReader::ContinueL() - START - buffer len: %d, aLastSection: %d", aBuffer.Length(), aLastSection);
       
  1050 
       
  1051 		ReadFromBufferL(aBuffer, aLastSection);
       
  1052 
       
  1053         __LOG("CBufferSnapshotReader::ContinueL() - END");
       
  1054 		}
       
  1055 		
       
  1056 	void CBufferSnapshotReader::ReadFromBufferL(const TDesC8& aBuffer, TBool /*aLastSection*/)
       
  1057 	/** Reads data from the buffer
       
  1058 	
       
  1059 	@param aBuffer buffer to read from.
       
  1060 	@param aLastSection is this the last section.
       
  1061 	*/
       
  1062 		{
       
  1063         __LOG("CBufferSnapshotReader::ReadFromBufferL() - START");
       
  1064 
       
  1065 		TUint8* current = const_cast<TUint8*>(aBuffer.Ptr());
       
  1066 		const TUint8* end = current + aBuffer.Size();
       
  1067 		while (current < end)
       
  1068 			{
       
  1069 			if (ReadFromBufferF(iSnapshot, current, end) == EFalse)
       
  1070 				{
       
  1071 				__LOG("CBufferSnapshotReader::ReadFromBufferL() - returned EFalse breaking!");
       
  1072 				break;
       
  1073 				}
       
  1074 			
       
  1075             __LOG1("CBufferSnapshotReader::ReadFromBufferL() - read snapshot info for file: %S", &iSnapshot.iFileName);
       
  1076             CSnapshot* snapshot = CSnapshot::NewLC(iSnapshot);
       
  1077 			iSnapshots.AppendL(snapshot);
       
  1078 			CleanupStack::Pop(snapshot);
       
  1079 			} // while
       
  1080 
       
  1081         __LOG("CBufferSnapshotReader::ReadFromBufferL() - END");
       
  1082 		} // ReadFromBufferL
       
  1083 		
       
  1084 	
       
  1085 	// CSnapshot //
       
  1086 	
       
  1087 	/**
       
  1088 	
       
  1089 	Symbian 2nd phase construction creates a CSelection
       
  1090 	
       
  1091 	@param aType - Selection Type
       
  1092 	@param aSelection - Selection Nmae
       
  1093 	@return CSelection a pointer to a new object 
       
  1094 	*/
       
  1095 	CSnapshot* CSnapshot::NewLC(const TInt64& aModified, const TDesC& aFileName)
       
  1096 		{
       
  1097 		CSnapshot* self = new (ELeave) CSnapshot(aModified);
       
  1098 		CleanupStack::PushL(self);
       
  1099 		self->ConstructL(aFileName);
       
  1100 		return self;
       
  1101 		}
       
  1102 	
       
  1103 	/**
       
  1104 	
       
  1105 	Symbian 2nd phase construction creates a Selection
       
  1106 	
       
  1107 	@param aSnapshot - TSnapshot snapshot
       
  1108 	@return CSelection a pointer to a new object 
       
  1109 	*/
       
  1110 	CSnapshot* CSnapshot::NewLC(const TSnapshot& aSnapshot)
       
  1111 		{
       
  1112 		return CSnapshot::NewLC(aSnapshot.iModified, aSnapshot.iFileName);
       
  1113 		}
       
  1114 	
       
  1115 	/**
       
  1116 	Standard C++ destructor
       
  1117 	*/
       
  1118 	CSnapshot::~CSnapshot()
       
  1119 		{
       
  1120 		delete iFileName;
       
  1121 		}
       
  1122 	
       
  1123 	/**
       
  1124 	Standard C++ constructor
       
  1125 	*/
       
  1126 	CSnapshot::CSnapshot(const TInt64& aModified) : iModified(aModified)
       
  1127 		{
       
  1128 		}
       
  1129 		
       
  1130 	/**
       
  1131 	Symbian 2nd phase constructor
       
  1132 	*/
       
  1133 	void CSnapshot::ConstructL(const TDesC& aFileName)
       
  1134 		{
       
  1135 		iFileName = aFileName.AllocL();
       
  1136 		}
       
  1137 	
       
  1138 	/**
       
  1139 	Selection Type
       
  1140 	
       
  1141 	@return TSelectionType Type
       
  1142 	*/
       
  1143 	const TInt64& CSnapshot::Modified() const
       
  1144 		{
       
  1145 		return iModified;
       
  1146 		}
       
  1147 	
       
  1148 	/**
       
  1149 	Selection Name
       
  1150 	
       
  1151 	@return const TDesC& Name
       
  1152 	*/
       
  1153 	const TDesC& CSnapshot::FileName() const
       
  1154 		{
       
  1155 		return *iFileName;
       
  1156 		}
       
  1157 		
       
  1158 	/**
       
  1159 	Create snapshot of type TSnapshot
       
  1160 	
       
  1161 	@return TSnapshot snapshot
       
  1162 	
       
  1163 	*/
       
  1164 	void CSnapshot::Snapshot(TSnapshot& aSnapshot)
       
  1165 		{
       
  1166 		aSnapshot.iFileName = *iFileName;
       
  1167 		aSnapshot.iModified = iModified;
       
  1168 		}
       
  1169 		
       
  1170 	/**
       
  1171 	Method will be used for Sort on RPointerArray
       
  1172 	
       
  1173 	@param aFirst CSnapshot& snapshot to compare
       
  1174 	@param aSecond CSnapshot& snapshot to compare
       
  1175 	
       
  1176 	@see RArray::Sort()
       
  1177 	*/
       
  1178 	TInt CSnapshot::Compare(const CSnapshot& aFirst, const CSnapshot& aSecond)
       
  1179 		{
       
  1180 		return aFirst.FileName().CompareF(aSecond.FileName());
       
  1181 		}
       
  1182 		
       
  1183 	/**
       
  1184 	Method will be used for Find on RPointerArray
       
  1185 	
       
  1186 	@param aFirst CSnapshot& snapshot to match
       
  1187 	@param aSecond CSnapshot& snapshot to match
       
  1188 	
       
  1189 	@see RArray::Find()
       
  1190 	*/
       
  1191 	TBool CSnapshot::Match(const CSnapshot& aFirst, const CSnapshot& aSecond)
       
  1192 		{
       
  1193 		return (aFirst.FileName() == aSecond.FileName());
       
  1194 		}
       
  1195 
       
  1196 
       
  1197 	} // namespace conn
       
  1198