persistentstorage/dbms/pcdbms/tdbms/src/crccheck.cpp
changeset 0 08ec8eefde2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/pcdbms/tdbms/src/crccheck.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,262 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "crccheck.h"
+
+const TInt TDBMS_CRCChecks::SetSessionPath(const TDesC& aPath)
+	{
+	return ifs.SetSessionPath(aPath);
+	}
+
+TInt TDBMS_CRCChecks::FileCrcL(const RFile& aFile, TUint32 &asum)
+	{
+	const TInt KFileCrcBufSize = 1024;
+
+	TInt err;
+	TInt pos = 0;
+	// Seek to the beginning of the file.
+	if( (err = aFile.Seek(ESeekStart, pos)) != KErrNone)
+		return err;
+
+	RBuf8 buffer;
+	if((err = buffer.Create(KFileCrcBufSize)) != KErrNone)
+		return err;
+	CleanupClosePushL(buffer);
+	asum=0;
+	for(;;)
+		{
+		err = aFile.Read(buffer, KFileCrcBufSize);
+		if(err) break;
+		TInt len = buffer.Length();
+		if(len == 0) break;
+		Mem::Crc32(asum, (TAny*) buffer.Ptr(), len);
+		}
+	CleanupStack::PopAndDestroy(1, &buffer);
+	return err;
+	}
+
+const TInt TDBMS_CRCChecks::GenerateCrcL(const TPtrC aFile)
+	{
+	RFile file;
+	TInt err = file.Open(ifs, aFile, EFileRead);
+	RDebug::Print(_L("==================== File open=%S, err=%d\n"), &aFile, err);
+	if(err != KErrNone) 
+		return err;
+	CleanupClosePushL(file);
+
+	TestCheckInfo tcinf;
+	err = file.Size(tcinf.filesz);
+	if(err)
+		{
+		CleanupStack::PopAndDestroy(1);
+		return err;
+		}
+	err = FileCrcL(file, tcinf.crc);
+	if(err)
+		{
+		CleanupStack::PopAndDestroy(1);
+		return err;
+		}
+    err = iarray.Append(tcinf);
+	CleanupStack::PopAndDestroy(1);
+	return err;
+	}
+
+const TInt TDBMS_CRCChecks::RecordCount()
+	{
+	return iarray.Count();
+	}
+
+const TestCheckInfo TDBMS_CRCChecks::operator[](const TInt aidx)
+	{
+	return iarray[aidx];
+	}
+
+const TInt TDBMS_CRCChecks::DumpCrcRecordsL(const TDesC &alog)
+	{
+	RFile logfile;
+	TInt err = logfile.Replace(ifs, alog, EFileWrite);
+	RDebug::Print(_L("==================== File replace=%S, err=%d\n"), &alog, err);
+	if(err != KErrNone)
+		return err;
+	CleanupClosePushL(logfile);
+	TBuf8<0x100> output;
+
+	for(TInt i=0 ; i<RecordCount() ; i++)
+		{
+		output.SetLength(0);
+		TestCheckInfo tc = iarray[i];
+		output.AppendFormat(_L8("%d %d 0x%08x\n"), i+1, tc.filesz, tc.crc );
+		err = logfile.Write(output);
+		if(err) break;
+		}
+	CleanupStack::PopAndDestroy(1);
+	return err;
+	}
+
+const TInt TDBMS_CRCChecks::ValidateCrcRecordsL(const TDesC &alog)
+	{
+	RFile logfile;
+	TInt err = logfile.Open(ifs, alog, EFileRead);
+	RDebug::Print(_L("==================== File open=%S, err=%d\n"), &alog, err);
+	if(err != KErrNone)
+		return err;
+	CleanupClosePushL(logfile);
+   	
+	TInt logfilesz;
+	if((err = logfile.Size(logfilesz)) != KErrNone)
+		{
+		CleanupStack::PopAndDestroy(1);
+		return err;
+		}
+
+	RBuf8 input;
+	if((err = input.Create(logfilesz)) != KErrNone)
+		{
+		CleanupStack::PopAndDestroy(1);
+		return err;
+		}
+	CleanupClosePushL(input);
+	// Read the entire file.
+	err = logfile.Read(input);
+	if(err != KErrNone)
+		{
+		CleanupStack::PopAndDestroy(2);
+		return err;
+		}
+	TInt nread = input.Length();
+	if(nread != logfilesz)
+		{
+		CleanupStack::PopAndDestroy(2);
+		User::Leave(KErrCorrupt);  // wrong error.
+		}
+
+	TPtrC8 slice;
+	slice.Set(input);
+	TInt offset=0;
+	TBuf8<0x100> expected;
+	TInt i; // we check this after the loop...
+	for(i=0; ; i++)
+		{
+		// Find the next carriage return in the file. 'slice' represents
+		// the next bit of the file before the next carriage return.
+		// Will this break on Symbian? That has '\r\n'...
+		TInt nextcr = slice.Locate(TChar('\n'));
+		// If no carriage return is found we must have reached the end of
+		// the file.
+		if(nextcr == KErrNotFound)
+		  	break;
+		// 'got' is the current line from the file, including the carriage
+		// return.
+		TPtrC8 got = slice.Left(nextcr+1);
+
+		// Before we construct the string this object expects to see,
+		// check we're not out of array..
+		// The number of lines in the file we checking should match what
+		// we have in our internal array.
+		if(i >= iarray.Count())
+			{
+			err = ECrcCheckMoreRecords;
+			break;
+			}
+
+		// Construct a string from our internal data that is expected to be
+		// the same as the data read in from the crc file.
+		expected.SetLength(0);
+		TestCheckInfo tc = iarray[i];
+		expected.AppendFormat(_L8("%d %d 0x%08x\n"), i+1, tc.filesz, tc.crc );
+        // Compare what we've got to what we expect.
+		if(got.Compare(expected) != 0)
+			{
+			err = ECrcCheckMismatch;
+			break;
+			}
+
+		offset += nextcr + 1;
+		slice.Set(input.Mid(offset));
+		}
+	// The number of lines in the file we checking should match what
+	// we have in our internal array. Here this indicates that we seem to
+	// have more in our array than appear in the file.
+	if(!err && (i != iarray.Count()))
+		err = ECrcCheckFewerRecords;
+	CleanupStack::PopAndDestroy(2);
+	return err;
+	}
+
+const void TDBMS_CRCChecks::ErrorReportL(const TInt aerr, TPtrC& aerrmsg)
+	{
+	switch(aerr)
+		{
+		case KErrNotFound:
+				aerrmsg.Set(_L("Failed to open CRC log file.\n"));
+				break;
+		case KErrNoMemory:
+				aerrmsg.Set(_L("Out of memory.\n"));
+				break;
+		case KErrNone:
+		case ECrcCheckOk:
+				aerrmsg.Set(_L("CRC check ok.\n"));
+				break;
+		case ECrcCheckMismatch:
+				aerrmsg.Set(_L("CRC mismatch.\n"));
+				break;
+		case ECrcCheckFewerRecords:
+				aerrmsg.Set(_L("Fewer CRCs than in the file!\n"));
+				break;
+		case ECrcCheckMoreRecords:
+				aerrmsg.Set(_L("More CRCs in the file than I have!\n"));
+				break;
+		default:
+				aerrmsg.Set(_L("Broken!\n")); // PANIC?
+				break;
+		}
+	return;
+	}
+
+#ifdef CRC_TEST
+int E32Main(void)
+	{
+	CTrapCleanup *cleanup = CTrapCleanup::New();
+	__ASSERT_ALWAYS(cleanup != NULL, User::Invariant());
+
+	TDBMS_CRCChecks mycrc;
+	TInt err;
+   	TRAPD(lc, err = mycrc.GenerateCrcL(_L("crcchecks.mmp")));
+   	TRAP(lc, err = mycrc.GenerateCrcL(_L("bld.inf")));
+
+	TRAP(lc, err = mycrc.DumpCrcRecordsL(_L("wibble")));
+   	TRAP(lc, err = mycrc.GenerateCrcL(_L("t_alter.mmp")));
+	TRAP(lc, err = mycrc.ValidateCrcRecordsL(_L("wibble")));
+	switch(err)
+		{
+		case TDBMS_CRCChecks::ECrcCheckMismatch:
+				printf("Got CRC mismatch\n");
+				break;
+		case TDBMS_CRCChecks::ECrcCheckFewerRecords:
+				printf("I have more CRCs than in the file!\n");
+				break;
+		case TDBMS_CRCChecks::ECrcCheckMoreRecords:
+				printf("More CRCs in the file than I have!\n");
+				break;
+		default:
+				printf("Broken!\n");
+				break;
+		}
+	printf("Leavecode = %d, err = %d\n", lc, err );
+
+	delete cleanup;
+	}
+#endif