phonebookui/Phonebook/BCardEng/src/BCardEng.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *      A class to convert Phonebook items to vCard stream and vice versa
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "BCardEng.h" // This class
       
    22 
       
    23 // System APIs
       
    24 #include <s32mem.h>
       
    25 #include <barsc.h>
       
    26 #include <barsread.h>
       
    27 #include <cntfldst.h>
       
    28 #include <vcard.h>
       
    29 
       
    30 // Series 60 APIs
       
    31 #include <StringLoader.h>
       
    32 #include <featmgr.h>
       
    33 #include <bldvariant.hrh>
       
    34 
       
    35 // Phonebook APIs
       
    36 #include <PbkEngUtils.h>
       
    37 #include <CPbkContactEngine.h>
       
    38 #include <CPbkContactItem.h>
       
    39 #include <CPbkFieldsInfo.h>
       
    40 #include <CPbkFieldInfo.h>
       
    41 #include <CPbkAttachmentFile.h>
       
    42 #include <CPbkConstants.h>
       
    43 
       
    44 #include <BCardEng.rsg>
       
    45 #include "CBCardParserParamArray.h"
       
    46 #include "CBCardFieldAction.h"
       
    47 #include "CBCardFieldUidMapping.h"
       
    48 #include "CBCardExportProperty.h"
       
    49 #include "TPbkMatchPriorityLevel.h"
       
    50 #include "TBCardVersitPlugin.h"
       
    51 #include "CBCardParser.h"
       
    52 #include "PbkDataCaging.hrh"
       
    53 
       
    54 /// Unnamed namespace for local definitons
       
    55 namespace {
       
    56 
       
    57 // LOCAL CONSTANTS AND MACROS
       
    58 _LIT(KResFileName, "BCardEng.rsc");
       
    59 _LIT(KBusinessCardText, "Business Card");   // Business card signature
       
    60 _LIT(KCloseParenthesis, ")");
       
    61 _LIT(KTelText, "tel ");
       
    62 _LIT(KFaxText, "fax ");
       
    63 _LIT(KSeparatorText, ", ");
       
    64 
       
    65 const TText KOpenParenthesis = '(';
       
    66 const TInt KBufferSize = 200;
       
    67 const TInt KStartPosition = 4;
       
    68 const TInt KLabelStartPosition = 5;
       
    69 const TInt KLabelValueDelimiterLength = 2;
       
    70 
       
    71 } // namespace
       
    72 
       
    73 // ================= MEMBER FUNCTIONS =======================
       
    74 
       
    75 inline CBCardEngine::CBCardEngine()
       
    76     {
       
    77     }
       
    78 
       
    79 EXPORT_C CBCardEngine* CBCardEngine::NewL(CPbkContactEngine *aEngine)
       
    80     {
       
    81 	CBCardEngine* self = new(ELeave) CBCardEngine();
       
    82 	CleanupStack::PushL(self);
       
    83 	self->ConstructL(aEngine);
       
    84 	CleanupStack::Pop(self);
       
    85 	return self;
       
    86     }
       
    87 
       
    88 /*
       
    89  * ConstructL() reads the import/export definitions from the resource file
       
    90  * and stores them into class member arrays.
       
    91  */
       
    92 void CBCardEngine::ConstructL(CPbkContactEngine* aEngine)
       
    93     {
       
    94     // Open a file server session
       
    95     RFs fs;
       
    96 	User::LeaveIfError(fs.Connect());
       
    97     CleanupClosePushL(fs);
       
    98 
       
    99     // Initialize feature manager
       
   100     FeatureManager::InitializeLibL();
       
   101 
       
   102     // Open the resource file
       
   103     RResourceFile resourceFile;
       
   104     PbkEngUtils::FindAndOpenResourceFileLC(fs, KResFileName,
       
   105 		KDC_RESOURCE_FILES_DIR, KPbkRomFileDrive, resourceFile);
       
   106 
       
   107 	TResourceReader resReader;
       
   108 
       
   109 	// Read picture filenames
       
   110 	resReader.SetBuffer(resourceFile.AllocReadLC(R_QTN_BCARD_FILENAME_PICTURE));
       
   111 	iPictureFileName = resReader.ReadHBufCL();
       
   112     CleanupStack::PopAndDestroy();  // R_QTN_BCARD_FILENAME_PICTURE
       
   113 
       
   114 	resReader.SetBuffer(resourceFile.AllocReadLC(R_QTN_BCARD_FILENAME_THUMBNAIL));    
       
   115     iThumbnailFileName = resReader.ReadHBufCL();
       
   116     CleanupStack::PopAndDestroy();  // R_QTN_BCARD_FILENAME_THUMBNAIL
       
   117     
       
   118     // Read propery name (+index) <-> Uid mapping
       
   119     resReader.SetBuffer(resourceFile.AllocReadLC(R_PBK_BCARD_NAME_UID_MAPPING));
       
   120     iNameUidMap = CBCardFieldUidMapping::NewL(resReader);
       
   121     CleanupStack::PopAndDestroy(); // R_PBK_BCARD_NAME_UID_MAPPING
       
   122     
       
   123     // Read export properties
       
   124     resReader.SetBuffer(resourceFile.AllocReadLC(R_PBK_BCARD_EXPORT_VCARD));
       
   125 	TInt count = resReader.ReadInt16();
       
   126     while (--count >= 0)
       
   127         {
       
   128         CBCardExportProperty* property = 
       
   129             CBCardExportProperty::NewLC(resReader, aEngine->FieldsInfo());
       
   130         // Do not export non-existing fields, this check is required for
       
   131         // western version not to export japanese reading fields
       
   132         if (property->InfoCount() > 0)
       
   133             {
       
   134             // Array takes ownership of the property
       
   135             User::LeaveIfError(iExportProperties.Append(property));
       
   136             CleanupStack::Pop(property);
       
   137             }
       
   138         else
       
   139             {
       
   140             CleanupStack::PopAndDestroy(property);
       
   141             }
       
   142         }
       
   143     CleanupStack::PopAndDestroy(3);  // resourceFile, fs
       
   144     
       
   145     iEngine = aEngine;
       
   146     iFieldAction = CBCardFieldAction::NewL(
       
   147         *aEngine,*iNameUidMap, *iPictureFileName, *iThumbnailFileName);
       
   148     }
       
   149 
       
   150 EXPORT_C CBCardEngine::~CBCardEngine()
       
   151     {
       
   152     delete iNameUidMap;
       
   153 	delete iThumbnailFileName;
       
   154 	delete iPictureFileName;
       
   155     delete iFieldAction;
       
   156     iExportProperties.ResetAndDestroy();
       
   157     iExportProperties.Close();
       
   158     FeatureManager::UnInitializeLib();
       
   159     }
       
   160 
       
   161 /*
       
   162  * THE MAIN IMPORT FUNCTION
       
   163  * Properties are imported from vCard file according to the specifications
       
   164  * loaded from the resource file.
       
   165  */ 
       
   166 EXPORT_C void CBCardEngine::ImportBusinessCardL(
       
   167     CPbkContactItem& aDestItem, RReadStream &aSourceStream)
       
   168     {
       
   169     // Must use CParserVCard here, not the own parser class!
       
   170     // Otherwise there will be problems, and the parsing goes wrongly
       
   171     CParserVCard* parser = CParserVCard::NewL();
       
   172     CleanupStack::PushL(parser);
       
   173 
       
   174     if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
       
   175         {
       
   176         // if in Japanese mode, use shift-jis by default
       
   177         parser->SetDefaultCharSet(Versit::EShiftJISCharSet);
       
   178         parser->SetFlags(CVersitParser::EUseDefaultCharSetForAllProperties);
       
   179         }
       
   180 
       
   181     // This has to be trapped
       
   182     TRAPD(err,parser->InternalizeL(aSourceStream));        
       
   183     if ((err != KErrNone) && (err != KErrEof))
       
   184         {
       
   185         User::Leave(err);        
       
   186         }
       
   187 
       
   188     CArrayPtr<CParserProperty>* arr = parser->ArrayOfProperties(EFalse);   
       
   189     if (!arr)
       
   190         {
       
   191         // Return if there are no properties
       
   192         CleanupStack::PopAndDestroy(parser); 
       
   193         return;
       
   194         }
       
   195 
       
   196     // Loop through different prioritylevels
       
   197     for (TPbkMatchPriorityLevel priorityLevel(iEngine->FieldsInfo().CreateMatchPriority());
       
   198         !priorityLevel.End(); 
       
   199         priorityLevel.Next())
       
   200         {
       
   201         // Loop through all the fields
       
   202         for (TInt i=0; i<arr->Count(); i++)
       
   203             {
       
   204             CParserProperty* prop = arr->At(i);        
       
   205             if (prop)
       
   206                 {
       
   207                 iFieldAction->AddFieldL(aDestItem, *prop, priorityLevel);
       
   208                 }    
       
   209             }
       
   210         }
       
   211 
       
   212     CleanupStack::PopAndDestroy(parser); // parser
       
   213     }
       
   214 
       
   215 /**
       
   216  * The main Export function.
       
   217  */
       
   218 EXPORT_C void CBCardEngine::ExportBusinessCardL(
       
   219         RWriteStream& aDestStream, 
       
   220         CPbkContactItem& aSourceItem)
       
   221     {
       
   222     CParserVCard* parser = CParserVCard::NewL();
       
   223     CleanupStack::PushL(parser);
       
   224     
       
   225     // For Japanese: Set charset based on local variation setting
       
   226     if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
       
   227         {
       
   228         if (iEngine->Constants()->LocallyVariatedFeatureEnabled(EPbkLVUseJapaneseUTF8))
       
   229             {
       
   230             parser->SetDefaultCharSet(Versit::EUTF8CharSet);
       
   231             }
       
   232         else
       
   233             {
       
   234             parser->SetDefaultCharSet(Versit::EShiftJISCharSet);
       
   235             }
       
   236         parser->SetFlags(CVersitParser::EUseDefaultCharSetForAllProperties);
       
   237         }
       
   238     
       
   239     // use plug in for disabling encoding
       
   240     TBCardVersitPlugin* exportPlugin = new (ELeave) TBCardVersitPlugin;
       
   241     CleanupStack::PushL(exportPlugin);
       
   242     parser->SetPlugIn(exportPlugin);
       
   243 
       
   244     for (TInt i = 0; i < iExportProperties.Count(); i++)
       
   245         {
       
   246         ProcessExportPropertyL(*parser, aSourceItem, *iExportProperties[i]);       
       
   247         }
       
   248 
       
   249     // Externalize the Parser to the Stream
       
   250     parser->ExternalizeL(aDestStream);
       
   251 
       
   252     CleanupStack::PopAndDestroy(exportPlugin);
       
   253     CleanupStack::PopAndDestroy(parser);
       
   254     }
       
   255 
       
   256 void CBCardEngine::ProcessExportPropertyL(
       
   257         CParserVCard& aParser, 
       
   258         CPbkContactItem& aSourceItem, 
       
   259         const CBCardExportProperty& aExportProperty)
       
   260     {
       
   261     if (aExportProperty.StorageType() == EPbkVersitPropertyCDesCArray)
       
   262         {
       
   263         iFieldAction->ExportArrayOfFieldsL(aParser, aSourceItem, aExportProperty);
       
   264         }
       
   265     else
       
   266         {
       
   267         const CPbkFieldInfo* info = aExportProperty.InfoAt(0);
       
   268         
       
   269         TBool doContinue = (info->Multiplicity() == EPbkFieldMultiplicityMany);
       
   270         
       
   271         TInt index = 0;
       
   272         do 
       
   273             {           
       
   274             TPbkContactItemField* field = aSourceItem.FindField(*info, index);            
       
   275             if (field)
       
   276                 {
       
   277                 ++index;
       
   278                 iFieldAction->ExportContactFieldL(
       
   279                     aExportProperty, 
       
   280                     aParser, 
       
   281                     aSourceItem, 
       
   282                     *field);
       
   283                 }
       
   284             else
       
   285                 {
       
   286                 doContinue = EFalse;
       
   287                 }
       
   288         
       
   289             } while (doContinue);
       
   290         }
       
   291     }
       
   292 
       
   293 TInt CBCardEngine::GetByteFromStream(TUint8& aByte, RReadStream& aSourceStream)
       
   294     {
       
   295     TRAPD(err, aByte = aSourceStream.ReadUint8L());
       
   296     return err;
       
   297     }
       
   298 
       
   299 TInt CBCardEngine::GetLineFromStreamL(TDes& aBuf, RReadStream& aSourceStream)
       
   300     {
       
   301     aBuf.SetLength(0);
       
   302     TUint8 byte=0;
       
   303     while(GetByteFromStream(byte, aSourceStream) == KErrNone)
       
   304         {
       
   305         if(byte == EKeyLineFeed)
       
   306             {
       
   307             break;
       
   308             }
       
   309         if(byte != EKeyEnter)
       
   310             {
       
   311             if (aBuf.Length() < aBuf.MaxLength())
       
   312                 {
       
   313                 aBuf.Append(byte);
       
   314                 }
       
   315             else
       
   316                 {
       
   317                 User::Leave(KErrCorrupt);
       
   318                 }
       
   319             }
       
   320         }
       
   321     return aBuf.Length();
       
   322     }
       
   323 
       
   324 EXPORT_C TBool CBCardEngine::ImportCompactBusinessCardL(
       
   325     CPbkContactItem& aDestItem, RReadStream &aSourceStream)
       
   326     {
       
   327     TBuf<KBufferSize> buf;
       
   328 
       
   329     // "Business Card" signature
       
   330     if(GetLineFromStreamL(buf, aSourceStream))
       
   331         {
       
   332         if(buf.Match(KBusinessCardText)==KErrNotFound)
       
   333             {
       
   334             return EFalse;
       
   335             }
       
   336         }        
       
   337 
       
   338     // Name
       
   339     if(GetLineFromStreamL(buf, aSourceStream))
       
   340         {
       
   341         iFieldAction->AddCompactCardFieldL(aDestItem, EPbkFieldIdLastName, buf);
       
   342         }
       
   343 
       
   344     // Company
       
   345     if(GetLineFromStreamL(buf, aSourceStream))
       
   346         {
       
   347         iFieldAction->AddCompactCardFieldL(aDestItem, EPbkFieldIdCompanyName, buf);
       
   348         }
       
   349 
       
   350     // Title
       
   351     if(GetLineFromStreamL(buf, aSourceStream))
       
   352         {
       
   353         iFieldAction->AddCompactCardFieldL(aDestItem, EPbkFieldIdJobTitle, buf);
       
   354         }
       
   355 
       
   356     // Telephone numbers
       
   357     TInt len=0;
       
   358     while((len = GetLineFromStreamL(buf, aSourceStream))>0)
       
   359         {
       
   360         TPbkFieldId fieldid = EPbkFieldIdNone;
       
   361         if(buf.Find(KTelText)>=0)
       
   362             {
       
   363             fieldid = EPbkFieldIdPhoneNumberStandard;
       
   364             } 
       
   365         else if(buf.Find(KFaxText)>=0) 
       
   366             {
       
   367             fieldid = EPbkFieldIdFaxNumber;
       
   368             }
       
   369 
       
   370         if(fieldid == EPbkFieldIdNone)
       
   371             {
       
   372             break;
       
   373             }
       
   374         else if(len <= KStartPosition)
       
   375             {
       
   376             // no data on this field, try next
       
   377             continue;
       
   378             }
       
   379         
       
   380 		// Read tel num label
       
   381 		TInt position = KStartPosition;
       
   382         HBufC* label = NULL;
       
   383         if(buf[KStartPosition] == KOpenParenthesis)
       
   384             {
       
   385             position = buf.Find(KCloseParenthesis);
       
   386             if(position == KErrNotFound)
       
   387                 {
       
   388                 continue;
       
   389                 }
       
   390             label = HBufC::NewLC(position-KStartPosition);
       
   391     		TPtr writebuf = label->Des();
       
   392 	    	writebuf = KNullDesC;
       
   393             for(TInt i=KLabelStartPosition; i<position; i++)
       
   394                 {
       
   395                 writebuf.Append(buf[i]);
       
   396                 }
       
   397 			// Jump few characters
       
   398             position += KLabelValueDelimiterLength;
       
   399             }
       
   400             
       
   401         if(position < buf.Length())
       
   402             {
       
   403     		// Read value
       
   404             HBufC* value = HBufC::NewLC(buf.Length()-position);
       
   405        		TPtr writebuf = value->Des();
       
   406         	writebuf = KNullDesC;
       
   407             for(TInt i=position; i<buf.Length(); i++)
       
   408                 {
       
   409                 writebuf.Append(buf[i]);
       
   410                 }
       
   411 
       
   412     		iFieldAction->AddCompactCardFieldL(aDestItem, fieldid,
       
   413     			*value, EFalse, label);
       
   414 
       
   415             CleanupStack::PopAndDestroy(value); 
       
   416             }
       
   417             
       
   418         if(label)
       
   419             {
       
   420             CleanupStack::PopAndDestroy(label); 
       
   421             }
       
   422         }
       
   423 
       
   424     // Email address
       
   425     if(len)
       
   426         {
       
   427         iFieldAction->AddCompactCardFieldL(aDestItem,
       
   428 			EPbkFieldIdEmailAddress, buf);
       
   429         }
       
   430 
       
   431     // Postal address (one or more lines)
       
   432     // First read all the address lines and store them
       
   433     // in a list
       
   434     CDesCArray* arr = new(ELeave) CDesCArrayFlat(2); // typically 2 lines
       
   435     CleanupStack::PushL(arr);
       
   436     len=0;
       
   437     while(GetLineFromStreamL(buf, aSourceStream))
       
   438         {
       
   439         arr->AppendL(buf);
       
   440         if(len)
       
   441             {
       
   442             len+=KSeparatorText().Length();
       
   443             }
       
   444         len+=buf.Length();
       
   445         }
       
   446 
       
   447     // Then concatenate them with commas into one string
       
   448     // and use that as field value.
       
   449     HBufC* fielddata = HBufC::NewLC(len);
       
   450 	TPtr writebuf = fielddata->Des();
       
   451 	writebuf = KNullDesC;
       
   452     for(TInt i=0;i<arr->Count();i++)
       
   453         {
       
   454         if(i)
       
   455             {
       
   456             writebuf.Append(KSeparatorText);
       
   457             }
       
   458         writebuf.Append(arr->MdcaPoint(i));
       
   459         }
       
   460 
       
   461     iFieldAction->AddCompactCardFieldL(aDestItem, EPbkFieldIdPostalAddress,
       
   462 		*fielddata);
       
   463     
       
   464     CleanupStack::PopAndDestroy(2); // fielddata, arr
       
   465 
       
   466     return ETrue;
       
   467     }
       
   468 
       
   469 EXPORT_C TBool CBCardEngine::SupportsFieldType(TPbkFieldId aFieldId)
       
   470     {
       
   471     TBool isSupported = EFalse;
       
   472     CBCardExportProperty* property;
       
   473     
       
   474     // Go trough the array of supported fields and try to find the fieldId
       
   475     for (TInt i=0; i < iExportProperties.Count(); i++)
       
   476         {
       
   477         property = iExportProperties[i];
       
   478         for (TInt j=0; j < property->InfoCount(); j++)
       
   479             {
       
   480             if (property->InfoAt(j)->FieldId() == aFieldId)
       
   481                 {
       
   482                 isSupported = ETrue;
       
   483                 break;
       
   484                 }
       
   485             }
       
   486         }
       
   487     return isSupported;
       
   488     }
       
   489 
       
   490 // End of File