diff -r 000000000000 -r 7f656887cf89 libraries/ltkutils/src/rez.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libraries/ltkutils/src/rez.cpp Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,178 @@ +// rez.cpp +// +// Copyright (c) 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "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: +// Accenture - Initial contribution +// +#include +#include +#include +#include + +// Horrible variadic macro to avoid leaving from within a variadic function, because GCCE doesn't like that +#define LeaveIfErr(err, errBuf, fmt...) \ + do \ + { \ + TInt __err = (err); \ + if (__err < 0 && errBuf) \ + { \ + *errBuf = HBufC::NewL(512); \ + FormatIntoBuf(*errBuf, fmt); \ + } \ + User::LeaveIfError(__err); \ + } \ + while (0) + + +void FormatIntoBuf(HBufC* aErrBuf, TRefByValue aFmt, ...) + { + VA_LIST list; + VA_START(list, aFmt); + + TPtr ptr = aErrBuf->Des(); + ptr.FormatList(aFmt, list); + VA_END(list); + } + + +EXPORT_C HBufC8* LtkUtils::Rez8L(const TDesC& aIdentifier, RFs* aFs, HBufC** aErrBuf) + { + TPtrC id(aIdentifier); + if (aIdentifier.Left(2) != _L("R:")) + { + // Just return the string as-is, ie unlocalised + HBufC8* result = HBufC8::NewL(aIdentifier.Length()); + result->Des().Copy(aIdentifier); + return result; + } + + RFs stackfs; + if (!aFs) + { + CleanupClosePushL(stackfs); + LeaveIfErr(stackfs.Connect(), aErrBuf, _L("Couldn't connect to RFs")); + aFs = &stackfs; + } + else + { + CleanupStack::PushL((CBase*)NULL); // Just so the cleanup stack is the same depth in both cases - this is ok to destroy + } + RFs& fs = *aFs; + + id.Set(id.Mid(2)); + TInt colon = id.Locate(':'); + if (colon == KErrNotFound || colon == 0) + { + LeaveIfErr(KErrArgument, aErrBuf, _L("Resource identifier must include a resource id - R:FILENAME:ID[:OFFSET]")); + } + + TPtrC resname(id.Left(colon)); + id.Set(id.Mid(colon+1)); + + colon = id.Locate(':'); + TPtrC offset; + if (colon != KErrNotFound) + { + offset.Set(id.Mid(colon+1)); + id.Set(id.Left(colon)); + } + + TFileName resFileName = resname; + resFileName.Insert(0, _L("\\Resource\\")); + resFileName.Append(_L(".rsc")); // Seems daft but you have to have this to keep Bafl happy + BaflUtils::NearestLanguageFile(fs, resFileName); + + RResourceFile resFile; + CleanupClosePushL(resFile); + TRAPD(err, resFile.OpenL(fs, resFileName)); + LeaveIfErr(err, aErrBuf, _L("Couldn't open resource file %S"), &resFileName); + + TRAP(err, resFile.ConfirmSignatureL()); + LeaveIfErr(err, aErrBuf, _L("Failed to confirm signature")); + + TBool hex = EFalse; + if (id.Left(2) == _L("0x")) + { + id.Set(id.Mid(2)); + hex = ETrue; + } + TUint resourceId; + TLex lex(id); + LeaveIfErr(lex.Val(resourceId, hex ? EHex : EDecimal), aErrBuf, _L("Couldn't parse resource id from %S"), &id); + + HBufC8* resdata = NULL; + TRAP(err, resdata = resFile.AllocReadL(resourceId)); + LeaveIfErr(err, aErrBuf, _L("Couldn't read resource %d from %S"), resourceId, &resFileName); + CleanupStack::PushL(resdata); + + TPtrC8 result(*resdata); + if (offset.Length()) + { + char last = (char)offset[offset.Length() - 1]; + if (last != 'd' && last != 'D') + { + LeaveIfErr(KErrArgument, aErrBuf, _L("Offset '%S' does not end in a 'd' or a 'D'. This is needed to indicate whether the actual target is 8-bit or 16-bit"), &offset); + } + TResourceReader reader; + reader.SetBuffer(resdata); + TLex lex(offset); + while (!lex.Eos()) + { + TChar ch = lex.Get(); + if (ch == 'd') + { + result.Set(reader.ReadTPtrC8()); + } + else if (ch == 'D') + { + TPtrC16 wptr = reader.ReadTPtrC16(); + result.Set(TPtrC8((TUint8*)wptr.Ptr(), wptr.Size())); + } + else + { + lex.UnGet(); + TInt amountToSkip; + LeaveIfErr(lex.Val(amountToSkip), aErrBuf, _L("Error lexing offset")); + reader.Advance(amountToSkip); + } + } + } + + HBufC8* resultBuf = result.AllocL(); + CleanupStack::PopAndDestroy(3); // resData, resFile, fs + return resultBuf; + } + +EXPORT_C HBufC* LtkUtils::RezL(const TDesC& aIdentifier, RFs* aFs, HBufC** aErrBuf) + { + if (aIdentifier.Left(2) != _L("R:")) + { + // Just return the string as-is, ie unlocalised + return aIdentifier.AllocL(); + } + HBufC8* buf8 = Rez8L(aIdentifier, aFs, aErrBuf); + CleanupStack::PushL(buf8); + TPtrC16 wptr((TUint16*)buf8->Ptr(), buf8->Size()/2); + HBufC* result = wptr.AllocL(); + CleanupStack::PopAndDestroy(buf8); + return result; + } + +EXPORT_C HBufC* LtkUtils::RezLC(const TDesC& aIdentifier, RFs* aFs, HBufC** aErrBuf) + { + HBufC* res = RezL(aIdentifier, aFs, aErrBuf); + CleanupStack::PushL(res); + return res; + } + +EXPORT_C HBufC8* LtkUtils::Rez8LC(const TDesC& aIdentifier, RFs* aFs, HBufC** aErrBuf) + { + HBufC8* res = Rez8L(aIdentifier, aFs, aErrBuf); + CleanupStack::PushL(res); + return res; + }