messagingfw/biomsgfw/BIUTSRC/BSP2.CPP
changeset 0 8e480a14352b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/biomsgfw/BIUTSRC/BSP2.CPP	Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,426 @@
+// Copyright (c) 2004-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:
+// BSP2.CPP
+//
+#include "BSP.H"
+#include "REGPSDLL.H"	// CRegisteredParserDll
+#include "msvapi.h"		// CMsvEntry
+#include <cbioasyncwaiter.h>
+
+#include <msvuids.h>	// KUidMsvMessageEntry, KUidMsvServiceEntry
+#include <msvids.h>
+#include <biouids.h>
+#include <biodb.h>
+#include <mmsvattachmentmanager.h>
+#include <mmsvattachmentmanagersync.h>
+#include <cmsvattachment.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS 
+#include "tmsvbioinfo.h"
+#include <biomessageuids.h>
+#include <bifchangeobserver.h>
+#endif
+
+// constants
+const TInt KMaxStringLength = 1024;
+const TInt KParsedFieldArrayGranularity = 16;
+const TInt KReadBufSize = 256;
+
+/** Constructor.
+
+This is called by CBIOServerMtm to create a parser object.
+
+@param aRegisteredParserDll Object that loaded the parser. It contains a reference 
+counter of the use of the parser.
+@param aEntry The message entry the parser should parse
+@param aFs Connected file server handle 
+*/
+EXPORT_C CBaseScriptParser2::CBaseScriptParser2(CRegisteredParserDll& aRegisteredParserDll,CMsvEntry& aEntry, RFs& aFs) :
+	CActive(EPriorityStandard), 
+	iRegisteredParserDll(aRegisteredParserDll), 
+	iEntry(aEntry), 
+	iFs(aFs), 
+	iEntryId(iEntry.Entry().Id())
+	{
+	}
+
+/** Destructor.
+
+This deletes iSettings and iReadBuffer and calls iRegisteredParserDll.ReleaseLibrary(). 
+*/
+EXPORT_C CBaseScriptParser2::~CBaseScriptParser2()
+	{
+	delete iReadBuffer;
+	delete iSettings;
+	iRegisteredParserDll.ReleaseLibrary();
+	}
+
+/** Utility function for unfolding Smart Messages.
+
+Nokia protocol allows for folding of long fields (see Nokia Smart Messaging 
+spec 2.0.0pre, 3-34 and RFC822, 3.1.1). This method unfolds the message by 
+deleting any linefeed characters which are followed immediately by linear 
+white space. It expects the buffer to be in iSmsBuf. 
+*/
+EXPORT_C void CBaseScriptParser2::UnfoldMessageL()
+    {
+    // Nokia protocol allows for folding of long fields (see Nokia Smart
+    // Messaging spec 2.0.0pre, 3-34 and RFC822, 3.1.1). This method
+    // unfolds the message by deleting any linefeed characters which are
+    // followed immediately by linear white space.
+    //   Note that the value returned by pBuf.Length() will change if
+    // linefeeds are deleted. Hence this is called for each iteration to
+    // avoid violating buffer bounds.
+
+    TPtr pBuf(iSmsBuf->Des());				// Create modifiable pointer to HBufC
+
+    for (TInt pos = 0; pos < (pBuf.Length() - 1); ++pos)
+        {
+        // Find linefeed followed by whitespace
+        if (pBuf[pos] == KCharLineFeed  &&
+            (pBuf[pos+1] == KCharSpace  ||  pBuf[pos+1] == KCharTab))
+            {
+            pBuf.Delete(pos, 1);
+            }
+        }
+    iSmsBuf = iSmsBuf->ReAllocL(pBuf.Length());		// Reallocate iSmsBuf with new size.
+    }
+
+void CBaseScriptParser2::InternalizeL(RMsvReadStream& aReadStream)
+	{
+	ResetL();
+	iParsedFieldArray = new(ELeave) CArrayPtrSeg<CParsedField>(KParsedFieldArrayGranularity);
+
+	CParsedField* parsedField(NULL);
+	TInt count = aReadStream.ReadUint8L();
+	for (TInt i=0; i < count; ++i)
+		{
+		parsedField = new (ELeave) CParsedField();
+		CleanupStack::PushL(parsedField);
+		parsedField->InternalizeL(aReadStream);
+		iParsedFieldArray->AppendL(parsedField);
+		CleanupStack::Pop(parsedField); 
+		}
+	}
+
+void CBaseScriptParser2::ExternalizeL(RMsvWriteStream& aStream) const
+	{
+	TInt count = iParsedFieldArray->Count();
+	aStream.WriteInt8L(count);
+	for (TInt number = 0; number<count; ++number) // must keep order, go forwards
+		{
+		aStream << *(*iParsedFieldArray)[number];
+		}
+	}
+
+/** Stores the parsed fields array.
+
+It stores the iParsedFieldArray array in the specified CMsvStore.
+
+@param aMsvStore Store to write to 
+*/
+EXPORT_C void CBaseScriptParser2::StoreL(CMsvStore& aMsvStore) const
+	{
+	RMsvWriteStream out;
+	out.AssignLC(aMsvStore, KUidMsvBIODataStream); // pushes 'out' to the stack
+	ExternalizeL(out);
+	out.CommitL();
+	out.Close(); // make sure we close the file
+	aMsvStore.CommitL();
+	CleanupStack::PopAndDestroy(); // out
+	}
+
+/** Restores the parsed fields array.
+
+It restores the iParsedFieldArray array from the specified CMsvStore.
+
+@param aMessageStore Store to read from 
+*/
+EXPORT_C void CBaseScriptParser2::RestoreL(CMsvStore& aMessageStore)
+	{
+	RMsvReadStream in;
+	in.OpenLC(aMessageStore, KUidMsvBIODataStream);
+	InternalizeL(in);
+	CleanupStack::PopAndDestroy(); // in
+	}
+
+/** Stores the message data in a specified file.
+
+It stores iSettings in the specified file.
+Write contents of Smart message to a file as attachment
+
+@param aFileName File to write to 
+*/
+EXPORT_C void CBaseScriptParser2::StoreL(const TFileName& aFileName) const
+	{
+	// Get the data contents, stored as 8-bit
+	TPtr dataContents = iSettings->Des();
+	HBufC8* buf = HBufC8::NewLC(dataContents.Length());
+	buf->Des().Copy(dataContents);
+	
+	// Create the attachment object and copy the data into the file
+	CMsvStore* store = iEntry.EditStoreL();
+	CleanupStack::PushL(store);
+	
+	
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	MMsvAttachmentManagerSync& managerSync = store->AttachmentManagerExtensionsL();
+	
+	// If an attachment already exists with the same filename then delete
+	// the existing one so multiple files of the same name dont exist
+	for( TInt ii=0; ii<manager.AttachmentCount(); ++ii )
+		{
+		CMsvAttachment* attachmentInfo = manager.GetAttachmentInfoL(ii);
+		CleanupStack::PushL(attachmentInfo);
+		if( attachmentInfo->AttachmentName().CompareF(aFileName) == 0 )
+			{
+			// We have a match, delete the attachment as we will have
+			// to add it as new one
+			managerSync.RemoveAttachmentL(ii);
+			CleanupStack::PopAndDestroy(attachmentInfo);
+			break;
+			}
+		CleanupStack::PopAndDestroy(attachmentInfo);
+		}
+		
+	// Create and add as a new attachment	
+	CMsvAttachment* attachment = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
+	CleanupStack::PushL(attachment);
+	attachment->SetSize(buf->Length());
+	attachment->SetAttachmentNameL(aFileName);
+		
+	RFile file;
+	managerSync.CreateAttachmentL(aFileName, file, attachment);
+	CleanupStack::Pop(attachment); // ownership passed to manager
+	CleanupClosePushL(file);
+	User::LeaveIfError(file.Write(*buf));
+	CleanupStack::PopAndDestroy(&file);
+	
+	// Commit the changes and cleanup
+	store->CommitL();
+	CleanupStack::PopAndDestroy(2, buf); // store, buf
+	}
+
+
+/** Restores the message data from a specified file.
+
+It restores iSettings from the specified file.
+
+@param aFileName File to read from 
+*/
+EXPORT_C void CBaseScriptParser2::RestoreL(const TFileName& aFileName)
+	{
+	// Find the attachment with the provided file name
+	CMsvStore* store = iEntry.ReadStoreL();
+	CleanupStack::PushL(store);
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	
+	TInt foundIndex = KErrNotFound;	
+	for( TInt ii=0; ii<manager.AttachmentCount(); ++ii )
+		{
+		CMsvAttachment* attachmentInfo = manager.GetAttachmentInfoL(ii);
+		if( attachmentInfo->AttachmentName().CompareF(aFileName) == 0 )
+			{
+			// found the attachment
+			foundIndex = ii;
+			delete attachmentInfo;
+			break;
+			}
+		delete attachmentInfo;
+		}
+	
+	// Leave if the attachment file has not been found
+	User::LeaveIfError(foundIndex);
+	
+	// Get the file attachment...
+	RFile file = manager.GetAttachmentFileL(foundIndex);
+	
+	CleanupStack::PopAndDestroy(store);
+	
+	CleanupClosePushL(file);
+
+	// read into descriptor resizing as we go
+	iReadBuffer = HBufC8::NewL(KReadBufSize);
+	TBuf8<KReadBufSize> fileChunk;
+	TInt fileErr = KErrNone;
+	while(fileErr==KErrNone)
+		{
+		fileErr = file.Read(fileChunk, fileChunk.MaxLength());
+		if(fileChunk.Length()==0)
+			break;
+		// check if we need to resize
+		TInt newLength = iReadBuffer->Des().Length() + fileChunk.Length();
+		if( newLength > iReadBuffer->Des().MaxLength())
+			{
+			iReadBuffer = iReadBuffer->ReAllocL(newLength);
+			}
+		iReadBuffer->Des().Append(fileChunk);
+		}
+	// if it worked stream data to it
+	// first copy data into 8-bit buffer (it's 8bit content anyway?)
+	CleanupStack::PopAndDestroy(&file); // file
+	User::LeaveIfError(fileErr);
+
+	delete iSettings;
+	iSettings = NULL;
+	iSettings = HBufC::NewL(iReadBuffer->Length());
+	iSettings->Des().Copy(iReadBuffer->Des());
+	} 
+
+/** Gets the UID of the BIO message type handled by the parser.
+
+@return BIO message type UID 
+*/
+EXPORT_C TUid CBaseScriptParser2::ParserUid()
+	{
+	return (iRegisteredParserDll.UidType()[2]);
+	}
+
+/** Deletes the iParsedFieldArray parsed fields array and sets it to NULL. 
+*/
+EXPORT_C void CBaseScriptParser2::ResetL()
+	{
+	// delete previous array and create a new one
+	if(iParsedFieldArray)
+		{
+		iParsedFieldArray->ResetAndDestroy();
+		delete iParsedFieldArray;
+		iParsedFieldArray=NULL;
+		}
+	}
+
+//
+// Class CParsed field container class for 
+// data item extracted from smart message
+//
+/** Constructor. */
+EXPORT_C CParsedField::CParsedField()
+	{
+	iFieldName =NULL;
+	iFieldValue =NULL;
+	iMandatoryField =ETrue;
+	}
+
+/** Destructor. */
+EXPORT_C CParsedField::~CParsedField()
+	{
+	delete iFieldName;
+	delete iFieldValue;
+	}
+
+
+/** Gets the field name.
+
+@return Field name 
+*/
+EXPORT_C TPtrC CParsedField::FieldName() const
+	{
+	return iFieldName->Des();
+	}
+
+
+/** Sets the field name.
+
+@param aFieldName Field name 
+*/
+EXPORT_C void CParsedField::SetFieldNameL(const TDesC& aFieldName)
+	{
+	HBufC* temp =aFieldName.AllocL();
+	delete iFieldName;
+	iFieldName = temp;	
+	}
+
+
+/** Gets the field value.
+
+@return Field value 
+*/
+EXPORT_C TPtrC CParsedField::FieldValue() const 
+	{
+	return iFieldValue->Des();
+	}
+
+
+/** Sets the field value.
+
+@param aFieldValue Field value 
+*/
+EXPORT_C void CParsedField::SetFieldValueL(const TDesC& aFieldValue)
+	{
+	HBufC* temp =aFieldValue.AllocL();
+	delete iFieldValue;
+	iFieldValue = temp;
+	}
+
+
+/** Tests if this is a mandatory field.
+
+@return True if this is a mandatory field 
+*/
+EXPORT_C TBool CParsedField::MandatoryField() const 
+	{
+	return iMandatoryField;
+	}
+
+
+/** Sets/unsets this as a mandatory field.
+
+@param aMandatoryField True if this is a mandatory field, false if not 
+*/
+EXPORT_C void CParsedField::SetMandatoryField(TBool aMandatoryField)
+	{
+	iMandatoryField = aMandatoryField;
+	}
+
+/** Internalises the object.
+
+@param aStream Stream to read from 
+*/
+EXPORT_C void CParsedField::InternalizeL(RReadStream& aStream)
+	{
+	Reset();
+	delete iFieldName;
+	iFieldName = NULL;
+	iFieldName = HBufC::NewL(aStream, KMaxStringLength);
+	TInt fieldValueLength = aStream.ReadInt16L();
+	delete iFieldValue;
+	iFieldValue = NULL;
+	iFieldValue = HBufC::NewL(aStream, fieldValueLength);
+	iMandatoryField = aStream.ReadInt8L();
+	}
+
+/** Externalises the object.
+
+@param aStream Stream to write to 
+*/
+EXPORT_C void CParsedField::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream << *iFieldName;
+	aStream.WriteUint16L(iFieldValue->Length());
+	aStream << *iFieldValue;
+	aStream.WriteUint8L(iMandatoryField ? 1 : 0);
+	}
+
+//
+// Reset contetnts of field
+//
+void CParsedField::Reset()
+	{
+	delete iFieldName;
+	iFieldName = NULL;
+
+	delete iFieldValue;
+	iFieldValue = NULL;
+
+	iMandatoryField= EFalse;
+	}