--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/widgetinstaller/Src/WidgetBackupRegistryXml.cpp Thu Aug 27 07:44:59 2009 +0300
@@ -0,0 +1,550 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: Processes registry persistent data in XML.
+*
+*/
+
+
+#include <e32base.h>
+#include <f32file.h>
+#include <libxml2_globals.h>
+#include <libxml2_parser.h>
+#include <charconv.h>
+#include "WidgetBackupRegistryXml.h"
+
+_LIT( KPropertyListVersion, "PropertyListVersion" );
+_LIT( KBundleIdentifier, "BundleIdentifier" );
+_LIT( KBundleName, "BundleName" );
+_LIT( KBundleDisplayName, "BundleDisplayName" );
+_LIT( KMainHTML, "MainHTML" );
+_LIT( KBundleShortVersion, "BundleShortVersion" );
+_LIT( KBundleVersion, "BundleVersion" );
+_LIT( KHeight, "Height" );
+_LIT( KWidth, "Width" );
+_LIT( KAllowFullAccess, "AllowFullAccess" );
+_LIT( KAllowNetworkAccess, "AllowNetworkAccess" );
+_LIT( KDriveName, "DriveName" );
+_LIT( KBasePath, "BasePath" );
+_LIT( KIconPath, "IconPath" );
+_LIT( KUrl, "Url" );
+_LIT( KFileSize, "FileSize" );
+_LIT( KUid, "Uid" );
+_LIT( KNokiaWidget, "NokiaWidget" );
+_LIT( KMiniViewEnabled, "MiniViewEnabled" );
+_LIT( KBlanketPermGranted, "BlanketPermissionGranted" ); // optional
+
+// ============================================================================
+// CWidgetBackupRegistryXml::NewL()
+// two-phase constructor
+//
+// @since 5.0
+// ============================================================================
+//
+CWidgetBackupRegistryXml* CWidgetBackupRegistryXml::NewL()
+ {
+ CWidgetBackupRegistryXml *self = new (ELeave) CWidgetBackupRegistryXml();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// ============================================================================
+// CWidgetBackupRegistryXml::CWidgetBackupRegistryXml()
+// C++ constructor
+//
+// @since 5.0
+// ============================================================================
+//
+CWidgetBackupRegistryXml::CWidgetBackupRegistryXml() : iProperties(EWidgetPropertyIdCount)
+ {
+ }
+
+// ============================================================================
+// CWidgetUIConfigHandler::ConstructL()
+// C++ constructor
+//
+// @since 5.0
+// ============================================================================
+//
+void CWidgetBackupRegistryXml::ConstructL()
+ {
+ TWidgetProperty property;
+
+ property.id = EWidgetPropertyListVersion;
+ property.name.Set( KPropertyListVersion );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ //
+ property.id = EBundleIdentifier;
+ property.name.Set( KBundleIdentifier );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EBundleName;
+ property.name.Set( KBundleName );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EBundleDisplayName;
+ property.name.Set( KBundleDisplayName );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EMainHTML;
+ property.name.Set( KMainHTML );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EBundleShortVersion;
+ property.name.Set( KBundleShortVersion );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EBundleVersion;
+ property.name.Set( KBundleVersion );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EHeight;
+ property.name.Set( KHeight );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ //
+ property.id = EWidth;
+ property.name.Set( KWidth );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ //
+ property.id = EAllowFullAccess;
+ property.name.Set( KAllowFullAccess );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ //
+ property.id = EAllowNetworkAccess;
+ property.name.Set( KAllowNetworkAccess );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ //
+ property.id = EDriveName;
+ property.name.Set( KDriveName );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EBasePath;
+ property.name.Set( KBasePath );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EIconPath;
+ property.name.Set( KIconPath );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EUrl;
+ property.name.Set( KUrl );
+ property.type = EWidgetPropTypeString;
+ iProperties.AppendL(property);
+ //
+ property.id = EFileSize;
+ property.name.Set( KFileSize );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ //
+ property.id = EUid;
+ property.name.Set( KUid );
+ property.type = EWidgetPropTypeInt; // not TUid
+ iProperties.AppendL(property);
+ //
+ property.id = ENokiaWidget;
+ property.name.Set( KNokiaWidget );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ //
+ property.id = EMiniViewEnable;
+ property.name.Set( KMiniViewEnabled );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ //
+ property.id = EBlanketPermGranted;
+ property.name.Set( KBlanketPermGranted );
+ property.type = EWidgetPropTypeInt;
+ iProperties.AppendL(property);
+ }
+
+// ============================================================================
+// CWidgetBackupRegistryXml::~CWidgetBackupRegistryXml()
+// destructor
+//
+// @since 5.0
+// ============================================================================
+//
+CWidgetBackupRegistryXml::~CWidgetBackupRegistryXml()
+ {
+ for (TInt i = iProperties.Count() - 1; i >= EWidgetPropertyIdCount; i--)
+ {
+ TUint16* name = const_cast<TUint16*>(iProperties[i].name.Ptr());
+ iProperties[i].name.Set(KNullDesC);
+ delete [] name;
+ }
+ iProperties.Reset();
+ iProperties.Close();
+ }
+
+// ============================================================================
+// Get the property descriptiont by finding entry for name.
+//
+// @param aPropName The name of the prop: <prop>propName</prop>
+// @since 5.0
+// @return prop type.
+// ============================================================================
+//
+TInt CWidgetBackupRegistryXml::GetPropertyId(
+ const TDesC& aPropName )
+ {
+ TInt i = 0;
+ for (; i < iProperties.Count(); ++i )
+ {
+ // use case insensitive match for property names
+ if ( 0 == aPropName.CompareF( iProperties[i].name ) )
+ {
+ return iProperties[i].id;
+ }
+ }
+ TUint16* name = NULL;
+ name = new TUint16 [aPropName.Length()];
+ if (name)
+ {
+ TPtr namePtr(name, aPropName.Length());
+ namePtr.Copy(aPropName);
+ TWidgetProperty property;
+ property.id = iProperties.Count();
+ property.name.Set( namePtr );
+ property.type = EWidgetPropTypeUnknown;
+ TInt err = iProperties.Append(property);
+ if (err == KErrNone)
+ {
+ return iProperties.Count() - 1;
+ }
+ delete name;
+ }
+ return EWidgetPropertyIdInvalid;
+ }
+
+// ============================================================================
+// Get the property name from the property id. Used in entry Externalize
+//
+// @param aPropertyId property id
+// @since 5.0
+// @return property name.
+// ============================================================================
+//
+
+const TPtrC& CWidgetBackupRegistryXml::XmlPropertyName(
+ TInt aPropertyId )
+ {
+ for ( TInt i = 0; i < iProperties.Count(); i++ )
+ {
+ if ( iProperties[i].id == aPropertyId )
+ {
+ return iProperties[i].name;
+ }
+ }
+ return iProperties[0].name; // should never get here
+ }
+
+
+// ============================================================================
+// CWidgetBackupRegistryXml::ToUnicodeL
+// Utility to bundle transcoding to unicode steps.
+//
+// @since 5.0
+// @param aEncoding input buffer encoding
+// @param aUnicodeSizeMultiplier how many bytes of input make one unicode char
+// @param aInBuf input data in encoding
+// @param aOutBuf malloc'ed output buf, caller takes ownership
+// @param aFileSession CCnvCharacterSetConverter requires it
+// ============================================================================
+//
+void CWidgetBackupRegistryXml::ToUnicodeL( TInt aEncoding,
+ TInt aUnicodeSizeMultiplier,
+ TPtrC8 aInBuf, HBufC16** aOutBuf,
+ RFs& aFileSession )
+ {
+ *aOutBuf = NULL;
+
+ // outbuf sizing and alloction
+ HBufC16* outBuf = HBufC16::NewLC(aUnicodeSizeMultiplier * aInBuf.Length());
+ TPtr16 outPtr = outBuf->Des();
+
+ // convert to unicode
+ CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC();
+ charConv->PrepareToConvertToOrFromL( aEncoding, aFileSession );
+ TInt state = CCnvCharacterSetConverter::KStateDefault;
+ TInt rep = 0; // number of unconvertible characters
+ TInt rIndx = 0; // index of first unconvertible character
+ User::LeaveIfError(
+ charConv->ConvertToUnicode( outPtr, aInBuf, state, rep, rIndx ) );
+ CleanupStack::PopAndDestroy( charConv );
+
+ CleanupStack::Pop( outBuf );
+ *aOutBuf = outBuf;
+ }
+
+// ============================================================================
+// CWidgetBackupRegistryXml::FromUnicodeL
+// Utility to bundle transcoding to unicode steps.
+//
+// @since 5.0
+// @param aEncoding input buffer encoding
+// @param aUnicodeSizeMultiplier how many bytes of input make one unicode char
+// @param aInBuf input data in encoding
+// @param aOutBuf malloc'ed output buf, caller takes ownership
+// @param aFileSession CCnvCharacterSetConverter requires it
+// ============================================================================
+//
+void CWidgetBackupRegistryXml::FromUnicodeL( TInt aEncoding,
+ TInt aUnicodeSizeMultiplier,
+ TPtrC16 aInBuf, HBufC8** aOutBuf,
+ RFs& aFileSession )
+ {
+ *aOutBuf = NULL;
+
+ // outbuf sizing and alloction
+ HBufC8* outBuf = HBufC8::NewLC(aUnicodeSizeMultiplier * (aInBuf.Length() + 1));
+ TPtr8 outPtr = outBuf->Des();
+
+ // convert from unicode
+ CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC();
+ charConv->PrepareToConvertToOrFromL( aEncoding, aFileSession );
+ User::LeaveIfError(
+ charConv->ConvertFromUnicode( outPtr, aInBuf));
+ outPtr.ZeroTerminate();
+ CleanupStack::PopAndDestroy( charConv );
+
+ CleanupStack::Pop( outBuf );
+ *aOutBuf = outBuf;
+ }
+
+// ============================================================================
+// CWidgetBackupRegistryXml::GetContentL
+// Utility to bundle extraction of XML text content
+//
+// @since 5.0
+// @param aEncoding input buffer encoding
+// @param aUnicodeSizeMultiplier how many bytes of input make one unicode char
+// @param aInBuf input data in encoding
+// @param aOutBuf malloc'ed output buf, caller takes ownership
+// @param aFileSession CCnvCharacterSetConverter requires it
+// ============================================================================
+//
+void CWidgetBackupRegistryXml::GetContentL( RFs& aFileSession,
+ xmlDocPtr aDoc,
+ xmlNode* aNode,
+ HBufC** aContent )
+ {
+ // xml uses UTF-8 for the internal representation
+ xmlChar* xmlContent =
+ xmlNodeListGetString( aDoc, aNode, 1 /* expand entities inline */);
+ if ( NULL == xmlContent )
+ {
+ User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt );
+ }
+ // we must transcode UTF-8 to UCS-2 (historical
+ // and now inaccurate name "unicode")
+ CleanupStack::PushL( xmlContent );
+ TPtrC8 content( xmlContent );
+ ToUnicodeL( KCharacterSetIdentifierUtf8, 2,
+ content, aContent, aFileSession );
+ CleanupStack::PopAndDestroy(); // xmlContent equivalent to xmlFree()
+ if ( NULL == *aContent )
+ {
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+// ============================================================================
+// CWidgetBackupRegistryXml::GetTextContentAsStringL
+//
+// ============================================================================
+//
+void CWidgetBackupRegistryXml::GetTextContentAsStringL( RFs& aFileSession, xmlDocPtr aDoc,
+ xmlNode* aNode, HBufC** aContent )
+ {
+ HBufC* tmpBuf = NULL;
+ TInt len = 0;
+ GetSubtreeAsStringL (aFileSession, aDoc, aNode, NULL, len);
+ tmpBuf = HBufC::NewLC(len);
+ GetSubtreeAsStringL (aFileSession, aDoc, aNode, &tmpBuf, len);
+ *aContent = tmpBuf;
+ CleanupStack::Pop(); // tmpBuf
+ }
+
+void CWidgetBackupRegistryXml::GetSubtreeAsStringL (RFs& aFileSession, xmlDocPtr aDoc, xmlNode* aNode, HBufC** aBuf, TInt& aLen)
+ {
+ xmlNode* node = aNode;
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ {
+ const xmlChar* name = node->name;
+ TPtrC8 tmpName(name);
+ if (aBuf)
+ {
+ HBufC* tmpBuf = NULL;
+ ToUnicodeL( KCharacterSetIdentifierUtf8, 2,
+ tmpName, &tmpBuf, aFileSession );
+ CleanupStack::PushL(tmpBuf);
+ (*aBuf)->Des().Append(_L("<"));
+ (*aBuf)->Des().Append(*tmpBuf);
+ (*aBuf)->Des().Append(_L(">"));
+ if (node->children)
+ {
+ GetSubtreeAsStringL (aFileSession, aDoc, node->children, aBuf, aLen);
+ }
+ (*aBuf)->Des().Append(_L("</"));
+ (*aBuf)->Des().Append(*tmpBuf);
+ (*aBuf)->Des().Append(_L(">"));
+ CleanupStack::PopAndDestroy(tmpBuf);
+ }
+ else
+ {
+ aLen += (5 + 2 * tmpName.Length());
+ if (node->children)
+ {
+ GetSubtreeAsStringL (aFileSession, aDoc, node->children, aBuf, aLen);
+ }
+ }
+ break;
+ }
+ //case XML_ATTRIBUTE_NODE:
+ case XML_TEXT_NODE:
+ {
+ xmlChar* content = node->content;
+ TPtrC8 tmpContent(content);
+ if (aBuf)
+ {
+ HBufC* tmpBuf = NULL;
+ xmlChar* encodedContent = EncodeStringL(aDoc, content);
+ CleanupStack::PushL( encodedContent );
+ TPtrC8 encodedContentPtr(encodedContent);
+ ToUnicodeL( KCharacterSetIdentifierUtf8, 2,
+ encodedContentPtr, &tmpBuf, aFileSession );
+ CleanupStack::PushL(tmpBuf);
+ (*aBuf)->Des().Append(*tmpBuf);
+ CleanupStack::PopAndDestroy(2); // encodedContent, tmpBuf
+ }
+ else
+ {
+ aLen += EncodedStringLength(tmpContent);
+ }
+ break;
+ }
+ case XML_CDATA_SECTION_NODE:
+ {
+ xmlChar* content = node->content;
+ TPtrC8 tmpContent(content);
+ if (aBuf)
+ {
+ HBufC* tmpBuf = NULL;
+ ToUnicodeL( KCharacterSetIdentifierUtf8, 2,
+ content, &tmpBuf, aFileSession);
+ CleanupStack::PushL(tmpBuf);
+ (*aBuf)->Des().Append(_L("<![CDATA["));
+ (*aBuf)->Des().Append(*tmpBuf);
+ (*aBuf)->Des().Append(_L("]]>"));
+ CleanupStack::PopAndDestroy(); // tmpBuf
+ }
+ else
+ {
+ aLen += (12 + tmpContent.Length());
+ }
+ break;
+ }
+ //case XML_ENTITY_REF_NODE:
+ //case XML_ENTITY_NODE:
+ //case XML_PI_NODE:
+ //case XML_COMMENT_NODE:
+ //case XML_DOCUMENT_NODE:
+ //case XML_DOCUMENT_TYPE_NODE:
+ //case XML_DOCUMENT_FRAG_NODE:
+ //case XML_NOTATION_NODE:
+ //case XML_HTML_DOCUMENT_NODE:
+ //case XML_DTD_NODE:
+ //case XML_ELEMENT_DECL:
+ //case XML_ATTRIBUTE_DECL:
+ //case XML_ENTITY_DECL:
+ //case XML_NAMESPACE_DECL:
+ //case XML_XINCLUDE_START:
+ //case XML_XINCLUDE_END:
+ }
+ if (node->next)
+ {
+ node = node->next;
+ GetSubtreeAsStringL(aFileSession, aDoc, node, aBuf, aLen);
+ }
+ }
+
+xmlChar* CWidgetBackupRegistryXml::EncodeStringL(xmlDocPtr aDoc, xmlChar* aStringToConvert)
+ {
+ xmlChar* noEntitiesContent = xmlEncodeSpecialChars(aDoc, aStringToConvert);
+ if ( NULL == noEntitiesContent )
+ {
+ User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt );
+ }
+ return noEntitiesContent;
+ }
+
+HBufC* CWidgetBackupRegistryXml::EncodeStringL(xmlDocPtr aDoc, TPtrC aStringToConvert, RFs& aFileSession)
+ {
+ HBufC8* out = NULL;
+ FromUnicodeL( KCharacterSetIdentifierUtf8, 2, aStringToConvert, &out, aFileSession );
+ CleanupStack::PushL(out);
+ xmlChar* noEntitiesContent = xmlEncodeSpecialChars(aDoc, out->Des().Ptr());
+ if ( NULL == noEntitiesContent )
+ {
+ User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt );
+ }
+ CleanupStack::PushL( noEntitiesContent );
+ TPtrC8 noEntitiesPtr(noEntitiesContent);
+ HBufC* noEntitiesBuf = NULL;
+ noEntitiesBuf = HBufC::NewL(noEntitiesPtr.Length());
+ noEntitiesBuf->Des().Copy(noEntitiesPtr);
+ CleanupStack::PopAndDestroy(2, out); // out, noEntitiesContent
+
+ return noEntitiesBuf;
+ }
+
+
+TInt CWidgetBackupRegistryXml::EncodedStringLength(TPtrC8 aStringToConvert)
+ {
+ _LIT(KEntity, "\"&\r<>");
+ if (aStringToConvert.Length() == 0 ) return 0;
+ TInt entityLength[] = {6,5,5,4,4};
+ TInt i;
+ TInt count = 0;
+ for (i = 0; i < aStringToConvert.Length(); i++)
+ {
+ TInt entityIndex = KEntity().Locate(aStringToConvert[i]);
+ if (entityIndex != KErrNotFound)
+ {
+ count+= entityLength[entityIndex];
+ }
+ else
+ {
+ count++;
+ }
+ }
+ return count;
+ }