diff -r aaeeca1f15af -r e8d784ac1a4b scrsaver/scrsaverplugins/BmpAnimScrPlugin/src/CBmpAnimIniData.cpp --- /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 +#include + +// 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 fs; + User::LeaveIfError(fs.iObj.Connect()); + fs.PushL(); + + // Just replace the file with the data, no seeking necessary + TAutoClose 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 fs; + User::LeaveIfError(fs.iObj.Connect()); + fs.PushL(); + + // Find file, given name + TFindFile ff(fs.iObj); + TAutoClose 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