scrsaver/scrsaverplugins/BmpAnimScrPlugin/src/CBmpAnimIniData.cpp
branchRCL_3
changeset 26 e8d784ac1a4b
parent 0 040fcad49f44
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scrsaver/scrsaverplugins/BmpAnimScrPlugin/src/CBmpAnimIniData.cpp	Wed Sep 01 12:30:40 2010 +0100
@@ -0,0 +1,472 @@
+/*
+* Copyright (c) 2003 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:     Bitmap animator INI file handler
+*
+*/
+
+
+
+
+
+#include "CBmpAnimIniData.h"
+
+#include <f32file.h>
+#include <e32std.h>
+
+// Default directory to look for INI file
+_LIT(KIniFileDir,"C:\\private\\100056cf\\");
+
+const TInt KTokenSize=32;
+
+#ifdef _DEBUG
+// Debugging aids
+enum TIniPanic
+	{
+	ESectionNameTooBig,
+	EKeyNameTooBig,
+	};
+
+void Panic(TIniPanic aPanic)
+	{
+	_LIT(CBmpAnimIniData,"CBmpAnimIniData");
+	User::Panic(CBmpAnimIniData,aPanic);
+	}
+#endif  // _DEBUG
+
+// d'tor
+CBmpAnimIniData::~CBmpAnimIniData()
+	{
+	delete (TText*)iPtr.Ptr();
+	delete iToken;
+	delete iName;
+	}
+
+    
+// Public allocation method
+CBmpAnimIniData* CBmpAnimIniData::NewL(const TDesC& aName)
+	{
+	CBmpAnimIniData* p=new(ELeave) CBmpAnimIniData;
+	CleanupStack::PushL(p);
+	p->ConstructL(aName);
+	CleanupStack::Pop();
+	return p;
+	}
+
+
+// Find a key's string) value regardless of section (wide)
+TBool CBmpAnimIniData::FindVar(const TDesC8& aKeyName, TDes16& aResult)
+    {
+    TPtrC8 tmpRes;
+    if (!FindVar(aKeyName, tmpRes))
+        {
+        return EFalse;
+        }
+
+    // Copy the 8-bit result into the 16-bit descriptor
+    aResult.Copy(tmpRes);
+    return ETrue;
+    }
+
+    
+// Find a key's (string) value regardless of section
+TBool CBmpAnimIniData::FindVar(const TDesC8& aKeyName, TPtrC8& aResult)
+    {
+    _LIT8(KDummySection, "");
+    // Call with no section, so starts at beginning
+    if (FindVar(KDummySection, aKeyName, aResult))
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+    
+
+// Find a key's (string) value given a section name and a key name (wide)
+TBool CBmpAnimIniData::FindVar(const TDesC8& aSectName,
+                               const TDesC8& aKeyName,
+                               TDes16& aResult)
+    {
+    TPtrC8 tmpRes;
+    if (!FindVar(aSectName, aKeyName, tmpRes))
+        {
+        return EFalse;
+        }
+
+    // Copy the 8-bit result into the 16-bit descriptor
+    aResult.Copy(tmpRes);
+    return ETrue;
+    }
+
+    
+// Find a key's (string) value given a section name and a key name
+TBool CBmpAnimIniData::FindVar(const TDesC8& aSectName,
+                               const TDesC8& aKeyName,
+                               TPtrC8& aResult)
+    {
+    __ASSERT_DEBUG(aSectName.Length() <= KTokenSize, Panic(ESectionNameTooBig));
+    __ASSERT_DEBUG(aKeyName.Length() <= KTokenSize, Panic(EKeyNameTooBig));
+
+    TInt posStartOfSection(0);
+    TInt posEndOfSection(0);
+    TPtrC8 SearchBuf;
+
+    // If we have a section, set pos to section start
+    if (aSectName.Length() > 0)
+        {
+        if (!FindSection(aSectName, posStartOfSection, posEndOfSection))
+            {
+            return EFalse;
+            }
+        }
+
+    // Look for key in ini file data Buffer
+    TInt posI = posStartOfSection; // Position in internal data Buffer
+    TBool FoundKey(EFalse);
+    while (!FoundKey)
+        {
+        // Search for next occurrence of aKeyName
+        SearchBuf.Set(iPtr.Mid(posI));
+        TInt posSB = SearchBuf.Find(aKeyName);
+
+        // If not found, return
+        if (posSB == KErrNotFound)
+            {
+            return EFalse;
+            }
+
+        // Check this is at beginning of line (ie. non-commented)
+        // ie. Check preceding char was CR or LF
+        if(posSB > 0)
+            {
+            // Create a Buffer, starting one char before found subBuf
+            TPtrC8 CharBefore(SearchBuf.Right(SearchBuf.Length() - posSB + 1));
+            // Check first char is end of prev
+            if(CharBefore[0] == '\n')
+                {
+                FoundKey = ETrue;
+                posI = posI + posSB;
+                }
+            else
+                {
+                posI = posI + posSB + 1;
+                }
+            }
+        else
+            {
+            FoundKey = ETrue;
+            }
+
+    }   // while (!FoundKey)
+
+    // Set pos to just after '=' sign
+    SearchBuf.Set(iPtr.Mid(posI));
+    TInt posSB = SearchBuf.Locate('=');
+    if (posSB == KErrNotFound)     // Illegal format, should flag this...
+        {
+        return EFalse;
+        }
+
+    // Identify start and end of data (EOL or EOF)
+    posI = posI + posSB + 1;    // 1 char after '='
+    TInt posValStart = posI;
+    TInt posValEnd;
+    SearchBuf.Set(iPtr.Mid(posI));
+    posSB = SearchBuf.Locate('\r');
+    if (posSB != KErrNotFound)
+        {
+        posValEnd = posI + posSB;
+        }
+    else
+        {
+        posValEnd = iPtr.Length();
+        }
+
+    // Check we are still in the section requested
+    if (aSectName.Length() > 0)
+        {
+        if (posValEnd > posEndOfSection)
+            {
+            return EFalse;
+            }
+        }
+
+    // Parse Buffer from posn of key
+    // Start one space after '='
+    TLex8 lex(iPtr.Mid(posValStart, posValEnd - posValStart));
+    lex.SkipSpaceAndMark();     // Should be at the start of the data
+    aResult.Set(lex.MarkedToken().Ptr(),
+                posValEnd - posValStart - lex.Offset());
+    
+    return ETrue;
+    }
+
+    
+// Find integer value regardless of section
+TBool CBmpAnimIniData::FindVar(const TDesC8& aKeyName, TInt& aResult)
+    {
+    TPtrC8 ptr(NULL, 0);
+    if (FindVar(aKeyName, ptr))
+        {
+        TLex8 lex(ptr);
+        if (lex.Val(aResult) == KErrNone)
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+
+    
+// Find integer value within a given section
+TBool CBmpAnimIniData::FindVar(
+    const TDesC8& aSection, const TDesC8& aKeyName, TInt& aResult)
+    {
+    TPtrC8 ptr(NULL, 0);
+    if (FindVar(aSection, aKeyName, ptr))
+        {
+        TLex8 lex(ptr);
+        if (lex.Val(aResult) == KErrNone)
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+
+
+// Write integer value in given section
+TInt CBmpAnimIniData::WriteVarL(
+    const TDesC8& aSection, const TDesC8& aKeyName, TInt aValue)
+    {
+    TBuf8<32> buf;
+    buf.Num(aValue);
+    return WriteVarL(aSection, aKeyName, buf);
+    }
+
+
+// Write string value in given section
+TInt CBmpAnimIniData::WriteVarL(
+    const TDesC8& aSection, const TDesC8& aKeyName, const TDesC8& aValue)
+    {
+    // First find the variable - this gives us a descriptor into the
+    // ini data giving the bound of the item that has to be replaced
+    TPtrC8 ptr;
+    TInt pos;
+    TBool found = FindVar(aSection, aKeyName, ptr);
+
+    HBufC8* text = HBufC8::NewLC(
+        aSection.Length() + aKeyName.Length() + aValue.Length() + 7); // +7 for '=', '[', ']' and 2*cr+lf.
+    TPtr8 textp = text->Des();
+
+    if (found)
+        {
+        pos = ptr.Ptr() - iPtr.Ptr();
+        textp.Append(aValue);
+        }
+    else
+        {
+        TInt posStartOfSection = 0;
+        TInt posEndOfSection = 0;
+        
+        if (FindSection(aSection, posStartOfSection, posEndOfSection))
+            {
+            pos = posEndOfSection;
+            }
+        else
+            {
+            pos = iPtr.Length();
+            textp.Append('[');
+            textp.Append(aSection);
+            textp.Append(']');
+            textp.Append('\r');
+            textp.Append('\n');
+            }
+        textp.Append(aKeyName);
+        textp.Append('=');
+        textp.Append(aValue);
+        textp.Append('\r');
+        textp.Append('\n');
+        }
+
+    TInt size = (iPtr.Length() + textp.Length() - ptr.Length()) * sizeof(TText8);
+
+    if (size > iPtr.MaxLength())
+        {
+        TText8* newdata = (TText8*) User::ReAllocL((TUint8*)iPtr.Ptr(), size);
+        iPtr.Set(newdata, iPtr.Length(), size/sizeof(TText8));
+        }
+
+    iPtr.Replace(pos, ptr.Length(), textp);
+
+    CleanupStack::PopAndDestroy(text);
+
+    return KErrNone;
+    }
+
+    
+// Commits the changes in variables, ie writes the file data (held in iPtr)
+// into the actual disk file
+void CBmpAnimIniData::CommitL()
+    {
+    TAutoClose<RFs> fs;
+    User::LeaveIfError(fs.iObj.Connect());
+    fs.PushL();
+
+    // Just replace the file with the data, no seeking necessary
+    TAutoClose<RFile> file;
+    file.iObj.Replace(fs.iObj, *iName, EFileStreamText|EFileWrite);
+    file.PushL();
+    
+    TPtrC8 ptrc8((TUint8*)iPtr.Ptr(), iPtr.Size());
+    User::LeaveIfError(file.iObj.Write(ptrc8));
+    
+    file.Pop();
+    fs.Pop();
+    }
+
+
+// --- protected --- 
+
+// c'tor
+CBmpAnimIniData::CBmpAnimIniData() 
+: iPtr(NULL, 0)
+    {
+    __DECLARE_NAME(_S("CBmpAnimIniData"));
+    }
+
+
+// Allocate a buffer and Read file's contents into iPtr
+void CBmpAnimIniData::ConstructL(const TDesC& aName)
+    {
+    // Allocate space for token
+    iToken = HBufC8::NewL(KTokenSize + 2);   // 2 extra chars for [tokenName]
+
+    // Connect to file server
+    TAutoClose<RFs> fs;
+    User::LeaveIfError(fs.iObj.Connect());
+    fs.PushL();
+
+    // Find file, given name
+    TFindFile ff(fs.iObj);
+    TAutoClose<RFile> file;    
+    TInt err = ff.FindByDir(aName, KIniFileDir);
+    
+    // If found - cool, use the found file's name and open it
+    if (err == KErrNone)
+        {
+        iName = ff.File().AllocL();
+        err = file.iObj.Open(fs.iObj, *iName, EFileStreamText | EFileRead);
+        }
+
+    // If not found - create the file using the given name
+    if (err == KErrNotFound)
+        {
+        err = file.iObj.Create(fs.iObj, aName, EFileStreamText);
+        iName = aName.AllocL();
+        }
+
+    file.PushL();
+
+    // Get file size and read in as 8-bit data
+    TInt size = 0;
+    User::LeaveIfError(file.iObj.Size(size));
+    TText8* data = (TText8*) User::AllocL(size);
+    iPtr.Set(data, size, size);
+    TPtr8 dest((TUint8*)data, 0, size);
+    User::LeaveIfError(file.iObj.Read(dest));
+
+    file.Pop();
+    fs.Pop();
+    }
+    
+
+// --- private --- 
+
+
+// Find a section in the INIfile
+TBool CBmpAnimIniData::FindSection(
+    const TDesC8& aSection, TInt& aStart, TInt& aEnd)
+    {
+    TInt posI = 0;  // Position in internal databuffer
+    TBool FoundSection = EFalse;
+    TPtrC8 SearchBuf;
+    
+    while (!FoundSection)
+        {
+        // Move search buffer to next area of interest
+        SearchBuf.Set(iPtr.Mid(posI));
+        
+        // Make up token "[SECTIONNAME]", to search for
+        TPtr8 sectionToken = iToken->Des();
+        _LIT8(sectionTokenFmtString,"[%S]");
+        sectionToken.Format(sectionTokenFmtString, &aSection);
+        
+        // Search for next occurrence of aSection
+        TInt posSB = SearchBuf.Find(sectionToken);
+        
+        // If not found, return
+        if (posSB == KErrNotFound)
+            {
+            return EFalse;
+            }
+        
+        // Check this is at beginning of line (ie. non-commented)
+        // ie. Check preceding char was LF
+        if (posSB > 0)
+            {
+            // Create a Buffer, starting one char before found subBuf
+            TPtrC8 CharBefore(SearchBuf.Right(SearchBuf.Length() - posSB + 1));
+            // Check first char is end of prev
+            if (CharBefore[0] == '\n')
+                {
+                FoundSection = ETrue;       // found
+                posI = posI + posSB;
+                }
+            else
+                {
+                posI = posI + posSB + 1;    // try again
+                }
+            }
+        else
+            {
+            FoundSection = ETrue;
+            }
+        
+        }   // while (!FoundSection)
+    
+    // Set start of section, after section name, (incl '[' and ']')
+    aStart = posI + aSection.Length() + 2;
+    
+    // Set end of section, by finding begin of next section or end
+    SearchBuf.Set(iPtr.Mid(posI));
+    
+    _LIT8(nextSectionBuf,"\n[");
+    
+    TInt posSB = SearchBuf.Find(nextSectionBuf);
+    if (posSB != KErrNotFound)
+        {
+        aEnd = posI + posSB + 1;
+        }
+    else
+        {
+        aEnd = iPtr.Length();
+        }
+    
+    return ETrue;
+    }
+
+// EOF