mediasettings/mediasettingsengine/src/MPSettingsRopConfigParser.cpp
changeset 0 96612d01cf9f
child 20 2d690156cf8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mediasettings/mediasettingsengine/src/MPSettingsRopConfigParser.cpp	Mon Jan 18 20:21:12 2010 +0200
@@ -0,0 +1,635 @@
+/*
+* Copyright (c) 2002 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:   Config descriptor parser for ROP specific settings.*
+*/
+
+
+// Version : %version: 3 %
+
+
+
+
+// INCLUDE FILES
+#include    <utf.h>
+#include    "MPSettingsRopConfigParser.h"
+#include	"mpxlog.h"
+
+// CONSTANTS
+const TInt KMPRopEntryArrayGranularity = 16;
+
+_LIT8(KMPRopTypeInteger, "Integer");
+_LIT8(KMPRopTypeString, "String");
+_LIT8(KMPRopEntrySeparator, ";");
+_LIT8(KMPRopKeySeparator, ":");
+_LIT8(KMPRopValueSeparator, "=");
+_LIT8(KMPRopStringConstrainer, "\"");
+_LIT8(KMPRopArrayOpeningMarker, "{");
+_LIT8(KMPRopArrayClosingMarker, "}");
+_LIT8(KMPRopArraySeparator, ",");
+_LIT8(KMPRopIntegerEntryPrototype, "%S:Integer = %d;");
+_LIT8(KMPRopStringEntryPrototype, "%S:String = \"%S\";");
+
+const TInt KMPRopIntegerEntryPrototypeStaticLength = 23; // static length + 11 chars for the (32bit) TInt
+const TInt KMPRopStringEntryPrototypeStaticLength = 13;
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// *******************************
+// *** class CMPRopSettingItem ***
+// *******************************
+
+// -----------------------------------------------------------------------------
+// CMPRopSettingItem::CMPRopSettingItem
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMPRopSettingItem::CMPRopSettingItem(TInt aId) : iId(aId),
+    iValueChanged(EFalse)
+    {
+    MPX_DEBUG1(_L("#MS# CMPRopSettingItem::CMPRopSettingItem()"));
+    }
+
+// -----------------------------------------------------------------------------
+// CMPRopSettingItem::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMPRopSettingItem::ConstructL(const TDesC& aKey)
+    {
+    MPX_DEBUG2(_L("#MS# CMPRopSettingItem::ConstructL(%S)"),&aKey);
+    iKey = HBufC8::NewL(aKey.Length());
+    TPtr8 ptr = iKey->Des();
+    CnvUtfConverter::ConvertFromUnicodeToUtf8(ptr, aKey);
+    }
+
+// -----------------------------------------------------------------------------
+// CMPRopSettingItem::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMPRopSettingItem* CMPRopSettingItem::NewLC(TInt aId, const TDesC& aKey)
+    {
+    MPX_DEBUG3(_L("#MS# CMPRopSettingItem::NewLC(%d,%S)"),aId,&aKey);
+    CMPRopSettingItem* self = new(ELeave) CMPRopSettingItem(aId);
+    
+    CleanupStack::PushL(self);
+    self->ConstructL(aKey);
+
+    return self;
+    }
+   
+// -----------------------------------------------------------------------------
+// CMPRopSettingItem::~CMPRopSettingItem
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMPRopSettingItem::~CMPRopSettingItem()
+    {
+    MPX_DEBUG1(_L("#MS# CMPRopSettingItem::~CMPRopSettingItem()"));
+    if (iKey) 
+		{
+		delete iKey;
+		}
+    delete iStringValue;
+    iIntArray.Close();
+    }
+
+
+// ****************************************
+// *** class CMPSettingsRopConfigParser ***
+// ****************************************
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::CMPSettingsRopConfigParser
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMPSettingsRopConfigParser::CMPSettingsRopConfigParser()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::CMPSettingsRopConfigParser()"));
+    }
+   
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::~CMPSettingsRopConfigParser
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMPSettingsRopConfigParser::~CMPSettingsRopConfigParser()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::~CMPSettingsRopConfigParser()"));
+	if (iEntries)
+      iEntries->ResetAndDestroy();
+    delete iEntries;
+    delete iTmpBuf;
+    delete iConfigHeader;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMPSettingsRopConfigParser::ConstructL()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::ConstructL()"));
+    iEntries = new(ELeave) CArrayPtrFlat<HBufC8>(KMPRopEntryArrayGranularity);
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMPSettingsRopConfigParser* CMPSettingsRopConfigParser::NewL()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::NewL()"));
+    CMPSettingsRopConfigParser* self = new(ELeave) CMPSettingsRopConfigParser;
+    
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::ParseConfigStringL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMPSettingsRopConfigParser::ParseConfigStringL(const TDesC8& aConfigString, const CArrayPtr<CMPRopSettingItem>* aItemArray)
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::ParseConfigStringL()"));
+    iBufferPtr.Set(aConfigString);
+    iItemArray = aItemArray;
+    
+    // Parse header
+    HBufC8* header = ParseConfigHeaderL();
+    CleanupStack::PushL(header);
+
+    // Read all config entries to an array
+    PopulateEntryArrayFromConfigStringL();
+
+    // Parse config entries from the array, delete items from the entry array
+    ParseSettingsBufferL();
+    iEntries->ResetAndDestroy();
+
+    CleanupStack::Pop(); // header
+
+    return header;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::CreateConfigStringL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMPSettingsRopConfigParser::CreateConfigStringL(const CArrayPtr<CMPRopSettingItem>* aItemArray, const TDesC8& aConfigHeader)
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::CreateConfigStringL()"));
+    HBufC8* configString = NULL;
+    iItemArray = aItemArray;
+
+    delete iConfigHeader;
+    iConfigHeader = NULL;
+    iConfigHeader = HBufC8::NewL(aConfigHeader.Length() + 1); // magic, leave room for line separator (';')
+    TPtr8 tmp = iConfigHeader->Des();
+
+    tmp.Append(aConfigHeader);
+    tmp.Append(KMPRopEntrySeparator);
+
+    PopulateEntryArrayFromItemArrayL();
+    
+    // If iEntries->Count() == 1 -> iEntries contains only config header ->
+    // none of the setting values has change => no need to create config string
+    if (iEntries->Count() > 1)
+        {
+        configString = CreateConfigStringFromEntryArrayL();
+        }
+
+    iEntries->ResetAndDestroy();
+
+    return configString;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::ParseConfigHeaderL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMPSettingsRopConfigParser::ParseConfigHeaderL()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::ParseConfigHeaderL()"));
+    HBufC8* buf = NULL;
+    TPtrC8 ptr;
+    TInt error = GetNextEntry(ptr);
+    if (error)
+        {
+        // If header line cannot be found, the string is corrupted => Leave
+        User::Leave(KErrCorrupt);
+        }
+
+    buf = ptr.AllocL();
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::NextConfigEntryL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMPSettingsRopConfigParser::NextConfigEntryL(TInt& aError)
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::NextConfigEntryL()"));
+    HBufC8* buf = NULL;
+
+    TPtrC8 ptr;
+    aError = GetNextEntry(ptr);
+
+    if (!aError)
+        {
+        buf = ptr.AllocL();
+        buf->Des().Trim();
+        }
+
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::PopulateEntryArrayFromConfigStringL
+// -----------------------------------------------------------------------------
+//
+void CMPSettingsRopConfigParser::PopulateEntryArrayFromConfigStringL()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::PopulateEntryArrayFromConfigStringL()"));
+    TInt error(KErrNone);
+    iEntries->ResetAndDestroy();
+
+    do
+        {
+        HBufC8* buf = NextConfigEntryL(error);
+
+        if (!error)
+            {
+            iEntries->AppendL(buf);
+            }
+        }
+    while (!error);
+
+    if (error != KErrNotFound)
+        {
+        User::Leave(error);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::PopulateEntryArrayFromItemArrayL
+// -----------------------------------------------------------------------------
+//
+void CMPSettingsRopConfigParser::PopulateEntryArrayFromItemArrayL()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::PopulateEntryArrayFromItemArrayL()"));
+    CMPRopSettingItem* item = NULL;
+    HBufC8* buf = NULL;
+    iEntries->ResetAndDestroy();
+
+    // Append config string header to array
+    iEntries->AppendL(iConfigHeader);
+    iConfigHeader = NULL;
+
+    TInt count = iItemArray->Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        item = iItemArray->At(i);
+
+        if (item->iValueChanged)
+            {
+            buf = CreateConfigEntryL(item);
+
+            if (buf)
+                {
+                CleanupStack::PushL(buf);
+                iEntries->AppendL(buf);
+                CleanupStack::Pop(); // buf
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::CreateConfigEntryL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMPSettingsRopConfigParser::CreateConfigEntryL(CMPRopSettingItem* aItem)
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::CreateConfigEntryL()"));
+    HBufC8* buf = NULL;
+
+    switch (aItem->iType)
+        {
+        case EMPRopConfTypeInteger:
+            {
+            buf = HBufC8::NewL(aItem->iKey->Length() + KMPRopIntegerEntryPrototypeStaticLength);
+            TPtr8 ptr = buf->Des();
+            ptr.Format(KMPRopIntegerEntryPrototype, aItem->iKey, aItem->iIntValue);
+            break;
+            }
+        case EMPRopConfTypeString:
+            {
+            HBufC* str = aItem->iStringValue;
+            TInt strLength = str->Length();
+            HBufC8* str8 = HBufC8::NewLC(strLength);
+            TPtr8 str8Ptr = str8->Des();
+            CnvUtfConverter::ConvertFromUnicodeToUtf8(str8Ptr, *str);
+            
+            buf = HBufC8::NewL(aItem->iKey->Length() + strLength + KMPRopStringEntryPrototypeStaticLength);
+            TPtr8 ptr = buf->Des();
+            ptr.Format(KMPRopStringEntryPrototype, aItem->iKey, &(*str8));
+            CleanupStack::PopAndDestroy(); //str8
+            break;
+            }
+        default:
+            break;
+        }
+
+    return buf;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::GetNextEntry
+// -----------------------------------------------------------------------------
+//
+TInt CMPSettingsRopConfigParser::GetNextEntry(TPtrC8& aEntry)
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::GetNextEntry()"));
+    TInt error(KErrNone);
+
+    TInt offset = iBufferPtr.Find(KMPRopEntrySeparator);
+    if (offset != KErrNotFound)
+        {
+        aEntry.Set(iBufferPtr.Left(offset));
+        iBufferPtr.Set(iBufferPtr.Mid(++offset)); // don't include ';'
+        }
+    else
+        {
+        error = KErrNotFound;
+        }
+
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::ParseSettingsBufferL
+// -----------------------------------------------------------------------------
+//
+void CMPSettingsRopConfigParser::ParseSettingsBufferL()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::ParseSettingsBufferL()"));
+    CMPRopSettingItem* item;
+    TPtrC8 value;
+
+    TInt count = iItemArray->Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        item = iItemArray->At(i);
+
+        item->iError = GetConfigDataL(*item->iKey, value, item->iType);
+        
+        if (!item->iError)
+            {
+            switch (item->iType)
+                {
+                case EMPRopConfTypeInteger:
+                    {
+                    // Parse integer value
+                    TLex8 lex(value);
+                    item->iError = lex.Val(item->iIntValue);
+                    break;
+                    }
+                case EMPRopConfTypeIntArray:
+                    {
+                    HBufC8* tmp = NULL;
+                    TInt offset = 0; // Magic: should not be KErrNotFound initially
+                    TInt error = KErrNone;
+                    TInt intVal = 0;
+                    item->iIntArray.Reset();
+                    
+                    while (offset != KErrNotFound && !error)
+                        {
+                        offset = value.Find(KMPRopArraySeparator);
+
+                        if (offset != KErrNotFound)
+                            {
+                            tmp = value.Left(offset).AllocLC();
+                            }
+                        else
+                            {
+                            tmp = value.AllocLC();
+                            }
+
+                        tmp->Des().Trim();
+                        TLex8 lex(*tmp);
+                        error = lex.Val(intVal);
+
+                        if (!error)
+                            {
+                            User::LeaveIfError(item->iIntArray.Append(intVal));
+
+                            if (offset != KErrNotFound)
+                                {
+                                value.Set(value.Mid(offset + 1));
+                                }
+                            }
+
+                        CleanupStack::PopAndDestroy(); // tmp
+                        tmp = NULL;
+                        }
+                    
+                    item->iError = error;
+                    break;
+                    }
+                case EMPRopConfTypeString:
+                    // Parse string value
+                    value.Set(ValueStringPtr(value, item->iError));
+
+                    if (!item->iError)
+                        {
+                        delete item->iStringValue;
+                        item->iStringValue = NULL;
+                        item->iStringValue = HBufC::NewL(value.Length());
+    
+                        TPtr tmp = item->iStringValue->Des();
+                        CnvUtfConverter::ConvertToUnicodeFromUtf8(tmp, value);
+                        }
+                    break;
+                default:
+                    item->iError = KErrNotSupported;
+                    break;
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::GetConfigDataL
+// -----------------------------------------------------------------------------
+//
+TInt CMPSettingsRopConfigParser::GetConfigDataL(const TDesC8& aKey, TPtrC8& aValue, TMPRopConfType& aType)
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::GetConfigDataL()"));
+    TInt ret = KErrNotFound;
+    TInt offset = KErrNotFound;
+    HBufC8* buf = NULL;
+
+    // Try to find aConfigKey from the beginning of each entry untill one is found
+    // (offset has to be 0, as there can be several different config keys that
+    // include some other config key, e.g. "Timeout" vs. "ConnTimeout").
+    for (TInt i = 0; offset != 0 && i < iEntries->Count(); i++)
+        {
+        buf = iEntries->At(i);
+        offset = buf->Find(aKey);
+        }
+
+    // Parse type and value if correct key was found
+    if (offset == 0)
+        {
+        offset = buf->Find(KMPRopKeySeparator);
+        TInt offset2 = buf->Find(KMPRopValueSeparator);
+        TInt arrayOffset = buf->Find(KMPRopArrayOpeningMarker);
+
+        if (offset != KErrNotFound && offset2 != KErrNotFound && offset < offset2)
+            {
+            ++offset; // Move past the key separator
+
+            delete iTmpBuf;
+            iTmpBuf = NULL;
+            iTmpBuf = buf->Mid(offset, offset2 - offset).AllocL();
+            iTmpBuf->Des().Trim();
+            
+            // Parse type
+            if (*iTmpBuf == TPtrC8(KMPRopTypeInteger))
+                {
+                if (arrayOffset == KErrNotFound)
+                    {
+                    aType = EMPRopConfTypeInteger;
+                    }
+                else
+                    {
+                    aType = EMPRopConfTypeIntArray;
+                    }
+                }
+            else if (*iTmpBuf == TPtrC8(KMPRopTypeString))
+                {
+                aType = EMPRopConfTypeString;
+                }
+            else
+                {
+                ret = KErrNotSupported;
+                }
+ 
+            if (ret != KErrNotSupported)
+                {
+                // Parse value
+                delete iTmpBuf;
+                iTmpBuf = NULL;
+
+                if (aType == EMPRopConfTypeIntArray)
+                    {
+                    TInt arrayOffset2 = buf->Find(KMPRopArrayClosingMarker);
+
+                    if (arrayOffset2 != KErrNotFound && arrayOffset < arrayOffset2)
+                        {
+                        // Copy, but do not include markers
+                        iTmpBuf = buf->Mid(arrayOffset + 1, arrayOffset2 - arrayOffset - 1).AllocL();
+                        ret = KErrNone;
+                        }
+                    else
+                        {
+                        return KErrCorrupt;
+                        }
+                    }
+                else
+                    {
+                    iTmpBuf = buf->Mid(++offset2).AllocL(); // Move past the value separator
+                    ret = KErrNone;
+                    }
+
+                iTmpBuf->Des().Trim();
+
+                aValue.Set(*iTmpBuf);
+                }
+            }
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::ValueStringPtr
+// -----------------------------------------------------------------------------
+//
+TPtrC8 CMPSettingsRopConfigParser::ValueStringPtr(const TDesC8& aValue, TInt& aError)
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::ValueStringPtr()"));
+    TPtrC8 ptr;
+    aError = KErrNotFound;
+    // Find first string constrainer
+    TInt offset = aValue.Find(KMPRopStringConstrainer);
+    
+    if (offset != KErrNotFound)
+        {
+        TPtrC8 tmp;
+        // 1.) Set offset1 to point the first character of the config string
+        // 2.) Set characters after the first string constrainer to tmp
+        tmp.Set(aValue.Mid(++offset));
+        // Find second string constrainer
+        offset = tmp.Find(KMPRopStringConstrainer);
+
+        if (offset != KErrNotFound)
+            {
+            // Set characters between the string constrainers to aString
+            ptr.Set(tmp.Left(offset));
+            aError = KErrNone;
+            }
+        }
+
+    return ptr;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPSettingsRopConfigParser::CreateConfigStringFromEntryArrayL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMPSettingsRopConfigParser::CreateConfigStringFromEntryArrayL()
+    {
+    MPX_DEBUG1(_L("#MS# CMPSettingsRopConfigParser::CreateConfigStringFromEntryArrayL()"));
+    TInt length(0);
+    TInt count = iEntries->Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        length += iEntries->At(i)->Length();
+        }
+
+    HBufC8* configString = HBufC8::NewL(length);
+    TPtr8 ptr = configString->Des();
+
+    for (TInt j = 0; j < count; ++j)
+        {
+        ptr.Append(*iEntries->At(j));
+        }
+
+    return configString;
+    }
+
+//  End of File