--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/localisation/apparchitecture/apparc/APACMDLN.CPP Thu Jan 21 12:53:44 2010 +0000
@@ -0,0 +1,815 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <apacmdln.h>
+#include "APASTD.H" // Panics etc.
+#include <s32mem.h>
+
+#include <e32svr.h>
+
+_LIT(KLitTokenServerDifferentiator, "-srvDfr=");
+_LIT(KLitTokenDefaultScreenNumber, "-dsc=");
+_LIT(KLitTokenParentWindowGroupID, "-prntwgid=");
+_LIT(KLitTokenDebugMemFail, "-debugMemFail:");
+_LIT(KLitTokenAppStartupInstrumentationEventIdBase, "-appStartupInstrEvIdBase=");
+_LIT(KLitTokenOpaqueData, "-opaque=");
+
+// CApaCommandLine
+
+CApaCommandLine::CApaCommandLine() :
+ iDocumentName( NULL), iExecutableName(NULL), iOpaqueData(NULL),
+ iTailEnd(NULL), iCommand(EApaCommandRun),
+ iServerDifferentiator(0), iDefaultScreenNumber(-1),
+ iParentWindowGroupID(0), iDebugMemFail(0), iAppStartupInstrumentationEventIdBase(0),
+ iFile(), iParentProcessId(KNullProcessId)
+ //
+ // private c'tor - initialize using NewLC()
+ //
+ {
+ }
+
+EXPORT_C CApaCommandLine::~CApaCommandLine()
+/** Destructor.
+
+Frees resources owned by the object prior to deletion. */
+ {
+ delete iDocumentName;
+ delete iExecutableName;
+ delete iOpaqueData;
+ delete iTailEnd;
+ iFile.Close();
+ }
+
+EXPORT_C CApaCommandLine* CApaCommandLine::NewL()
+/** Creates an empty command line object.
+
+@return A pointer to the new command line object. */
+ {
+ CApaCommandLine* This=CApaCommandLine::NewLC();
+ CleanupStack::Pop();
+ return This;
+ }
+
+EXPORT_C void CApaCommandLine::ConstructCmdLineFromMessageL(const RMessage2& aMessage)
+/** Acts as a second constructor and completes a commandline object from
+ the aMessage object.
+
+@internalTechnology */
+ {
+ const TInt bufLen = aMessage.GetDesLengthL(EIpcSlotMain);
+ HBufC8* const buffer=HBufC8::NewLC(bufLen);
+ {TPtr8 buffer_asWritable(buffer->Des());
+ aMessage.ReadL(EIpcSlotMain, buffer_asWritable);}
+ RDesReadStream stream;
+ stream.Open(*buffer);
+ InternalizeL(stream);
+ CleanupStack::PopAndDestroy(buffer);
+
+ iFile.AdoptFromClient(aMessage, EIpcSlotFsSession, EIpcSlotFile); // ignore the returned error - assume it means that no file has been passed across
+ }
+
+void CApaCommandLine::GetCommandLineFromProcessEnvironmentL()
+ {
+ const TInt bufLen = User::ParameterLength(EEnvironmentSlotMain);
+ if (bufLen==KErrNotFound)
+ {
+ HBufC* const commandLineString=HBufC::NewLC(User::CommandLineLength());
+ {TPtr commandLineString_asWritable(commandLineString->Des());
+ User::CommandLine(commandLineString_asWritable);}
+ User::LeaveIfError(Parse(*commandLineString));
+ CleanupStack::PopAndDestroy(commandLineString);
+ }
+ else
+ {
+ User::LeaveIfError(bufLen); // in case bufLen is some error other than KErrNotFound
+ HBufC8* const buffer=HBufC8::NewLC(bufLen);
+ {TPtr8 buffer_asWritable(buffer->Des());
+ User::LeaveIfError(User::GetDesParameter(EEnvironmentSlotMain, buffer_asWritable));}
+ RDesReadStream stream;
+ stream.Open(*buffer);
+ InternalizeL(stream);
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+ iFile.AdoptFromCreator(EEnvironmentSlotFsSession, EEnvironmentSlotFile); // ignore the returned error - assume it means that no file has been passed across
+ }
+
+EXPORT_C CApaCommandLine* CApaCommandLine::NewLC()
+/** Creates an empty command line object, and puts a pointer to it onto the cleanup
+stack.
+
+@return A pointer to the new command line object. */
+ {
+ CApaCommandLine* This=new(ELeave) CApaCommandLine;
+ CleanupStack::PushL(This);
+ return This;
+ }
+
+EXPORT_C void CApaCommandLine::SetDocumentNameL(const TDesC& aDocName)
+/** Sets the document name from the specified descriptor.
+
+If the document name has embedded spaces, then it must be enclosed within
+quotation marks.
+
+@param aDocName A descriptor containing the document name. */
+ {
+ HBufC* const documentName=aDocName.AllocL();
+ delete iDocumentName; // only done after the AllocL succeeds
+ iDocumentName=documentName;
+ }
+
+EXPORT_C TPtrC CApaCommandLine::DocumentName() const
+/** Gets the document name from the launch information.
+
+@return A pointer descriptor representing the document name. The document
+name is returned without any enclosing quotation marks. If the launch information
+contains no document name, then the pointer descriptor has zero length. */
+ {
+ if (iDocumentName!=NULL)
+ {
+ return *iDocumentName;
+ }
+ return KNullDesC();
+ }
+
+EXPORT_C void CApaCommandLine::SetExecutableNameL(const TDesC& aExecutableName)
+/** Sets the executable name from the specified descriptor.
+
+@param aExecutableName A descriptor containing the executable name. */
+ {
+ HBufC* const executableName=aExecutableName.AllocL();
+ delete iExecutableName; // only done after the AllocL succeeds
+ iExecutableName=executableName;
+ }
+
+EXPORT_C TPtrC CApaCommandLine::ExecutableName() const
+/** Gets the executable name from the launch information.
+
+@return A pointer descriptor representing the executable name. */
+ {
+ if (iExecutableName!=NULL)
+ {
+ return *iExecutableName;
+ }
+ return KNullDesC();
+ }
+
+EXPORT_C void CApaCommandLine::SetOpaqueDataL(const TDesC8& aOpaqueData)
+/** Sets the opaque-data from the specified 8-bit descriptor.
+
+This is called internally and populated from the data in the application's registration resource file,
+i.e. from the resource indicated by the opaque_data field of the APP_REGISTRATION_INFO resource (if the
+opaque_data field was non-zero).
+
+@param aOpaqueData An 8-bit descriptor containing the opaque-data. */
+ {
+ HBufC8* const opaqueData = aOpaqueData.AllocL();
+ delete iOpaqueData;
+ iOpaqueData = opaqueData;
+ }
+
+EXPORT_C TPtrC8 CApaCommandLine::OpaqueData() const
+/** Gets the opaque-data from the launch information.
+
+See the description of SetOpaqueDataL. By default, this attribute is an empty descriptor.
+
+@see SetOpaqueDataL
+@return An 8-bit pointer descriptor representing the opaque-data. */
+ {
+ if (iOpaqueData != NULL)
+ {
+ return *iOpaqueData;
+ }
+ return KNullDesC8();
+ }
+
+EXPORT_C void CApaCommandLine::SetCommandL(TApaCommand aCommand)
+/** Sets the command code.
+
+The command code is used to indicate how an application is to be launched.
+
+@see TApaCommand
+@param aCommand The command code. */
+ {
+ iCommand=aCommand;
+ }
+
+EXPORT_C TApaCommand CApaCommandLine::Command() const
+/** Gets the command code from the launch information.
+
+See the description of SetCommandL.
+
+@see SetCommandL
+@see TApaCommand
+@return The command code. */
+ {
+ return iCommand;
+ }
+
+EXPORT_C void CApaCommandLine::SetTailEndL(const TDesC8& aTailEnd)
+/** Sets the trailing data.
+
+The UI Framework provides a specific set of pre-defined command line
+options. Additional user defined or pre-defined command line options,
+may be passed to an application by setting the TailEnd.
+
+@param aTailEnd An 8 bit descriptor containing the trailing data. */
+ {
+ HBufC8* const newTailEnd=aTailEnd.AllocL();
+ delete iTailEnd; // only done after the AllocL succeeds
+ iTailEnd=newTailEnd;
+ }
+
+EXPORT_C TPtrC8 CApaCommandLine::TailEnd() const
+/** Gets the trailing data from the launch information.
+
+See the description of SetTailEndL.
+
+@see SetTailEndL
+@return A pointer descriptor representing the trailing data. If the launch
+information contains no trailing data, then the pointer descriptor has zero
+length. */
+ {
+ if (iTailEnd!=NULL)
+ {
+ return *iTailEnd;
+ }
+ return KNullDesC8();
+ }
+
+EXPORT_C void CApaCommandLine::SetFileByHandleL(const RFile& aFile)
+/** Sets the file to be passed into the application (by handle).
+This will then be retrieved by that application-process calling GetFileByHandleL().
+
+@publishedPartner
+@released
+@param aFile The file object to be passed into the application. No transfer of this
+object's ownership takes place in this function. */
+ {
+ __ASSERT_ALWAYS(aFile.SubSessionHandle()!=KNullHandle, Panic(EPanicInvalidHandle));
+ __ASSERT_ALWAYS(iFile.SubSessionHandle()==KNullHandle, Panic(EPanicHandleAlreadySet));
+ User::LeaveIfError(iFile.Duplicate(aFile));
+ }
+
+EXPORT_C void CApaCommandLine::GetFileByHandleL(RFile& aFile) const
+/** Opens (by handle) the file that was passed into SetFileByHandleL by the process launching the local application.
+
+On entering this function, aFile must be non-open. It is recommended that aFile is
+pushed onto the cleanup-stack (via CleanupClosePushL()) before this function is called.
+
+@publishedPartner
+@released
+@param aFile The file object to be set up from the handle passed into the application. The
+caller has the responsibility to Close() this object, even if this function leaves. */
+ {
+ __ASSERT_ALWAYS(aFile.SubSessionHandle()==KNullHandle, Panic(EPanicHandleAlreadySet));
+ if (iFile.SubSessionHandle()!=KNullHandle)
+ {
+ User::LeaveIfError(aFile.Duplicate(iFile));
+ }
+ }
+
+/** Assigns a command line to a process (EKA2 only).
+
+This replaces the EKA1 method which involved retrieving the full command line (using
+CApaCommandLine::FullCommandLine()) and passing it to the process (or thread on the
+emulator).
+
+This function is used as follows (the order of the first 2 steps is irrelevant):-
+- create the process and load the executable (RProcess::Create()),
+- create the command line object (CApaCommandLine::NewLC()), and set it up using
+the various setter functions, for instance SetDocumentNameL(),
+- call SetProcessEnvironmentL() to assign the command line to the process,
+- call Resume() on the process.
+
+Note that this sequence of steps bypasses the application architecture, and is
+not recommended. RApaLsSession::StartApp() is the recommended way to
+launch an application with a command line.
+
+@param aProcess The process to which the command line is assigned.
+@leave KErrNotSupported This indicates that the function was called on EKA1.
+@see RApaLsSession::StartApp()
+*/
+EXPORT_C void CApaCommandLine::SetProcessEnvironmentL(RProcess& aProcess) const
+ {
+ HBufC8* const streamableAttributes=StreamableAttributesLC();
+ User::LeaveIfError(aProcess.SetParameter(EEnvironmentSlotMain, *streamableAttributes));
+ CleanupStack::PopAndDestroy(streamableAttributes);
+
+ if (iFile.SubSessionHandle()!=KNullHandle)
+ {
+ User::LeaveIfError(iFile.TransferToProcess(aProcess, EEnvironmentSlotFsSession, EEnvironmentSlotFile));
+ }
+ }
+
+EXPORT_C void CApaCommandLine::GetIpcArgsLC(TIpcArgs& aIpcArgs) const
+/**
+@internalTechnology
+*/
+ {
+ aIpcArgs.Set(EIpcSlotMain, StreamableAttributesLC());
+ if (iFile.SubSessionHandle()!=KNullHandle)
+ {
+ User::LeaveIfError(iFile.TransferToServer(aIpcArgs, EIpcSlotFsSession, EIpcSlotFile));
+ }
+ }
+
+EXPORT_C TInt CApaCommandLine::GetCommandLineFromProcessEnvironment(CApaCommandLine*& aCommandLine)
+/** Constructs a command line object.
+
+If command line information is provided in the environment-slots it creates command line object from
+process environment-slots, else creates it from the information returned by User::CommandLine().
+
+It can be called from a context where there is no CTrapCleanup.
+
+Calling this function more than once in a process is not supported and will result in an empty command
+line being returned. If an application wants to inspect any part of its command line, it
+should override CEikAppUi::ProcessCommandParametersL(CApaCommandLine& aCommandLine) and call the base
+class implementation if required.
+
+@see CEikAppUi::ProcessCommandParametersL(CApaCommandLine& aCommandLine).
+@param aCommandLine On return, a pointer to a newly constructed command line object.
+@return KErrNone, if successful; otherwise one of the other system-wide error codes.
+@internalTechnology */
+ { // static
+ aCommandLine = NULL;
+ CApaCommandLine* const commandLine = new CApaCommandLine;
+ if(!commandLine)
+ return KErrNoMemory;
+
+ CTrapCleanup* trapCleanup = NULL;
+ if (!User::TrapHandler())
+ {
+ trapCleanup = CTrapCleanup::New(); // we're being called from an environment without a cleanup-stack, so temporarily create one here
+ if(!trapCleanup)
+ {
+ delete commandLine;
+ return KErrNoMemory;
+ }
+ }
+
+ TRAPD(error, commandLine->GetCommandLineFromProcessEnvironmentL());
+ aCommandLine = commandLine;
+ delete trapCleanup;
+ return error;
+ }
+
+EXPORT_C void CApaCommandLine::SetParentProcessId(TProcessId aProcessId)
+/** Sets the Parent Process ID for the Child Process launched with this command line.
+
+This establishes a Parent-Child relationship which ensures that the child process is
+terminated when the parent terminates.
+
+@param aProcessId The Process ID. */
+ {
+ iParentProcessId=aProcessId;
+ }
+
+EXPORT_C TProcessId CApaCommandLine::ParentProcessId() const
+/** Gets the Parent Process ID of the Child Process launched with this command line.
+
+See the description of SetParentProcessId.
+
+@see SetParentProcessId
+@return The Parent Process ID. */
+ {
+ return iParentProcessId;
+ }
+
+
+void CApaCommandLine::ExternalizeL(RWriteStream& aStream) const
+ {
+ // iFile is not supported via RReadStream/RWriteStream
+ aStream << DocumentName();
+ aStream << ExecutableName();
+ aStream << OpaqueData();
+ aStream << TailEnd();
+ aStream.WriteInt32L(iCommand);
+ aStream.WriteInt32L(iServerDifferentiator);
+ aStream.WriteInt32L(iDefaultScreenNumber);
+ aStream.WriteInt32L(iParentWindowGroupID);
+ aStream.WriteInt32L(iDebugMemFail);
+ aStream.WriteInt32L(iAppStartupInstrumentationEventIdBase);
+ aStream.WriteInt32L(iParentProcessId);
+ }
+
+
+void CApaCommandLine::InternalizeL(RReadStream& aStream)
+ {
+ // iFile is not supported via RReadStream/RWriteStream
+ const TInt KMaxBufLength = 4000;
+ iDocumentName = HBufC::NewL(aStream,KMaxBufLength);
+ iExecutableName = HBufC::NewL(aStream,KMaxBufLength);
+ iOpaqueData = HBufC8::NewL(aStream, KMaxBufLength);
+ iTailEnd = HBufC8::NewL(aStream,KMaxBufLength);
+ iCommand = static_cast<TApaCommand>(aStream.ReadInt32L());
+ iServerDifferentiator = aStream.ReadInt32L();
+ iDefaultScreenNumber = aStream.ReadInt32L();
+ iParentWindowGroupID = aStream.ReadInt32L();
+ iDebugMemFail = aStream.ReadInt32L();
+ iAppStartupInstrumentationEventIdBase = aStream.ReadInt32L();
+ iParentProcessId=aStream.ReadInt32L();
+ }
+
+HBufC8* CApaCommandLine::StreamableAttributesLC() const
+ {
+ CBufFlat* const buffer = CBufFlat::NewL(128);
+ CleanupStack::PushL(buffer);
+ RBufWriteStream writeStream;
+ writeStream.Truncate(*buffer);
+ ExternalizeL(writeStream);
+ writeStream.CommitL();
+ HBufC8* const bufferAsDescriptor = buffer->Ptr(0).AllocL();
+ CleanupStack::PopAndDestroy(buffer);
+ CleanupStack::PushL(bufferAsDescriptor);
+ return bufferAsDescriptor;
+ }
+
+EXPORT_C void CApaCommandLine::SetServerNotRequiredL()
+/** Sets that no server is required.
+
+The value of server differentiator is set to zero, to indicate that no server
+is required.
+
+See the description of SetServerRequiredL.
+@see SetServerRequiredL
+*/
+ {
+ SetServerDifferentiatorL(0);
+ }
+
+EXPORT_C void CApaCommandLine::SetServerRequiredL(TUint aServerDifferentiator)
+/** Sets the required server.
+
+The server differentiator is a number generated by the client that helps to uniquely
+identify the server. It is used by an application to indicate whether a server should
+be created and how it should be named.
+
+@param aServerDifferentiator A differentiator for the required server.*/
+
+ {
+ SetServerDifferentiatorL(aServerDifferentiator);
+ }
+
+void CApaCommandLine::SetServerDifferentiatorL(TUint aServerDifferentiator)
+ {
+ iServerDifferentiator=aServerDifferentiator;
+ }
+
+EXPORT_C TUint CApaCommandLine::ServerRequired() const
+/** Gets the server differentiator.
+
+See the description of SetServerRequiredL.
+
+@see SetServerRequiredL
+@return The non-zero differentiator for the server, else zero indicating a server
+is not required.*/
+ {
+ return iServerDifferentiator;
+ }
+
+EXPORT_C void CApaCommandLine::SetDefaultScreenL(TInt aDefaultScreenNumber)
+/** Provides support for devices with more than one screen. A number representing the default
+or startup screen may be passed to an application.
+Screen numbers and characteristics are defined in the window server initialisation
+file (wsini.ini).
+
+@param aDefaultScreenNumber The number of the default (startup) screen. */
+ {
+ __ASSERT_ALWAYS(aDefaultScreenNumber>=0, Panic(EPanicInvalidScreenNumber));
+ iDefaultScreenNumber=aDefaultScreenNumber;
+ }
+
+EXPORT_C TInt CApaCommandLine::DefaultScreen() const
+/** Extracts and returns the default (startup) screen that was specified in the command line.
+
+@return A number representing the default (startup) screen. 0 (Zero) if nothing present. */
+ {
+ return Max(0, iDefaultScreenNumber);
+ }
+
+EXPORT_C TBool CApaCommandLine::IsDefaultScreenSet() const
+/**
+@internalTechnology
+*/
+ {
+ return (iDefaultScreenNumber>=0);
+ }
+
+EXPORT_C void CApaCommandLine::SetParentWindowGroupID(TInt aParentWindowGroupID)
+/** Sets the ID of the parent window-group - the application should create its own
+window-group as a child off this parent.
+
+@param aParentWindowGroupID The ID of the parent window-group - the application
+should create its window-group as a child off this parent. */
+ {
+ iParentWindowGroupID=aParentWindowGroupID;
+ }
+
+EXPORT_C TInt CApaCommandLine::ParentWindowGroupID() const
+/** Returns the ID of the parent window-group - the application should create its own
+window-group as a child of this parent.
+
+@return The ID of the parent window-group - the application should create its
+window-group as a child off this . */
+ {
+ return iParentWindowGroupID;
+ }
+
+EXPORT_C void CApaCommandLine::SetDebugMemFailL(TInt aDebugMemFail)
+/** @internalAll */
+ {
+ iDebugMemFail=aDebugMemFail;
+ }
+
+EXPORT_C TInt CApaCommandLine::DebugMemFail() const
+/** @internalAll */
+ {
+ return iDebugMemFail;
+ }
+
+EXPORT_C void CApaCommandLine::SetAppStartupInstrumentationEventIdBaseL(TInt aAppStartupInstrumentationEventIdBase)
+/** @internalAll */
+ {
+ iAppStartupInstrumentationEventIdBase=aAppStartupInstrumentationEventIdBase;
+ }
+
+EXPORT_C TInt CApaCommandLine::AppStartupInstrumentationEventIdBase() const
+/** @internalAll */
+ {
+ return iAppStartupInstrumentationEventIdBase;
+ }
+
+EXPORT_C TInt CApaCommandLine::EnvironmentSlotForPublicUse(TInt aIndex)
+/** Returns the index of a process environment-slot for public use (in other words,
+one that is not used internally by CApaCommandLine). The number of slots available
+for public use can be found in the (private) enum value CApaCommandLine::ENumberOfEnvironmentSlotsForPublicUse,
+(this value may be increased over time). The returned value can then be passed into
+any of the Open(TInt,...) functions on RSessionBase, RMutex, RChunk, RCondVar, etc,
+or into User::GetTIntParameter(), User::GetDesParameter(), etc, depending on the type
+of the object in that environment slot.
+
+@param aIndex The logical index of the public environment-slot. This must be greater
+than or equal to zero, and less than CApaCommandLine::ENumberOfEnvironmentSlotsForPublicUse.
+@return The physical index of an environment-slot in the local process. */
+ { // static
+ __ASSERT_ALWAYS((aIndex>=0) && (aIndex<ENumberOfEnvironmentSlotsForPublicUse), Panic(EPanicEnvironmentSlotNotForPublicUse));
+ return EFirstEnvironmentSlotForPublicUse+aIndex;
+ }
+
+TInt CApaCommandLine::Parse(const TDesC& aCmdLine)
+// does the opposite of SetCmdLineL, i.e. sets iDocumentName, iExecutableName, iTailEnd, iCommand, iServerDifferentiator, iDefaultScreenNumber, iParentWindowGroupID , iDebugMemFail & iAppStartupInstrumentationEventIdBase from aCmdLine
+// also sets iOpaqueData
+ {
+ const TInt cmdLength=aCmdLine.Length();
+
+ // these variables are all "shadows" of member variables - we'll set the member variables corresponding to these at the end of this function, once all memory-allocation has succeeded, to make this function atomic
+ TInt endLibNameOffset=cmdLength-1;
+ TInt endDocNameOffset=cmdLength-1;
+ HBufC* documentName=NULL;
+ HBufC* executableName=NULL;
+ HBufC8* tailEnd=NULL;
+ HBufC8* opaqueData=NULL;
+ TApaCommand command=EApaCommandRun;
+ TInt serverDifferentiator=0;
+ TInt defaultScreenNumber=-1;
+ TInt parentWindowGroupID=0;
+ TInt debugMemFail=0;
+ TInt appStartupInstrumentationEventIdBase=0;
+ TInt notUsed;
+
+ TBool openQuote=EFalse;
+ TBool foundEndLibName=EFalse;
+ for (TInt i=0; i<cmdLength; ++i)
+ {
+ TChar current=aCmdLine[i];
+ if (current=='"')
+ {
+ openQuote=!openQuote;
+ continue;
+ };
+ if ((current==' ') && !openQuote)
+ {
+ // space found outside of quotes
+ if (foundEndLibName)
+ {
+ endDocNameOffset=i-1;
+ break; // parse no further
+ }
+ endLibNameOffset=i-1;
+ foundEndLibName=ETrue;
+ }
+ }
+ if (endLibNameOffset>-1)
+ {
+ executableName=StripQuotes(aCmdLine.Left(endLibNameOffset+1)).Alloc();
+ if (executableName==NULL)
+ {
+ delete documentName;
+ delete executableName;
+ delete tailEnd;
+ delete opaqueData;
+ return KErrNoMemory;
+ }
+ }
+ TInt offset=endDocNameOffset-endLibNameOffset;
+ if (offset>1)
+ {
+ TChar commandLetter=aCmdLine[endLibNameOffset+2];
+ switch (commandLetter)
+ {
+ case KApaCommandLetterOpen:
+ command=EApaCommandOpen;
+ break;
+ case KApaCommandLetterCreate:
+ command=EApaCommandCreate;
+ break;
+ case KApaCommandLetterViewActivate:
+ command=EApaCommandViewActivate;
+ break;
+ case KApaCommandLetterRunWithoutViews:
+ command=EApaCommandRunWithoutViews;
+ break;
+ case KApaCommandLetterBackgroundAndWithoutViews:
+ command=EApaCommandBackgroundAndWithoutViews;
+ break;
+ case KApaCommandLetterRun:
+ default:
+ break;
+ case KApaCommandLetterBackground:
+ command=EApaCommandBackground;
+ break;
+ }
+
+ if (offset>2)
+ {
+ const TInt documentNameStartPosition=endLibNameOffset+3;
+ documentName=StripQuotes(aCmdLine.Mid(documentNameStartPosition, (endDocNameOffset+1)-documentNameStartPosition)).Alloc();
+ if (documentName==NULL)
+ {
+ delete documentName;
+ delete executableName;
+ delete tailEnd;
+ delete opaqueData;
+ return KErrNoMemory;
+ }
+ }
+ }
+ const TInt KNumberOfSupportedOptions=6;
+ TFixedArray<SOption, KNumberOfSupportedOptions> optionArray;
+ optionArray[0].iToken=&KLitTokenServerDifferentiator;
+ optionArray[0].iResult=&serverDifferentiator;
+ optionArray[0].iRadix=EDecimal;
+ optionArray[1].iToken=&KLitTokenDefaultScreenNumber;
+ optionArray[1].iResult=&defaultScreenNumber;
+ optionArray[1].iRadix=EDecimal;
+ optionArray[2].iToken=&KLitTokenParentWindowGroupID;
+ optionArray[2].iResult=&parentWindowGroupID;
+ optionArray[2].iRadix=EDecimal;
+ optionArray[3].iToken=&KLitTokenDebugMemFail;
+ optionArray[3].iResult=&debugMemFail;
+ optionArray[3].iRadix=EHex;
+ optionArray[4].iToken=&KLitTokenAppStartupInstrumentationEventIdBase;
+ optionArray[4].iResult=&appStartupInstrumentationEventIdBase;
+ optionArray[4].iRadix=EDecimal;
+ optionArray[5].iToken=&KLitTokenOpaqueData;
+ optionArray[5].iResult=¬Used;
+ optionArray[5].iRadix=EDecimal; // should not used if the command-line is well-formed
+ TLex lex(aCmdLine.Mid(endDocNameOffset+1));
+ lex.Mark();
+ for (TInt optionIndex=0; optionIndex<KNumberOfSupportedOptions; ++optionIndex)
+ {
+ lex.SkipSpace();
+ SOption& option=optionArray[optionIndex];
+ const TPtrC remainder(lex.Remainder());
+ __ASSERT_DEBUG(option.iToken, Panic(EDPanicInvalidToken));
+ const TInt tokenLength=option.iToken->Length();
+ if ((remainder.Length()>=tokenLength) && (remainder.Left(tokenLength).CompareF(*option.iToken)==0))
+ {
+ if (option.iToken==&KLitTokenOpaqueData)
+ {
+ TInt endOfOpaqueDataIndex = 0;
+ for (TInt i=tokenLength; i<remainder.Length(); ++i)
+ {
+ TChar current=remainder[i];
+ if (current==' ')
+ {
+ endOfOpaqueDataIndex = i;
+ break; // parse no further
+ }
+ }
+ if(endOfOpaqueDataIndex > tokenLength)
+ {
+ const TInt opaqueDataLength = endOfOpaqueDataIndex - tokenLength;
+ delete opaqueData;
+ opaqueData=TPtrC8(reinterpret_cast<const TUint8*>(remainder.Mid(tokenLength, opaqueDataLength).Ptr()),opaqueDataLength*sizeof(TText)).Alloc();
+ if (opaqueData==NULL)
+ {
+ delete documentName;
+ delete executableName;
+ delete tailEnd;
+ return KErrNoMemory;
+ }
+ lex.Inc(tokenLength + opaqueDataLength);
+ lex.Mark();
+ }
+ else
+ {
+ delete opaqueData;
+ delete documentName;
+ delete executableName;
+ delete tailEnd;
+ // invalid command line. copy TLex.Val behavior
+ return KErrGeneral;
+ }
+ }
+ else
+ {
+ ASSERT(option.iResult);
+ const TInt originalValue=*option.iResult;
+ lex.Inc(tokenLength);
+ TUint16 val = static_cast<TUint16> (*option.iResult);
+ if (lex.Val(val, option.iRadix)==KErrNone)
+ {
+ lex.Mark();
+ }
+ else
+ {
+ *option.iResult=originalValue;
+ }
+ }
+ }
+ }
+ lex.UnGetToMark();
+ lex.SkipSpace();
+ const TPtrC remainder(lex.Remainder());
+ const TInt lengthOfRemainder=remainder.Length();
+ if (lengthOfRemainder>0)
+ {
+ tailEnd=TPtrC8(reinterpret_cast<const TUint8*>(remainder.Ptr()),lengthOfRemainder*sizeof(TText)).Alloc();
+ if (tailEnd==NULL)
+ {
+ delete documentName;
+ delete executableName;
+ delete tailEnd;
+ delete opaqueData;
+ return KErrNoMemory;
+ }
+ }
+
+ // we can now set the member variables as all memory-allocation has succeeded
+ delete iDocumentName;
+ iDocumentName=documentName;
+ delete iExecutableName;
+ iExecutableName=executableName;
+ delete iTailEnd;
+ iTailEnd=tailEnd;
+ iCommand=command;
+ iServerDifferentiator=serverDifferentiator;
+ iDefaultScreenNumber=defaultScreenNumber;
+ iParentWindowGroupID=parentWindowGroupID;
+ iDebugMemFail=debugMemFail;
+ iAppStartupInstrumentationEventIdBase=appStartupInstrumentationEventIdBase;
+ delete iOpaqueData;
+ iOpaqueData = opaqueData;
+ return KErrNone;
+ }
+
+TPtrC CApaCommandLine::StripQuotes(const TDesC& aDes) const
+ //
+ // return aDes stripped of any enclosing quotes
+ //
+ {
+ TInt start=0;
+ TInt end=aDes.Length()-1;
+ TPtrC ret;
+ if (end>=0)
+ {
+ if (aDes[0]=='"')
+ {
+ start++;
+ }
+ if (aDes[end]=='"')
+ {
+ end--;
+ }
+ TInt length=end-start+1;
+ if (length>0)
+ {
+ ret.Set(aDes.Mid(start, length));
+ }
+ }
+ return ret;
+ }