os/ossrv/genericservices/s60compatibilityheaders/commonengine/src/textresolver.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericservices/s60compatibilityheaders/commonengine/src/textresolver.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,640 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +
1.20 +
1.21 +#include <barsread.h> // TResourceReader
1.22 +#include <bautils.h> // BaflUtils
1.23 +#include "textresolver.h"
1.24 +#include <errorres.rsg>
1.25 +#include <uikon/eikdefconst.h>
1.26 +
1.27 +
1.28 +const TInt KUnknownError( 0 );
1.29 +const TInt KBlankError( -2 );
1.30 +
1.31 +const TInt KRIMask(0x00000fff);
1.32 +_LIT(KErrorResResourceFileName, "z:\\resource\\errors\\ERRORRES.RSC");
1.33 +_LIT(KRDSupport, "c:\\resource\\ErrRD");
1.34 +_LIT(KTextResolverPanic, "TextResolver");
1.35 +
1.36 +
1.37 +GLDEF_C void Panic(TInt aPanic)
1.38 + {
1.39 + User::Panic(KTextResolverPanic, aPanic);
1.40 + }
1.41 +
1.42 +
1.43 +CTextResolver::CTextResolver()
1.44 + {
1.45 + }
1.46 +
1.47 +CTextResolver::CTextResolver(CCoeEnv& aEnv)
1.48 + :iCoe(&aEnv)
1.49 + {
1.50 + }
1.51 +/**
1.52 + * Two-phase constructor method that is used to create a new instance
1.53 + * of the CTextResolver class. The implementation uses the passed
1.54 + * CCoeEnv instance to access the resource files.
1.55 + *
1.56 + * @param aEnv the CCoeEnv instance to be used to access the resource
1.57 + * files.
1.58 + * @return a pointer to a new instance of the CTextResolver class.
1.59 + */
1.60 +EXPORT_C CTextResolver* CTextResolver::NewL(CCoeEnv& aEnv)
1.61 + {
1.62 + CTextResolver* self = CTextResolver::NewLC(aEnv);
1.63 + CleanupStack::Pop(self);
1.64 + return self;
1.65 + }
1.66 +
1.67 + /**
1.68 + * Constructor creates a new instance of CTextResolver. The
1.69 + * implementation uses the passed CCoeEnv instance to access the
1.70 + * resource files. Leaves the object on the cleanup stack.
1.71 + *
1.72 + * @param aEnv the CCoeEnv instance to be used to access the resource
1.73 + * files.
1.74 + * @return a pointer to a new instance of the CTextResolver class.
1.75 + */
1.76 +EXPORT_C CTextResolver* CTextResolver::NewLC(CCoeEnv& aEnv)
1.77 + {
1.78 + CTextResolver* self = new (ELeave) CTextResolver(aEnv);
1.79 + CleanupStack::PushL(self);
1.80 + self->ConstructL();
1.81 + return self;
1.82 + }
1.83 +
1.84 + /**
1.85 + * Constructor creates a new instance of CTextResolver. Resource files
1.86 + * are accessed through the RResourceFile API.
1.87 + *
1.88 + * @return a pointer to a new instance of the CTextResolver class.
1.89 + */
1.90 +EXPORT_C CTextResolver* CTextResolver::NewL()
1.91 + {
1.92 + CTextResolver* self = CTextResolver::NewLC();
1.93 + CleanupStack::Pop(self);
1.94 + return self;
1.95 + }
1.96 +
1.97 + /**
1.98 + * Constructor creates a new instance of CTextResolver.Resource files
1.99 + * are accessed through the RResourceFile API. Leaves the object on
1.100 + * the cleanup stack.
1.101 + *
1.102 + * @return a pointer to a new instance of the CTextResolver class.
1.103 + */
1.104 +EXPORT_C CTextResolver* CTextResolver::NewLC()
1.105 + {
1.106 + CTextResolver* self = new (ELeave) CTextResolver();
1.107 + CleanupStack::PushL(self);
1.108 + self->ConstructL();
1.109 + return self;
1.110 + }
1.111 +
1.112 +//
1.113 +// ---------------------------------------------------------
1.114 +// CTextResolver::ConstructL
1.115 +//
1.116 +// Symbian OS default constructor, initializes variables and cache
1.117 +// ---------------------------------------------------------
1.118 +//
1.119 +void CTextResolver::ConstructL()
1.120 + {
1.121 + // if no coe is present, connect new filesession.
1.122 + if (!iCoe)
1.123 + {
1.124 + User::LeaveIfError(iFs.Connect());
1.125 +
1.126 + TFileName resFile(KErrorResResourceFileName);
1.127 + BaflUtils::NearestLanguageFile(iFs, resFile);
1.128 + iResFile.OpenL(iFs, resFile);
1.129 + }
1.130 +
1.131 + iRDSupport = BaflUtils::FileExists(iCoe ? iCoe->FsSession() : iFs, KRDSupport);
1.132 + }
1.133 +
1.134 +/**
1.135 +* Destructor
1.136 +*/
1.137 +EXPORT_C CTextResolver::~CTextResolver()
1.138 + {
1.139 + Reset();
1.140 + iResFile.Close();
1.141 +
1.142 + // if no coe is present, close filesession.
1.143 + if (!iCoe)
1.144 + iFs.Close();
1.145 +
1.146 + delete iTitleText;
1.147 + delete iTextBuffer;
1.148 + delete iContextSeparator;
1.149 + }
1.150 +
1.151 +/**
1.152 +* Resolves the given error code and returns the error text for the
1.153 +* resolved error. Resolved text can be of any length. This version
1.154 +* is for "normal" use.
1.155 +*
1.156 +* @param aError The error code to be resolved.
1.157 +* @param aContext Optional context for error numbers. If the aContext
1.158 +* parameter is not passed to the function, it uses the default value
1.159 +* ECtxAutomatic.
1.160 +* @return the error text for the resolved error. "System error" (in
1.161 +* English localisation) is returned when error code is not known. For
1.162 +* unknown errors blank error flag (flags are defined in
1.163 +* textresolver.hrh) is also set to hide errors without proper
1.164 +* explanation. There is no limit on how long the resolved string
1.165 +* can be.
1.166 +*/
1.167 +EXPORT_C const TDesC& CTextResolver::ResolveErrorString(TInt aError, TErrorContext aContext)
1.168 + {
1.169 + TUint flags(0);
1.170 + TInt id(0);
1.171 + return ResolveErrorString(aError,id,flags,aContext);
1.172 + }
1.173 +
1.174 +/**
1.175 +* Resolves the given error code and returns the error text for the
1.176 +* resolved error. Resolved text can be of any length. This version
1.177 +* is for advanced use
1.178 +*
1.179 +* @param aError The error code to be resolved.
1.180 +* @param aTextId ID of the returned text.
1.181 +* @param aFlags The priority of the returned error. The priority is
1.182 +* defined by the this module! Flags are defined in textresolver.hrh.
1.183 +* @param aContext Optional context for error numbers. If the aContext
1.184 +* parameter is not passed to the function, it uses the default value
1.185 +* ECtxAutomatic.
1.186 +* @return the error text for the resolved error. "System error" (in
1.187 +* English localisation) is returned when error code is not known. For
1.188 +* unknown errors blank error flag (flags are defined in
1.189 +* textresolver.hrh) is also set to hide errors without proper
1.190 +* explanation. There is no limit on how long the resolved string
1.191 +* can be.
1.192 +*/
1.193 +EXPORT_C const TDesC& CTextResolver::ResolveErrorString(TInt aError, TInt& aTextId, TUint& aFlags, TErrorContext aContext)
1.194 + {
1.195 + aFlags = 0;
1.196 + if (iCoe) // Use the resource loaded using the CCoeEnv to read the resource file
1.197 + {
1.198 + TRAPD(err, DoResolveErrorStringL(aError, aTextId, aFlags));
1.199 + if (err)
1.200 + {
1.201 + if ((!AddContextAndSeparator(aContext)))
1.202 + {
1.203 + // Even the resource file opening failed, return OOM flag
1.204 + aFlags |= EErrorResOOMFlag;
1.205 + return KNullDesC;
1.206 + }
1.207 + return *iTextBuffer;
1.208 + }
1.209 +
1.210 + if(aFlags&ETextResolverUnknownErrorFlag) // Error code not supported. No error text found.
1.211 + {
1.212 + // Error is not recognised
1.213 + aTextId = R_ERROR_RES_GENERAL; // Read and return an "unknown error" text from the
1.214 + // Nokia-specific version of the errorres.rss file
1.215 + TPtr appTextPtr = iTitleText->Des();
1.216 + TPtr textPtr = iTextBuffer->Des();
1.217 + iCoe->ReadResourceL(appTextPtr, R_BASE);
1.218 + iCoe->ReadResourceL(textPtr, R_ERROR_RES_GENERAL);
1.219 + }
1.220 + }
1.221 + else // No CCoeEnv available
1.222 + {
1.223 + aTextId = 0;
1.224 + TRAPD(err, DoRawReadOfSystemErrorResourcesToArraysL(aError, aTextId));
1.225 + if(err)
1.226 + {
1.227 + // Cleaning needed since object not destroyed
1.228 + Reset();
1.229 +
1.230 + if (aTextId != R_ERROR_RES_NO_MEMORY || !AddContextAndSeparator(aContext))
1.231 + {
1.232 + // Even the resource file opening failed, return OOM flag
1.233 + aFlags |= EErrorResOOMFlag;
1.234 + return KNullDesC;
1.235 + }
1.236 +
1.237 + return *iTextBuffer;
1.238 + }
1.239 +
1.240 + aTextId = ResourceForError(aError);
1.241 + switch (aTextId)
1.242 + {
1.243 + case KBlankError:
1.244 + {
1.245 + aFlags |= ETextResolverBlankErrorFlag;
1.246 + break;
1.247 + }
1.248 + case KUnknownError:
1.249 + {
1.250 + // Error is not recognised
1.251 + aTextId = R_ERROR_RES_GENERAL;
1.252 +
1.253 + delete iTitleText;
1.254 + iTitleText = AllocReadUnicodeString(iResFile, R_BASE);
1.255 + aFlags |= ETextResolverUnknownErrorFlag;
1.256 + // No break here; Fall through to default case to resolve text for the general error
1.257 + }
1.258 + default:
1.259 + {
1.260 + // --- Error recognised by the resolver, so get the text ---
1.261 + delete iTextBuffer;
1.262 + iTextBuffer = AllocReadUnicodeString(iResFile, aTextId);
1.263 + break;
1.264 + }
1.265 + };
1.266 + }
1.267 +
1.268 + if(aFlags&ETextResolverBlankErrorFlag) // Error code supported, but no error text found.
1.269 + {
1.270 + delete iTextBuffer;
1.271 + iTextBuffer = NULL; // Return no error text at all
1.272 + }
1.273 +
1.274 + if (!AddContextAndSeparator(aContext))
1.275 + {
1.276 + aFlags |= EErrorResOOMFlag;
1.277 + return KNullDesC;
1.278 + }
1.279 +
1.280 + if (iRDSupport && iTextBuffer)
1.281 + {
1.282 + HBufC* tempBuffer = iTextBuffer->ReAlloc(iTextBuffer->Length()+14);
1.283 +
1.284 + // if allocation succeeds, append error id. Otherwise iTextBuffer stays as it is
1.285 + if (tempBuffer)
1.286 + {
1.287 + iTextBuffer = tempBuffer;
1.288 + iTextBuffer->Des().Append(' ');
1.289 + iTextBuffer->Des().Append('(');
1.290 + iTextBuffer->Des().AppendNum(aError);
1.291 + iTextBuffer->Des().Append(')');
1.292 + }
1.293 + }
1.294 + else if (aFlags & ETextResolverUnknownErrorFlag)
1.295 + { // We hide the errors we cannot give proper explanation,
1.296 + //i.e. "System Error" will not be shown.
1.297 + aFlags |= ETextResolverBlankErrorFlag;
1.298 + }
1.299 +
1.300 + if (iTextBuffer)
1.301 + return *iTextBuffer;
1.302 + else
1.303 + return KNullDesC;
1.304 + }
1.305 +
1.306 +TInt CTextResolver::ResourceForError(TInt aError)
1.307 + {
1.308 + ASSERT(!iCoe);
1.309 + const TInt errorCount = iStartError->Count();
1.310 +
1.311 + delete iTitleText;
1.312 + iTitleText = NULL;
1.313 +
1.314 + for (TInt cc = 0; cc < errorCount; ++cc)
1.315 + {
1.316 + const TInt starterror = (*iStartError)[cc];
1.317 + const TInt endError = starterror-(*iErrorTexts)[cc]->Count()+1;
1.318 +
1.319 + if (aError >= endError && aError <= starterror)
1.320 + {
1.321 + ASSERT(!iTitleText);
1.322 + iTitleText = AllocReadUnicodeString(iResFile, (*iAppTexts)[cc]);
1.323 +
1.324 + const TInt errorIndex = -(aError-starterror);
1.325 + const TInt flags = (*iFlags)[cc]->At(errorIndex);
1.326 +
1.327 + if (flags & ETextResolverPanicErrorFlag)
1.328 + {
1.329 + // --- Some errors are never meant to get to the UI level ---
1.330 + // --- Those of them that do, result in a panic ---
1.331 + Panic(aError);
1.332 + }
1.333 +
1.334 + else if (flags & ETextResolverBlankErrorFlag)
1.335 + {
1.336 + // --- Error code can be ignored from the users' perspective ---
1.337 + // --- Return blank error text ---
1.338 + return KBlankError;
1.339 + }
1.340 +
1.341 + else if (flags & ETextResolverUnknownErrorFlag)
1.342 + {
1.343 + // --- Error not recognised by TextResolver ---
1.344 + // --- Will be passed on to UIKON for interpretation ---
1.345 + return KUnknownError;
1.346 + }
1.347 +
1.348 + return (*iErrorTexts)[cc]->At(errorIndex);
1.349 + }
1.350 + }
1.351 +
1.352 + return KUnknownError;
1.353 + }
1.354 +
1.355 +
1.356 +/**
1.357 +Read the system error texts from errorres.rss only, without using the Uikon CEikErrorResolver.
1.358 +This will not pick up any appliation specific errors.
1.359 +*/
1.360 +void CTextResolver::DoRawReadOfSystemErrorResourcesToArraysL(TInt& aError, TInt& aTextId)
1.361 + {
1.362 + ASSERT(!iCoe);
1.363 + TResourceReader reader;
1.364 + ReadLocalizedSeparatorCharacterFromResourceAndPrepareResourceReaderLC(reader);
1.365 +
1.366 + // Lets handle KErrNoMemory as a special case, this this way we can maybe avoid extra "Resolving Errors"
1.367 + if (aError == KErrNoMemory)
1.368 + {
1.369 + ASSERT(!iTextBuffer && !iTitleText);
1.370 + aTextId = R_ERROR_RES_NO_MEMORY;
1.371 + iTextBuffer = AllocReadUnicodeString(iResFile, aTextId);
1.372 + iTitleText = AllocReadUnicodeString(iResFile, R_BASE);
1.373 + User::Leave(KErrNoMemory);
1.374 + }
1.375 +
1.376 + if(iStartError && iErrorTexts && iFlags && iAppTexts)
1.377 + {
1.378 + CleanupStack::PopAndDestroy(); // rBuffer
1.379 + return; // Already all done
1.380 + }
1.381 +
1.382 + // The resource data is used differenciate between the old and new resource formats
1.383 + // (i.e, resources using title text and one's without using title text)
1.384 + // This API only support the new format, so just check that it is on the new format
1.385 + const TInt dummy = reader.ReadInt16();
1.386 + const TInt version = reader.ReadInt16();
1.387 + __ASSERT_ALWAYS(dummy == 0 && version == 2, User::Leave(KErrNotSupported));
1.388 +
1.389 + // Read into the error arrays
1.390 + const TInt arrayCount = reader.ReadInt16();
1.391 +
1.392 + ASSERT(!iStartError && !iErrorTexts && !iFlags && !iAppTexts);
1.393 + iStartError = new(ELeave) CArrayFixFlat<TInt>(arrayCount);
1.394 + iErrorTexts = new(ELeave) CArrayPtrSeg<CErrorResourceIdArray>(arrayCount);
1.395 + iFlags = new(ELeave) CArrayPtrSeg<CErrorResourceFlagArray>(arrayCount);
1.396 + iAppTexts = new(ELeave) CArrayFixFlat<TInt>(arrayCount);
1.397 +
1.398 + for (TInt cc = 0; cc < arrayCount; ++cc)
1.399 + {
1.400 + // Read in error array
1.401 + iAppTexts->AppendL(reader.ReadInt32()); // Application indicators
1.402 + iStartError->AppendL(reader.ReadInt32());
1.403 +
1.404 + const TInt listId = reader.ReadInt32();
1.405 +
1.406 + TResourceReader reader2;
1.407 + HBufC8* rBuffer = iResFile.AllocReadL(listId & KRIMask); // Remove offset from id
1.408 + reader2.SetBuffer(rBuffer);
1.409 + CleanupStack::PushL(rBuffer);
1.410 +
1.411 + const TInt count = reader2.ReadInt16();
1.412 + CArrayFixFlat<TInt>* array = new(ELeave) CErrorResourceIdArray(count);
1.413 + CleanupStack::PushL(array);
1.414 +
1.415 + CArrayFixFlat<TInt>* flagarray = new(ELeave) CErrorResourceFlagArray(count);
1.416 + CleanupStack::PushL(flagarray);
1.417 +
1.418 + for (TInt dd = 0; dd < count; ++dd)
1.419 + {
1.420 + const TInt flags = reader2.ReadInt8();
1.421 + flagarray->AppendL(flags);
1.422 + // Append resource id for this error text
1.423 + array->AppendL(reader2.ReadInt32());
1.424 + }
1.425 +
1.426 + iFlags->AppendL(flagarray);
1.427 + CleanupStack::Pop(flagarray);
1.428 +
1.429 + iErrorTexts->AppendL(array);
1.430 + CleanupStack::Pop(array);
1.431 +
1.432 + CleanupStack::PopAndDestroy(rBuffer);
1.433 + }
1.434 +
1.435 + CleanupStack::PopAndDestroy(); // reader's rBuffer
1.436 + }
1.437 +
1.438 +// ---------------------------------------------------------
1.439 +// CTextResolver::Reset()
1.440 +//
1.441 +// Reset the member variables
1.442 +// ---------------------------------------------------------
1.443 +//
1.444 +void CTextResolver::Reset()
1.445 + {
1.446 + if (iBaseResourceFileOffset)
1.447 + {
1.448 + iCoe->DeleteResourceFile(iBaseResourceFileOffset);
1.449 + iBaseResourceFileOffset = 0;
1.450 + }
1.451 +
1.452 + if (iErrorTexts)
1.453 + {
1.454 + iErrorTexts->ResetAndDestroy();
1.455 + delete iErrorTexts;
1.456 + iErrorTexts = NULL;
1.457 + }
1.458 +
1.459 + if (iFlags)
1.460 + {
1.461 + iFlags->ResetAndDestroy();
1.462 + delete iFlags;
1.463 + iFlags = NULL;
1.464 + }
1.465 +
1.466 + delete iStartError;
1.467 + iStartError = NULL;
1.468 +
1.469 + delete iAppTexts;
1.470 + iAppTexts = NULL;
1.471 + }
1.472 +
1.473 +/**
1.474 +ErrorResolver resource files in the ?:/resource/errors/ folder must always begin with
1.475 +an array of error texts. The Nokia-specific version of the errorres.rss file also
1.476 +contains the localized titel/text separator character at the end of the file.
1.477 +This method reads the separator character from file using the CCoeEnv provided.
1.478 +*/
1.479 +void CTextResolver::ReadLocalizedSeparatorCharacterFromResourceL(CCoeEnv& aCoeEnv)
1.480 + {
1.481 + ASSERT(&aCoeEnv);
1.482 +
1.483 + if (!iBaseResourceFileOffset)
1.484 + {
1.485 + TFileName filename(KErrorResResourceFileName);
1.486 + BaflUtils::NearestLanguageFile(aCoeEnv.FsSession(), filename);
1.487 +
1.488 + iBaseResourceFileOffset = aCoeEnv.AddResourceFileL(filename);
1.489 +
1.490 + ASSERT(!iContextSeparator);
1.491 + iContextSeparator = aCoeEnv.AllocReadResourceL(R_LOCALIZED_CONTEXT_SEPARATOR);
1.492 + }
1.493 + }
1.494 +
1.495 +/**
1.496 +ErrorResolver resource files in the ?:/resource/errors/ folder must always begin with
1.497 +an array of error texts. The Nokia-specific version of the errorres.rss file also
1.498 +contains the localized titel/text separator character at the end of the file.
1.499 +This method reads the separator character from file WITHOUT using a CCoeEnv.
1.500 +*/
1.501 +void CTextResolver::ReadLocalizedSeparatorCharacterFromResourceAndPrepareResourceReaderLC(TResourceReader& aResReader)
1.502 + {
1.503 + ASSERT(!iCoe);
1.504 + ASSERT(!iBaseResourceFileOffset);
1.505 +
1.506 + HBufC8* rBuffer = iResFile.AllocReadL(R_ERROR_RES_BASE_LIST & KRIMask); // Remove offset from id
1.507 + aResReader.SetBuffer(rBuffer);
1.508 + CleanupStack::PushL(rBuffer);
1.509 +
1.510 + if(!iContextSeparator)
1.511 + iContextSeparator = AllocReadUnicodeString(iResFile, R_LOCALIZED_CONTEXT_SEPARATOR);
1.512 +
1.513 + // Leave rBuffer on CleanupStack
1.514 + }
1.515 +
1.516 +// returns NULL if out of memory
1.517 +HBufC* CTextResolver::AllocReadUnicodeString(RResourceFile& aResFile, TInt aTextId)
1.518 + {
1.519 + // Reading Unicode string w/o CCoe
1.520 + HBufC8* tempBuffer = NULL;
1.521 + HBufC* retBuffer = NULL;
1.522 +
1.523 + TRAPD(err, tempBuffer = aResFile.AllocReadL((KRIMask & aTextId))); // Remove offset from id
1.524 + if (!err)
1.525 + {
1.526 + __ASSERT_DEBUG((tempBuffer->Length()%2)==0,Panic(aTextId));
1.527 +
1.528 + // do bitwise shift to halve the length for mapping the tempBuffer to unicode.
1.529 + TInt newLen = tempBuffer->Length()>>1;
1.530 + TPtrC tempPointer((TText*)tempBuffer->Ptr(), newLen);
1.531 +
1.532 + retBuffer = tempPointer.Alloc();
1.533 + delete tempBuffer;
1.534 + }
1.535 +
1.536 + return retBuffer;
1.537 + }
1.538 +
1.539 +TBool CTextResolver::AddContextAndSeparator(TErrorContext aContext)
1.540 + {
1.541 + TBool retval(EFalse);
1.542 +
1.543 + if (iTextBuffer && iTitleText && iContextSeparator) // If we got all the parts we need...
1.544 + {
1.545 + //... then put them together according to the aContext argument
1.546 +
1.547 + // Context checked after validity of string buffers is checked,
1.548 + // because EFalse return value is required if any of those is NULL.
1.549 + if (aContext == ECtxNoCtxNoSeparator)
1.550 + retval = ETrue;
1.551 + else
1.552 + {
1.553 + HBufC* tempBuffer = iTextBuffer->ReAlloc(iTextBuffer->Length()+iContextSeparator->Length()+iTitleText->Length()+1);
1.554 +
1.555 + // If allocation succeeds, insert context. Otherwise iTextBuffer stays as it is.
1.556 + if (tempBuffer)
1.557 + {
1.558 + iTextBuffer = tempBuffer;
1.559 +
1.560 + // Add the title ("context") text and separator before the error text
1.561 +
1.562 + _LIT(KNewLineChar, "\n");
1.563 + iTextBuffer->Des().Insert(0, KNewLineChar);
1.564 + iTextBuffer->Des().Insert(0, *iContextSeparator);
1.565 +
1.566 + if (aContext != ECtxNoCtx)
1.567 + iTextBuffer->Des().Insert(0,*iTitleText);
1.568 +
1.569 + retval = ETrue;
1.570 + }
1.571 + }
1.572 + }
1.573 + return retval;
1.574 + }
1.575 +
1.576 +void CTextResolver::AllocBuffersL()
1.577 + {
1.578 + delete iTitleText;
1.579 + iTitleText = NULL;
1.580 + delete iTextBuffer;
1.581 + iTextBuffer = NULL;
1.582 +
1.583 + iTitleText = HBufC::NewL(KEikErrorResolverMaxTextLength);
1.584 + iTextBuffer = HBufC::NewL(KEikErrorResolverMaxTextLength);
1.585 + }
1.586 +
1.587 +void CTextResolver::DoResolveErrorStringL(TInt aError, TInt& aTextId, TUint& aFlags)
1.588 + {
1.589 + ASSERT(iCoe);
1.590 + AllocBuffersL();
1.591 +
1.592 + TPtr errTextPtr = iTextBuffer->Des();
1.593 + TPtr errTitlePtr = iTitleText->Des();
1.594 +
1.595 + CEikonEnv::TErrorValidity errValidity = static_cast<CEikonEnv*>(iCoe)->DoGetErrorTextAndTitle(errTextPtr, aError, aTextId, aFlags, errTitlePtr, ETrue);
1.596 +
1.597 + if (errValidity == CEikonEnv::EErrorNumInvalid)
1.598 + Panic(aError);
1.599 +
1.600 + // If either the iTextBuffer or iTitleText buffers were too small,
1.601 + // they will contain the required length coded as digits into the buffer
1.602 + TLex sizeRealloc(*iTextBuffer);
1.603 + TInt sizeRequiredForTextBuffer = 0;
1.604 + TInt sizeRequiredForTitleBuffer = 0;
1.605 +
1.606 + // Try reading the size required, if any
1.607 + sizeRealloc.Val(sizeRequiredForTextBuffer);
1.608 + sizeRealloc = *iTitleText;
1.609 + sizeRealloc.Val(sizeRequiredForTitleBuffer);
1.610 +
1.611 + // If sizes were found, realloc and get the error text again
1.612 + if (sizeRequiredForTextBuffer || sizeRequiredForTitleBuffer)
1.613 + {
1.614 + if (sizeRequiredForTextBuffer)
1.615 + {
1.616 + delete iTextBuffer;
1.617 + iTextBuffer = NULL;
1.618 + iTextBuffer = HBufC::NewL(sizeRequiredForTextBuffer);
1.619 + }
1.620 +
1.621 + if (sizeRequiredForTitleBuffer)
1.622 + {
1.623 + delete iTitleText;
1.624 + iTitleText = NULL;
1.625 + iTitleText = HBufC::NewL(sizeRequiredForTitleBuffer);
1.626 + }
1.627 +
1.628 + TPtr errTextPtr(iTextBuffer->Des());
1.629 + TPtr errTitlePtr(iTitleText->Des());
1.630 + errValidity = static_cast<CEikonEnv*>(iCoe)->DoGetErrorTextAndTitle(errTextPtr, aError, aTextId, aFlags, errTitlePtr, ETrue);
1.631 + if (!iTextBuffer->Length())
1.632 + {
1.633 + delete iTextBuffer;
1.634 + iTextBuffer = NULL;
1.635 + }
1.636 + }
1.637 +
1.638 + ReadLocalizedSeparatorCharacterFromResourceL(*iCoe);
1.639 + }
1.640 +
1.641 +// End of File
1.642 +
1.643 +