--- /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 <fshell/ltkutils.h>
+#include <f32file.h>
+#include <bautils.h>
+#include <barsc.h>
+
+// 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<const TDesC> 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;
+ }