messagingfw/biomsgfw/BIUTSRC/BSP2.CPP
changeset 62 db3f5fa34ec7
parent 0 8e480a14352b
equal deleted inserted replaced
60:9f5ae1728557 62:db3f5fa34ec7
       
     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 // BSP2.CPP
       
    15 //
       
    16 #include "BSP.H"
       
    17 #include "REGPSDLL.H"	// CRegisteredParserDll
       
    18 #include "msvapi.h"		// CMsvEntry
       
    19 #include <cbioasyncwaiter.h>
       
    20 
       
    21 #include <msvuids.h>	// KUidMsvMessageEntry, KUidMsvServiceEntry
       
    22 #include <msvids.h>
       
    23 #include <biouids.h>
       
    24 #include <biodb.h>
       
    25 #include <mmsvattachmentmanager.h>
       
    26 #include <mmsvattachmentmanagersync.h>
       
    27 #include <cmsvattachment.h>
       
    28 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS 
       
    29 #include "tmsvbioinfo.h"
       
    30 #include <biomessageuids.h>
       
    31 #include <bifchangeobserver.h>
       
    32 #endif
       
    33 
       
    34 // constants
       
    35 const TInt KMaxStringLength = 1024;
       
    36 const TInt KParsedFieldArrayGranularity = 16;
       
    37 const TInt KReadBufSize = 256;
       
    38 
       
    39 /** Constructor.
       
    40 
       
    41 This is called by CBIOServerMtm to create a parser object.
       
    42 
       
    43 @param aRegisteredParserDll Object that loaded the parser. It contains a reference 
       
    44 counter of the use of the parser.
       
    45 @param aEntry The message entry the parser should parse
       
    46 @param aFs Connected file server handle 
       
    47 */
       
    48 EXPORT_C CBaseScriptParser2::CBaseScriptParser2(CRegisteredParserDll& aRegisteredParserDll,CMsvEntry& aEntry, RFs& aFs) :
       
    49 	CActive(EPriorityStandard), 
       
    50 	iRegisteredParserDll(aRegisteredParserDll), 
       
    51 	iEntry(aEntry), 
       
    52 	iFs(aFs), 
       
    53 	iEntryId(iEntry.Entry().Id())
       
    54 	{
       
    55 	}
       
    56 
       
    57 /** Destructor.
       
    58 
       
    59 This deletes iSettings and iReadBuffer and calls iRegisteredParserDll.ReleaseLibrary(). 
       
    60 */
       
    61 EXPORT_C CBaseScriptParser2::~CBaseScriptParser2()
       
    62 	{
       
    63 	delete iReadBuffer;
       
    64 	delete iSettings;
       
    65 	iRegisteredParserDll.ReleaseLibrary();
       
    66 	}
       
    67 
       
    68 /** Utility function for unfolding Smart Messages.
       
    69 
       
    70 Nokia protocol allows for folding of long fields (see Nokia Smart Messaging 
       
    71 spec 2.0.0pre, 3-34 and RFC822, 3.1.1). This method unfolds the message by 
       
    72 deleting any linefeed characters which are followed immediately by linear 
       
    73 white space. It expects the buffer to be in iSmsBuf. 
       
    74 */
       
    75 EXPORT_C void CBaseScriptParser2::UnfoldMessageL()
       
    76     {
       
    77     // Nokia protocol allows for folding of long fields (see Nokia Smart
       
    78     // Messaging spec 2.0.0pre, 3-34 and RFC822, 3.1.1). This method
       
    79     // unfolds the message by deleting any linefeed characters which are
       
    80     // followed immediately by linear white space.
       
    81     //   Note that the value returned by pBuf.Length() will change if
       
    82     // linefeeds are deleted. Hence this is called for each iteration to
       
    83     // avoid violating buffer bounds.
       
    84 
       
    85     TPtr pBuf(iSmsBuf->Des());				// Create modifiable pointer to HBufC
       
    86 
       
    87     for (TInt pos = 0; pos < (pBuf.Length() - 1); ++pos)
       
    88         {
       
    89         // Find linefeed followed by whitespace
       
    90         if (pBuf[pos] == KCharLineFeed  &&
       
    91             (pBuf[pos+1] == KCharSpace  ||  pBuf[pos+1] == KCharTab))
       
    92             {
       
    93             pBuf.Delete(pos, 1);
       
    94             }
       
    95         }
       
    96     iSmsBuf = iSmsBuf->ReAllocL(pBuf.Length());		// Reallocate iSmsBuf with new size.
       
    97     }
       
    98 
       
    99 void CBaseScriptParser2::InternalizeL(RMsvReadStream& aReadStream)
       
   100 	{
       
   101 	ResetL();
       
   102 	iParsedFieldArray = new(ELeave) CArrayPtrSeg<CParsedField>(KParsedFieldArrayGranularity);
       
   103 
       
   104 	CParsedField* parsedField(NULL);
       
   105 	TInt count = aReadStream.ReadUint8L();
       
   106 	for (TInt i=0; i < count; ++i)
       
   107 		{
       
   108 		parsedField = new (ELeave) CParsedField();
       
   109 		CleanupStack::PushL(parsedField);
       
   110 		parsedField->InternalizeL(aReadStream);
       
   111 		iParsedFieldArray->AppendL(parsedField);
       
   112 		CleanupStack::Pop(parsedField); 
       
   113 		}
       
   114 	}
       
   115 
       
   116 void CBaseScriptParser2::ExternalizeL(RMsvWriteStream& aStream) const
       
   117 	{
       
   118 	TInt count = iParsedFieldArray->Count();
       
   119 	aStream.WriteInt8L(count);
       
   120 	for (TInt number = 0; number<count; ++number) // must keep order, go forwards
       
   121 		{
       
   122 		aStream << *(*iParsedFieldArray)[number];
       
   123 		}
       
   124 	}
       
   125 
       
   126 /** Stores the parsed fields array.
       
   127 
       
   128 It stores the iParsedFieldArray array in the specified CMsvStore.
       
   129 
       
   130 @param aMsvStore Store to write to 
       
   131 */
       
   132 EXPORT_C void CBaseScriptParser2::StoreL(CMsvStore& aMsvStore) const
       
   133 	{
       
   134 	RMsvWriteStream out;
       
   135 	out.AssignLC(aMsvStore, KUidMsvBIODataStream); // pushes 'out' to the stack
       
   136 	ExternalizeL(out);
       
   137 	out.CommitL();
       
   138 	out.Close(); // make sure we close the file
       
   139 	aMsvStore.CommitL();
       
   140 	CleanupStack::PopAndDestroy(); // out
       
   141 	}
       
   142 
       
   143 /** Restores the parsed fields array.
       
   144 
       
   145 It restores the iParsedFieldArray array from the specified CMsvStore.
       
   146 
       
   147 @param aMessageStore Store to read from 
       
   148 */
       
   149 EXPORT_C void CBaseScriptParser2::RestoreL(CMsvStore& aMessageStore)
       
   150 	{
       
   151 	RMsvReadStream in;
       
   152 	in.OpenLC(aMessageStore, KUidMsvBIODataStream);
       
   153 	InternalizeL(in);
       
   154 	CleanupStack::PopAndDestroy(); // in
       
   155 	}
       
   156 
       
   157 /** Stores the message data in a specified file.
       
   158 
       
   159 It stores iSettings in the specified file.
       
   160 Write contents of Smart message to a file as attachment
       
   161 
       
   162 @param aFileName File to write to 
       
   163 */
       
   164 EXPORT_C void CBaseScriptParser2::StoreL(const TFileName& aFileName) const
       
   165 	{
       
   166 	// Get the data contents, stored as 8-bit
       
   167 	TPtr dataContents = iSettings->Des();
       
   168 	HBufC8* buf = HBufC8::NewLC(dataContents.Length());
       
   169 	buf->Des().Copy(dataContents);
       
   170 	
       
   171 	// Create the attachment object and copy the data into the file
       
   172 	CMsvStore* store = iEntry.EditStoreL();
       
   173 	CleanupStack::PushL(store);
       
   174 	
       
   175 	
       
   176 	MMsvAttachmentManager& manager = store->AttachmentManagerL();
       
   177 	MMsvAttachmentManagerSync& managerSync = store->AttachmentManagerExtensionsL();
       
   178 	
       
   179 	// If an attachment already exists with the same filename then delete
       
   180 	// the existing one so multiple files of the same name dont exist
       
   181 	for( TInt ii=0; ii<manager.AttachmentCount(); ++ii )
       
   182 		{
       
   183 		CMsvAttachment* attachmentInfo = manager.GetAttachmentInfoL(ii);
       
   184 		CleanupStack::PushL(attachmentInfo);
       
   185 		if( attachmentInfo->AttachmentName().CompareF(aFileName) == 0 )
       
   186 			{
       
   187 			// We have a match, delete the attachment as we will have
       
   188 			// to add it as new one
       
   189 			managerSync.RemoveAttachmentL(ii);
       
   190 			CleanupStack::PopAndDestroy(attachmentInfo);
       
   191 			break;
       
   192 			}
       
   193 		CleanupStack::PopAndDestroy(attachmentInfo);
       
   194 		}
       
   195 		
       
   196 	// Create and add as a new attachment	
       
   197 	CMsvAttachment* attachment = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
       
   198 	CleanupStack::PushL(attachment);
       
   199 	attachment->SetSize(buf->Length());
       
   200 	attachment->SetAttachmentNameL(aFileName);
       
   201 		
       
   202 	RFile file;
       
   203 	managerSync.CreateAttachmentL(aFileName, file, attachment);
       
   204 	CleanupStack::Pop(attachment); // ownership passed to manager
       
   205 	CleanupClosePushL(file);
       
   206 	User::LeaveIfError(file.Write(*buf));
       
   207 	CleanupStack::PopAndDestroy(&file);
       
   208 	
       
   209 	// Commit the changes and cleanup
       
   210 	store->CommitL();
       
   211 	CleanupStack::PopAndDestroy(2, buf); // store, buf
       
   212 	}
       
   213 
       
   214 
       
   215 /** Restores the message data from a specified file.
       
   216 
       
   217 It restores iSettings from the specified file.
       
   218 
       
   219 @param aFileName File to read from 
       
   220 */
       
   221 EXPORT_C void CBaseScriptParser2::RestoreL(const TFileName& aFileName)
       
   222 	{
       
   223 	// Find the attachment with the provided file name
       
   224 	CMsvStore* store = iEntry.ReadStoreL();
       
   225 	CleanupStack::PushL(store);
       
   226 	MMsvAttachmentManager& manager = store->AttachmentManagerL();
       
   227 	
       
   228 	TInt foundIndex = KErrNotFound;	
       
   229 	for( TInt ii=0; ii<manager.AttachmentCount(); ++ii )
       
   230 		{
       
   231 		CMsvAttachment* attachmentInfo = manager.GetAttachmentInfoL(ii);
       
   232 		if( attachmentInfo->AttachmentName().CompareF(aFileName) == 0 )
       
   233 			{
       
   234 			// found the attachment
       
   235 			foundIndex = ii;
       
   236 			delete attachmentInfo;
       
   237 			break;
       
   238 			}
       
   239 		delete attachmentInfo;
       
   240 		}
       
   241 	
       
   242 	// Leave if the attachment file has not been found
       
   243 	User::LeaveIfError(foundIndex);
       
   244 	
       
   245 	// Get the file attachment...
       
   246 	RFile file = manager.GetAttachmentFileL(foundIndex);
       
   247 	
       
   248 	CleanupStack::PopAndDestroy(store);
       
   249 	
       
   250 	CleanupClosePushL(file);
       
   251 
       
   252 	// read into descriptor resizing as we go
       
   253 	iReadBuffer = HBufC8::NewL(KReadBufSize);
       
   254 	TBuf8<KReadBufSize> fileChunk;
       
   255 	TInt fileErr = KErrNone;
       
   256 	while(fileErr==KErrNone)
       
   257 		{
       
   258 		fileErr = file.Read(fileChunk, fileChunk.MaxLength());
       
   259 		if(fileChunk.Length()==0)
       
   260 			break;
       
   261 		// check if we need to resize
       
   262 		TInt newLength = iReadBuffer->Des().Length() + fileChunk.Length();
       
   263 		if( newLength > iReadBuffer->Des().MaxLength())
       
   264 			{
       
   265 			iReadBuffer = iReadBuffer->ReAllocL(newLength);
       
   266 			}
       
   267 		iReadBuffer->Des().Append(fileChunk);
       
   268 		}
       
   269 	// if it worked stream data to it
       
   270 	// first copy data into 8-bit buffer (it's 8bit content anyway?)
       
   271 	CleanupStack::PopAndDestroy(&file); // file
       
   272 	User::LeaveIfError(fileErr);
       
   273 
       
   274 	delete iSettings;
       
   275 	iSettings = NULL;
       
   276 	iSettings = HBufC::NewL(iReadBuffer->Length());
       
   277 	iSettings->Des().Copy(iReadBuffer->Des());
       
   278 	} 
       
   279 
       
   280 /** Gets the UID of the BIO message type handled by the parser.
       
   281 
       
   282 @return BIO message type UID 
       
   283 */
       
   284 EXPORT_C TUid CBaseScriptParser2::ParserUid()
       
   285 	{
       
   286 	return (iRegisteredParserDll.UidType()[2]);
       
   287 	}
       
   288 
       
   289 /** Deletes the iParsedFieldArray parsed fields array and sets it to NULL. 
       
   290 */
       
   291 EXPORT_C void CBaseScriptParser2::ResetL()
       
   292 	{
       
   293 	// delete previous array and create a new one
       
   294 	if(iParsedFieldArray)
       
   295 		{
       
   296 		iParsedFieldArray->ResetAndDestroy();
       
   297 		delete iParsedFieldArray;
       
   298 		iParsedFieldArray=NULL;
       
   299 		}
       
   300 	}
       
   301 
       
   302 //
       
   303 // Class CParsed field container class for 
       
   304 // data item extracted from smart message
       
   305 //
       
   306 /** Constructor. */
       
   307 EXPORT_C CParsedField::CParsedField()
       
   308 	{
       
   309 	iFieldName =NULL;
       
   310 	iFieldValue =NULL;
       
   311 	iMandatoryField =ETrue;
       
   312 	}
       
   313 
       
   314 /** Destructor. */
       
   315 EXPORT_C CParsedField::~CParsedField()
       
   316 	{
       
   317 	delete iFieldName;
       
   318 	delete iFieldValue;
       
   319 	}
       
   320 
       
   321 
       
   322 /** Gets the field name.
       
   323 
       
   324 @return Field name 
       
   325 */
       
   326 EXPORT_C TPtrC CParsedField::FieldName() const
       
   327 	{
       
   328 	return iFieldName->Des();
       
   329 	}
       
   330 
       
   331 
       
   332 /** Sets the field name.
       
   333 
       
   334 @param aFieldName Field name 
       
   335 */
       
   336 EXPORT_C void CParsedField::SetFieldNameL(const TDesC& aFieldName)
       
   337 	{
       
   338 	HBufC* temp =aFieldName.AllocL();
       
   339 	delete iFieldName;
       
   340 	iFieldName = temp;	
       
   341 	}
       
   342 
       
   343 
       
   344 /** Gets the field value.
       
   345 
       
   346 @return Field value 
       
   347 */
       
   348 EXPORT_C TPtrC CParsedField::FieldValue() const 
       
   349 	{
       
   350 	return iFieldValue->Des();
       
   351 	}
       
   352 
       
   353 
       
   354 /** Sets the field value.
       
   355 
       
   356 @param aFieldValue Field value 
       
   357 */
       
   358 EXPORT_C void CParsedField::SetFieldValueL(const TDesC& aFieldValue)
       
   359 	{
       
   360 	HBufC* temp =aFieldValue.AllocL();
       
   361 	delete iFieldValue;
       
   362 	iFieldValue = temp;
       
   363 	}
       
   364 
       
   365 
       
   366 /** Tests if this is a mandatory field.
       
   367 
       
   368 @return True if this is a mandatory field 
       
   369 */
       
   370 EXPORT_C TBool CParsedField::MandatoryField() const 
       
   371 	{
       
   372 	return iMandatoryField;
       
   373 	}
       
   374 
       
   375 
       
   376 /** Sets/unsets this as a mandatory field.
       
   377 
       
   378 @param aMandatoryField True if this is a mandatory field, false if not 
       
   379 */
       
   380 EXPORT_C void CParsedField::SetMandatoryField(TBool aMandatoryField)
       
   381 	{
       
   382 	iMandatoryField = aMandatoryField;
       
   383 	}
       
   384 
       
   385 /** Internalises the object.
       
   386 
       
   387 @param aStream Stream to read from 
       
   388 */
       
   389 EXPORT_C void CParsedField::InternalizeL(RReadStream& aStream)
       
   390 	{
       
   391 	Reset();
       
   392 	delete iFieldName;
       
   393 	iFieldName = NULL;
       
   394 	iFieldName = HBufC::NewL(aStream, KMaxStringLength);
       
   395 	TInt fieldValueLength = aStream.ReadInt16L();
       
   396 	delete iFieldValue;
       
   397 	iFieldValue = NULL;
       
   398 	iFieldValue = HBufC::NewL(aStream, fieldValueLength);
       
   399 	iMandatoryField = aStream.ReadInt8L();
       
   400 	}
       
   401 
       
   402 /** Externalises the object.
       
   403 
       
   404 @param aStream Stream to write to 
       
   405 */
       
   406 EXPORT_C void CParsedField::ExternalizeL(RWriteStream& aStream) const
       
   407 	{
       
   408 	aStream << *iFieldName;
       
   409 	aStream.WriteUint16L(iFieldValue->Length());
       
   410 	aStream << *iFieldValue;
       
   411 	aStream.WriteUint8L(iMandatoryField ? 1 : 0);
       
   412 	}
       
   413 
       
   414 //
       
   415 // Reset contetnts of field
       
   416 //
       
   417 void CParsedField::Reset()
       
   418 	{
       
   419 	delete iFieldName;
       
   420 	iFieldName = NULL;
       
   421 
       
   422 	delete iFieldValue;
       
   423 	iFieldValue = NULL;
       
   424 
       
   425 	iMandatoryField= EFalse;
       
   426 	}