libraries/iosrv/server/readwrite.cpp
changeset 0 7f656887cf89
child 14 4ab8c027df23
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // readwrite.cpp
       
     2 // 
       
     3 // Copyright (c) 2006 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include "server.h"
       
    14 #include "pipe.h"
       
    15 #include "console.h"
       
    16 #include "readwrite.h"
       
    17 #include "session.h"
       
    18 #include "log.h"
       
    19 #include "persistentconsole.h"
       
    20 
       
    21 _LIT(KNewLine, "\r\n");
       
    22 _LIT(KLf, "\n");
       
    23 
       
    24 #ifdef IOSRV_LOGGING
       
    25 #define OBJ_NAME(x) TName objName((x).Name())
       
    26 #else
       
    27 #define OBJ_NAME(x)
       
    28 #endif
       
    29 
       
    30 #define __ASSERT_RETURN(x, y) {if (!(x)) {{y;};return;}}
       
    31 
       
    32 
       
    33 static void CleanupNullMessage(TAny* aMsgPtr)
       
    34 	{
       
    35 	*((RMsg*)aMsgPtr) = RMsg();
       
    36 	}
       
    37 	
       
    38 static void CleanupNullMessagePushL(RMsg& aMsg)
       
    39 	{
       
    40 	CleanupStack::PushL(TCleanupItem(CleanupNullMessage, &aMsg));
       
    41 	}
       
    42 	
       
    43 
       
    44 //
       
    45 // MIoEndPoint.
       
    46 //
       
    47 
       
    48 TBool MIoEndPoint::IoepIsConsole() const
       
    49 	{
       
    50 	return IoepIsType(RIoHandle::EConsole);
       
    51 	}
       
    52 
       
    53 
       
    54 //
       
    55 // MIoReadEndPoint.
       
    56 //
       
    57 
       
    58 void MIoReadEndPoint::IorepReadKeyL(MIoReader&)
       
    59 	{
       
    60 	User::Leave(KErrNotSupported);
       
    61 	}
       
    62 
       
    63 void MIoReadEndPoint::IorepSetConsoleModeL(RIoReadWriteHandle::TMode, MIoReader& aReader)
       
    64 	{
       
    65 	aReader.IorSetConsoleModeComplete(KErrNotSupported);
       
    66 	}
       
    67 
       
    68 TBool MIoReadEndPoint::AttachedToConsole(const MIoReadEndPoint* aEp)
       
    69 	{
       
    70 	if (!aEp) return EFalse;
       
    71 	if (aEp->IoepIsType(RIoHandle::EPersistentConsole))
       
    72 		{
       
    73 		CIoPersistentConsole* pcons = (CIoPersistentConsole*)aEp;
       
    74 		return AttachedToConsole(pcons->TransientReader());
       
    75 		}
       
    76 	else
       
    77 		{
       
    78 		return aEp->IoepIsConsole();
       
    79 		}
       
    80 	}
       
    81 
       
    82 
       
    83 //
       
    84 // MIoWriteEndPoint.
       
    85 //
       
    86 
       
    87 void MIoWriteEndPoint::IowepCursorPosL(MIoWriter& aWriter) const
       
    88 	{
       
    89 	TPoint pos = IowepCursorPos();
       
    90 	aWriter.IowCursorPos(KErrNone, pos);
       
    91 	}
       
    92 	
       
    93 void MIoWriteEndPoint::IowepSetCursorPosAbsL(const TPoint& aPoint, MIoWriter& aWriter)
       
    94 	{
       
    95 	IowepSetCursorPosAbs(aPoint);
       
    96 	aWriter.IowSetCursorPosAbsComplete(KErrNone);
       
    97 	}
       
    98 	
       
    99 void MIoWriteEndPoint::IowepSetCursorPosRelL(const TPoint& aPoint, MIoWriter& aWriter)
       
   100 	{
       
   101 	IowepSetCursorPosRel(aPoint);
       
   102 	aWriter.IowSetCursorPosRelComplete(KErrNone);
       
   103 	}
       
   104 	
       
   105 void MIoWriteEndPoint::IowepSetCursorHeightL(TInt aPercentage, MIoWriter& aWriter)
       
   106 	{
       
   107 	IowepSetCursorHeight(aPercentage);
       
   108 	aWriter.IowSetCursorHeightComplete(KErrNone);
       
   109 	}
       
   110 	
       
   111 void MIoWriteEndPoint::IowepSetTitleL(MIoWriter& aWriter)
       
   112 	{
       
   113 	HBufC* title = aWriter.IowTitleLC();
       
   114 	IowepSetTitle(*title);
       
   115 	CleanupStack::PopAndDestroy(title);
       
   116 	aWriter.IowSetTitleComplete(KErrNone);
       
   117 	}
       
   118 	
       
   119 void MIoWriteEndPoint::IowepClearScreenL(MIoWriter& aWriter)
       
   120 	{
       
   121 	IowepClearScreen();
       
   122 	aWriter.IowClearScreenComplete(KErrNone);
       
   123 	}
       
   124 	
       
   125 void MIoWriteEndPoint::IowepClearToEndOfLineL(MIoWriter& aWriter)
       
   126 	{
       
   127 	IowepClearToEndOfLine();
       
   128 	aWriter.IowClearToEndOfLineComplete(KErrNone);
       
   129 	}
       
   130 	
       
   131 void MIoWriteEndPoint::IowepScreenSizeL(MIoWriter& aWriter) const
       
   132 	{
       
   133 	TSize size = IowepScreenSize();
       
   134 	aWriter.IowScreenSize(KErrNone, size);
       
   135 	}
       
   136 
       
   137 void MIoWriteEndPoint::IowepSetAttributesL(TUint aAttributes, ConsoleAttributes::TColor aForegroundColor, ConsoleAttributes::TColor aBackgroundColor, MIoWriter& aWriter)
       
   138 	{
       
   139 	IowepSetAttributes(aAttributes, aForegroundColor, aBackgroundColor);
       
   140 	aWriter.IowSetAttributesComplete(KErrNone);
       
   141 	}
       
   142 
       
   143 TPoint MIoWriteEndPoint::IowepCursorPos() const
       
   144 	{
       
   145 	return TPoint(0, 0);
       
   146 	}
       
   147 
       
   148 void MIoWriteEndPoint::IowepSetCursorPosAbs(const TPoint&)
       
   149 	{
       
   150 	}
       
   151 
       
   152 void MIoWriteEndPoint::IowepSetCursorPosRel(const TPoint&)
       
   153 	{
       
   154 	}
       
   155 
       
   156 void MIoWriteEndPoint::IowepSetCursorHeight(TInt)
       
   157 	{
       
   158 	}
       
   159 
       
   160 void MIoWriteEndPoint::IowepSetTitle(const TDesC&)
       
   161 	{
       
   162 	}
       
   163 
       
   164 void MIoWriteEndPoint::IowepClearScreen()
       
   165 	{
       
   166 	}
       
   167 
       
   168 void MIoWriteEndPoint::IowepClearToEndOfLine()
       
   169 	{
       
   170 	}
       
   171 
       
   172 TSize MIoWriteEndPoint::IowepScreenSize() const
       
   173 	{
       
   174 	return TSize(0, 0);
       
   175 	}
       
   176 
       
   177 void MIoWriteEndPoint::IowepSetAttributes(TUint, ConsoleAttributes::TColor, ConsoleAttributes::TColor)
       
   178 	{
       
   179 	}
       
   180 
       
   181 TBool MIoWriteEndPoint::AttachedToConsole(const MIoWriteEndPoint* aEp)
       
   182 	{
       
   183 	if (!aEp) return EFalse;
       
   184 	if (aEp->IoepIsType(RIoHandle::EPersistentConsole))
       
   185 		{
       
   186 		CIoPersistentConsole* pcons = (CIoPersistentConsole*)aEp;
       
   187 		return AttachedToConsole(pcons->TransientWriter());
       
   188 		}
       
   189 	else
       
   190 		{
       
   191 		return aEp->IoepIsConsole();
       
   192 		}
       
   193 
       
   194 	}
       
   195 
       
   196 //
       
   197 // CIoReadWriteObject.
       
   198 //
       
   199 
       
   200 TUint CIoReadWriteObject::Id() const
       
   201 	{
       
   202 	return iId;
       
   203 	}
       
   204 
       
   205 CIoReadWriteObject::CIoReadWriteObject(TUint aId)
       
   206 	: iId(aId), iOwningThreadId(0)
       
   207 	{
       
   208 	}
       
   209 
       
   210 void CIoReadWriteObject::SetOwnerL(TThreadId aOwningThread)
       
   211 	{
       
   212 	iOwningThreadId = aOwningThread;
       
   213 	}
       
   214 
       
   215 TInt CIoReadWriteObject::Open(TThreadId aOwningThread)
       
   216 	{
       
   217 	TInt err = CObject::Open();
       
   218 	if ((err==KErrNone) && (IsOwner(aOwningThread)))
       
   219 		{
       
   220 		iOpenedByOwner = ETrue;
       
   221 		}
       
   222 	return err;
       
   223 	}
       
   224 	
       
   225 void CIoReadWriteObject::SetModeL(const RMsg& aMessage)
       
   226 	{
       
   227 	TInt mode(aMessage.Int0());
       
   228 	if ((mode >= RIoWriteHandle::EText) && (mode <= RIoWriteHandle::EBinary))
       
   229 		{
       
   230 		iMode = static_cast<RIoWriteHandle::TMode>(mode);
       
   231 		Complete(aMessage, KErrNone);
       
   232 		}
       
   233 	else
       
   234 		{
       
   235 		Complete(aMessage, KErrNotSupported);
       
   236 		}
       
   237 	}
       
   238 
       
   239 void CIoReadWriteObject::DoDuplicateL(const CIoReadWriteObject& aDuplicate)
       
   240 	{
       
   241 	iConsole = aDuplicate.iConsole;
       
   242 	}
       
   243 
       
   244 TBool CIoReadWriteObject::IsOwner(TThreadId aOwningThread) const
       
   245 	{
       
   246 	return iOwningThreadId == aOwningThread;
       
   247 	}
       
   248 
       
   249 TBool CIoReadWriteObject::OpenedByOwner() const
       
   250 	{
       
   251 	return iOpenedByOwner;
       
   252 	}
       
   253 
       
   254 void CIoReadWriteObject::SetConsole(CIoConsole& aConsole)
       
   255 	{
       
   256 	iConsole = &aConsole;
       
   257 	}
       
   258 
       
   259 CIoConsole* CIoReadWriteObject::Console()
       
   260 	{
       
   261 	return iConsole;
       
   262 	}
       
   263 
       
   264 MIoEndPoint* CIoReadWriteObject::EndPoint()
       
   265 	{
       
   266 	return iEndPoint;
       
   267 	}
       
   268 
       
   269 const CIoConsole* CIoReadWriteObject::Console() const
       
   270 	{
       
   271 	return iConsole;
       
   272 	}
       
   273 
       
   274 #ifndef IOSRV_LOGGING
       
   275 void CIoReadWriteObject::Dump(const TDesC&) const
       
   276 	{
       
   277 	}
       
   278 #else
       
   279 void CIoReadWriteObject::Dump(const TDesC& aData) const
       
   280 	{
       
   281 	TBuf<80> out;
       
   282 	TBuf<16> ascii;
       
   283 	TInt dataIndex = 0;
       
   284 	TInt pos = 0;
       
   285 	do
       
   286 		{
       
   287 		out.Zero();
       
   288 		ascii.Zero();
       
   289 		out.AppendNumFixedWidthUC(pos, EHex, 8);
       
   290 		out.Append(_L(": "));
       
   291 		for (TInt i = 0; i < 16; ++i)
       
   292 			{
       
   293 			if (dataIndex < aData.Length())
       
   294 				{
       
   295 				TUint8 byte = (TUint8)aData[dataIndex++];
       
   296 				out.AppendNumFixedWidthUC(byte, EHex, 2);
       
   297 				out.Append(_L(" "));
       
   298 				if ((byte < 0x20) || (byte >= 0x7f) || byte == '%')
       
   299 					{
       
   300 					byte = '.';
       
   301 					}
       
   302 				ascii.Append(TChar(byte));
       
   303 				++pos;
       
   304 				}
       
   305 			else
       
   306 				{
       
   307 				out.Append(_L("   "));
       
   308 				}
       
   309 			}
       
   310 		out.Append(ascii);
       
   311 		CIoLog::Printf(out);
       
   312 		}
       
   313 		while (dataIndex < aData.Length());
       
   314 	}
       
   315 #endif
       
   316 
       
   317 
       
   318 //
       
   319 // CIoReadObject.
       
   320 //
       
   321 
       
   322 CIoReadObject* CIoReadObject::NewLC(TInt aId)
       
   323 	{
       
   324 	CIoReadObject* self = new(ELeave) CIoReadObject(aId);
       
   325 	LOG(CIoLog::Printf(_L("Read object 0x%08x created"), self));
       
   326 	CleanupClosePushL(*self);
       
   327 	return self;
       
   328 	}
       
   329 
       
   330 CIoReadObject::~CIoReadObject()
       
   331 	{
       
   332 	OBJ_NAME(*this);
       
   333 	LOG(CIoLog::Printf(_L("Read object \"%S\" (0x%08x) destroying"), &objName, this));
       
   334 	if (iEndPoint)
       
   335 		{
       
   336 		ReadEndPoint()->IorepDetach(*this);
       
   337 		}
       
   338 
       
   339 	CompleteIfPending(iReadMessage, KErrSessionClosed);
       
   340 	CompleteIfPending(iReadKeyMessage, KErrSessionClosed);
       
   341 	CompleteIfPending(iChangeNotifyMessage, KErrSessionClosed);
       
   342 
       
   343 	delete iBuf;
       
   344 	delete iLineSeparator;
       
   345 	iCapturedKeys.Close();
       
   346 	iKeyBuffer.Close();
       
   347 	}
       
   348 
       
   349 void CIoReadObject::DuplicateL(const CIoReadObject& aDuplicate)
       
   350 	{
       
   351 	DoDuplicateL(aDuplicate);
       
   352 	if (aDuplicate.iEndPoint)
       
   353 		{
       
   354 		AttachL(*aDuplicate.ReadEndPoint(), RIoEndPoint::EBackground);
       
   355 		}
       
   356 	}
       
   357 
       
   358 void CIoReadObject::AttachL(MIoReadEndPoint& aEndPoint, RIoEndPoint::TReadMode aMode)
       
   359 	{
       
   360 	if (iEndPoint)
       
   361 		{
       
   362 		ReadEndPoint()->IorepDetach(*this);
       
   363 		}
       
   364 
       
   365 	aEndPoint.IorepAttachL(*this, aMode);
       
   366 	iEndPoint = &aEndPoint;
       
   367 	}
       
   368 
       
   369 void CIoReadObject::SetReadMode(RIoReadHandle::TReadMode aMode)
       
   370 	{
       
   371 	iReadMode = aMode;
       
   372 	}
       
   373 
       
   374 void CIoReadObject::SetToForegroundL()
       
   375 	{
       
   376 	if (iEndPoint)
       
   377 		{
       
   378 		ReadEndPoint()->IorepSetForegroundReaderL(*this);
       
   379 		}
       
   380 	}
       
   381 
       
   382 TBool CIoReadObject::IsForegroundL() const
       
   383 	{
       
   384 	if (iEndPoint)
       
   385 		{
       
   386 		return ReadEndPoint()->IorepIsForegroundL(*this);
       
   387 		}
       
   388 	return EFalse;
       
   389 	}
       
   390 
       
   391 void CIoReadObject::ReadL(const RMsg& aMessage)
       
   392 	{
       
   393 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicReadWhenNotAttached));
       
   394 	__ASSERT_RETURN(!MessagePending(iReadMessage) && !MessagePending(iReadKeyMessage), PanicClient(aMessage, EPanicReadAlreadyPending));
       
   395 
       
   396 	const TInt maxReadLength = MaxDesLengthL(aMessage, 0);
       
   397 	AllocateBufferL(maxReadLength);
       
   398 	iReadMessage = aMessage;
       
   399 	iMaxReadLength = maxReadLength;
       
   400 
       
   401 	if (iCompleteErr)
       
   402 		{
       
   403 		if ((iCompleteErr == KErrEof) && (iBuf->Length() > 0))
       
   404 			{
       
   405 			// the end point has reached the end of the stream
       
   406 			// but we haven't finished processing the data in our buffer yet
       
   407 			TryToCompleteRead();
       
   408 			}
       
   409 		else
       
   410 			{
       
   411 			iReadMessage.Complete(iCompleteErr);
       
   412 			}
       
   413 		}
       
   414 	else
       
   415 		{
       
   416 		ProcessRead();
       
   417 		}
       
   418 	}
       
   419 
       
   420 void CIoReadObject::ReadCancel(const CIoSession& aSession)
       
   421 	{
       
   422 	if (MessagePending(iReadMessage) && (iReadMessage.Session() == static_cast<const CSession2*>(&aSession)))
       
   423 		{
       
   424 		Complete(iReadMessage, KErrCancel);
       
   425 		iBuf->Des().Zero();
       
   426 		}
       
   427 	}
       
   428 
       
   429 void CIoReadObject::ProcessRead()
       
   430 	{
       
   431 	ASSERT((MessagePending(iReadMessage) || MessagePending(iReadKeyMessage)) && !(MessagePending(iReadMessage) && MessagePending(iReadKeyMessage)));
       
   432 
       
   433 	if (MessagePending(iReadMessage))
       
   434 		{
       
   435 		if (iCompleteErr)
       
   436 			{
       
   437 			iReadMessage.Complete(iCompleteErr);
       
   438 			}
       
   439 		else
       
   440 			{
       
   441 			TryToCompleteRead();
       
   442 
       
   443 			if (IorReadPending())
       
   444 				{
       
   445 				TRAPD(err, ReadEndPoint()->IorepReadL(*this));
       
   446 				if (err)
       
   447 					{
       
   448 					Complete(iReadMessage, err);
       
   449 					}
       
   450 				else if (IorReadPending())
       
   451 					{
       
   452 					TryToCompleteRead();
       
   453 					}
       
   454 				}
       
   455 			}
       
   456 		}
       
   457 	else
       
   458 		{
       
   459 		if (iCompleteErr)
       
   460 			{
       
   461 			iReadKeyMessage.Complete(iCompleteErr);
       
   462 			}
       
   463 		else
       
   464 			{
       
   465 			if (iKeyBuffer.Count() > 0)
       
   466 				{
       
   467 				CompleteReadKey(KErrNone, iKeyBuffer[0]);
       
   468 				iKeyBuffer.Remove(0);
       
   469 				}
       
   470 			else
       
   471 				{
       
   472 				TRAPD(err, ReadEndPoint()->IorepReadKeyL(*this));
       
   473 				if (err)
       
   474 					{
       
   475 					Complete(iReadKeyMessage, err);
       
   476 					}
       
   477 				}
       
   478 			}
       
   479 		}
       
   480 	}
       
   481 
       
   482 void CIoReadObject::SetLineSeparatorL(const RMsg& aMessage)
       
   483 	{
       
   484 	HBufC* separator = HBufC::NewLC(DesLengthL(aMessage, 0));
       
   485 	TPtr ptr(separator->Des());
       
   486 	MessageReadL(aMessage, 0, ptr);
       
   487 	delete iLineSeparator;
       
   488 	iLineSeparator = separator;
       
   489 	CleanupStack::Pop(separator);
       
   490 	Complete(aMessage, KErrNone);
       
   491 	}
       
   492 
       
   493 void CIoReadObject::ReadKeyL(const RMsg& aMessage)
       
   494 	{
       
   495 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicReadKeyWhenNotAttached));
       
   496 	__ASSERT_RETURN(!MessagePending(iReadMessage) && !MessagePending(iReadKeyMessage), PanicClient(aMessage, EPanicReadAlreadyPending));
       
   497 
       
   498 	iReadKeyMessage = aMessage;
       
   499 
       
   500 	if (iCompleteErr)
       
   501 		{
       
   502 		iReadKeyMessage.Complete(iCompleteErr);
       
   503 		}
       
   504 	else
       
   505 		{
       
   506 		ProcessRead();
       
   507 		}
       
   508 	}
       
   509 
       
   510 void CIoReadObject::ReadKeyCancel(const CIoSession& aSession)
       
   511 	{
       
   512 	if (MessagePending(iReadKeyMessage) && (iReadKeyMessage.Session() == &aSession))
       
   513 		{
       
   514 		Complete(iReadKeyMessage, KErrCancel);
       
   515 		}
       
   516 	}
       
   517 
       
   518 void CIoReadObject::CaptureKeyL(const RMsg& aMessage)
       
   519 	{
       
   520 	User::LeaveIfError(iCapturedKeys.Append(TCapturedKey(aMessage.Int0(), aMessage.Int1(), aMessage.Int2())));
       
   521 	Complete(aMessage, KErrNone);
       
   522 	}
       
   523 
       
   524 void CIoReadObject::CancelCaptureKey(const RMsg& aMessage)
       
   525 	{
       
   526 	TCapturedKey capturedKey(aMessage.Int0(), aMessage.Int1(), aMessage.Int2());
       
   527 	const TInt numCapturedKeys = iCapturedKeys.Count();
       
   528 	for (TInt i = 0; i < numCapturedKeys; ++i)
       
   529 		{
       
   530 		const TCapturedKey& thisCapturedKey = iCapturedKeys[i];
       
   531 		if ((capturedKey.iKeyCode == thisCapturedKey.iKeyCode) && (capturedKey.iModifiers == thisCapturedKey.iModifiers) && (capturedKey.iModifierMask == thisCapturedKey.iModifierMask))
       
   532 			{
       
   533 			iCapturedKeys.Remove(i);
       
   534 			Complete(aMessage, KErrNone);
       
   535 			return;
       
   536 			}
       
   537 		}
       
   538 
       
   539 	Complete(aMessage, KErrNotFound);
       
   540 	}
       
   541 
       
   542 void CIoReadObject::CaptureAllKeys(const RMsg& aMessage)
       
   543 	{
       
   544 	iCaptureAllKeys = ETrue;
       
   545 	Complete(aMessage, KErrNone);
       
   546 	}
       
   547 
       
   548 void CIoReadObject::CancelCaptureAllKeys(const RMsg& aMessage)
       
   549 	{
       
   550 	iCaptureAllKeys = EFalse;
       
   551 	Complete(aMessage, KErrNone);
       
   552 	}
       
   553 	
       
   554 void CIoReadObject::NotifyChange(const RMsg& aMessage)
       
   555 	{
       
   556 	if (MessagePending(iChangeNotifyMessage))
       
   557 		{
       
   558 		Complete(aMessage, KErrAlreadyExists);
       
   559 		}
       
   560 	else
       
   561 		{
       
   562 		iChangeNotifyMessage = aMessage;
       
   563 		}
       
   564 	}
       
   565 	
       
   566 void CIoReadObject::CancelNotifyChange(const CIoSession& aSession)
       
   567 	{
       
   568 	if (MessagePending(iChangeNotifyMessage) && (iChangeNotifyMessage.Session() == static_cast<const CSession2*>(&aSession)))
       
   569 		{
       
   570 		Complete(iChangeNotifyMessage, KErrCancel);
       
   571 		}
       
   572 	}
       
   573 
       
   574 void CIoReadObject::CancelSetMode(const CIoSession& aSession)
       
   575 	{
       
   576 	if (MessagePending(iSetModeMessage) && (iSetModeMessage.Session() == static_cast<const CSession2*>(&aSession)))
       
   577 		{
       
   578 		Complete(iSetModeMessage, KErrCancel);
       
   579 		}
       
   580 	}
       
   581 
       
   582 TBool CIoReadObject::IsType(RIoHandle::TType aType) const
       
   583 	{
       
   584 	return ((aType == RIoHandle::EReadWriteObject) || (aType == RIoHandle::EReadObject));
       
   585 	}
       
   586 
       
   587 void CIoReadObject::SessionClosed(const CIoSession& aSession)
       
   588 	{
       
   589 	ReadCancel(aSession);
       
   590 	ReadKeyCancel(aSession);
       
   591 	CancelNotifyChange(aSession);
       
   592 	CancelSetMode(aSession);
       
   593 	}
       
   594 
       
   595 void CIoReadObject::SetModeL(const RMsg& aMessage)
       
   596 	{
       
   597 	TInt mode(aMessage.Int0());
       
   598 	if ((mode >= RIoWriteHandle::EText) && (mode <= RIoWriteHandle::EBinary))
       
   599 		{
       
   600 		if (ReadEndPoint() && ReadEndPoint()->IorepIsForegroundL(*this))
       
   601 			{
       
   602 			__ASSERT_RETURN(!MessagePending(iSetModeMessage), PanicClient(aMessage, EPanicSetModeAlreadyPending));
       
   603 			ReadEndPoint()->IorepSetConsoleModeL((RIoReadWriteHandle::TMode)mode, *this);
       
   604 			iSetModeMessage = aMessage;
       
   605 			}
       
   606 		else
       
   607 			{
       
   608 			Complete(aMessage, KErrNone);
       
   609 			}
       
   610 
       
   611 		iMode = static_cast<RIoWriteHandle::TMode>(mode);
       
   612 		}
       
   613 	else
       
   614 		{
       
   615 		Complete(aMessage, KErrNotSupported);
       
   616 		}
       
   617 	}
       
   618 
       
   619 RIoReadWriteHandle::TMode CIoReadObject::IorwMode() const
       
   620 	{
       
   621 	return iMode;
       
   622 	}
       
   623 
       
   624 TBool CIoReadObject::IorReadPending() const
       
   625 	{
       
   626 	return (MessagePending(iReadMessage));
       
   627 	}
       
   628 
       
   629 TBool CIoReadObject::IorReadKeyPending() const
       
   630 	{
       
   631 	return (MessagePending(iReadKeyMessage));
       
   632 	}
       
   633 
       
   634 TDes& CIoReadObject::IorReadBuf()
       
   635 	{
       
   636 	ASSERT((iMaxReadLength - iBuf->Length()) > 0);
       
   637 	iPtr.Set(const_cast<TText*>(iBuf->Des().Ptr()) + iBuf->Length(), 0, iMaxReadLength - iBuf->Length());
       
   638 	return iPtr;
       
   639 	}
       
   640 
       
   641 void CIoReadObject::IorDataBuffered(TInt aLength)
       
   642 	{
       
   643 	iBuf->Des().SetLength(iBuf->Length() + aLength);
       
   644 	TryToCompleteRead();
       
   645 	}
       
   646 
       
   647 TBool CIoReadObject::IorDataIsBuffered() const
       
   648 	{
       
   649 	return (iBuf->Length() > 0);
       
   650 	}
       
   651 
       
   652 TBool CIoReadObject::IorIsKeyCaptured(TUint aKeyCode, TUint aModifiers)
       
   653 	{
       
   654 	if (iCaptureAllKeys)
       
   655 		{
       
   656 		return ETrue;
       
   657 		}
       
   658 	const TInt numCapturedKeys = iCapturedKeys.Count();
       
   659 	for (TInt i = 0; i < numCapturedKeys; ++i)
       
   660 		{
       
   661 		const TCapturedKey& thisCapturedKey = iCapturedKeys[i];
       
   662 		if ((aKeyCode == thisCapturedKey.iKeyCode) && ((aModifiers & thisCapturedKey.iModifierMask) == thisCapturedKey.iModifiers))
       
   663 			{
       
   664 			return ETrue;
       
   665 			}
       
   666 		}
       
   667 	return EFalse;
       
   668 	}
       
   669 
       
   670 void CIoReadObject::IorReadComplete(TInt aError)
       
   671 	{
       
   672 	if ((aError == KErrNone) || (aError==KErrEof))
       
   673 		{
       
   674 		CompleteRead(aError, iBuf->Length());
       
   675 		}
       
   676 	else
       
   677 		{
       
   678 		CompleteRead(aError, 0);
       
   679 		}
       
   680 	}
       
   681 
       
   682 void CIoReadObject::IorReadKeyComplete(TInt aError, TUint aKeyCode, TUint aModifiers)
       
   683 	{
       
   684 	RIoConsoleReadHandle::TConsoleKey consoleKey;
       
   685 	consoleKey.iKeyCode = aKeyCode;
       
   686 	consoleKey.iModifiers = aModifiers;
       
   687 	if (IorReadKeyPending())
       
   688 		{
       
   689 		CompleteReadKey(aError, consoleKey);
       
   690 		}
       
   691 	else
       
   692 		{
       
   693 		if (aError)
       
   694 			{
       
   695 			LOG(CIoLog::Printf(_L("Error in IorReadKeyComplete %d"), aError));
       
   696 			if (IorReadPending()) CompleteRead(aError, 0);
       
   697 			// What state are we in if neither IorReadKeyPending or IorReadPending are true? Should we be setting iCompleteErr?
       
   698 			}
       
   699 		else
       
   700 			{
       
   701 			iKeyBuffer.Append(consoleKey);
       
   702 			if (IorReadPending())
       
   703 				{
       
   704 				TryToCompleteRead();
       
   705 				}
       
   706 			}
       
   707 		}
       
   708 	}
       
   709 
       
   710 TName CIoReadObject::IorName()
       
   711 	{
       
   712 	return Name();
       
   713 	}
       
   714 	
       
   715 void CIoReadObject::IorReaderChange(TUint aChange)
       
   716 	{
       
   717 	if ((aChange == RIoReadHandle::EGainedForeground) && iEndPoint && ReadEndPoint()->IoepIsType(RIoHandle::EConsole))
       
   718 		{
       
   719 		ReadEndPoint()->IorepSetConsoleModeL(iMode, *this);
       
   720 		}
       
   721 
       
   722 	if (MessagePending(iChangeNotifyMessage))
       
   723 		{
       
   724 		TRAPD(err, MessageWriteL(iChangeNotifyMessage, 0, TPckg<TUint>(aChange)));
       
   725 		Complete(iChangeNotifyMessage, err);
       
   726 		}
       
   727 	}
       
   728 
       
   729 void CIoReadObject::IorSetConsoleModeComplete(TInt aError)
       
   730 	{
       
   731 	if (MessagePending(iSetModeMessage))
       
   732 		{
       
   733 		// The set mode request was explicitly requested, so complete it.
       
   734 		Complete(iSetModeMessage, aError);
       
   735 		}
       
   736 	else
       
   737 		{
       
   738 		// The set mode request was made because the read object has come to the foreground. If there was an error,
       
   739 		// report it via the next read request. However, only report errors when setting to binary mode. This is because
       
   740 		// every console must implicitly support text mode, but they may not support the extension interface and report
       
   741 		// KErrExtensionNotSupported even for text mode.
       
   742 
       
   743 		if (aError && (iMode == RIoReadWriteHandle::EBinary))
       
   744 			{
       
   745 			iCompleteErr = aError;
       
   746 			}
       
   747 		}
       
   748 	}
       
   749 
       
   750 CIoReadObject::CIoReadObject(TInt aId)
       
   751 	: CIoReadWriteObject(aId), iPtr(NULL, 0, 0)
       
   752 	{
       
   753 	}
       
   754 
       
   755 void CIoReadObject::AllocateBufferL(TInt aLength)
       
   756 	{
       
   757 	if (iBuf == NULL)
       
   758 		{
       
   759 		iBuf = HBufC::NewL(aLength);
       
   760 		}
       
   761 	else if (iBuf->Des().MaxLength() < aLength)
       
   762 		{
       
   763 		iBuf = iBuf->ReAllocL(aLength);
       
   764 		}
       
   765 	}
       
   766 
       
   767 void CIoReadObject::TryToCompleteRead()
       
   768 	{
       
   769 	if (iKeyBuffer.Count() > 0)
       
   770 		{
       
   771 		// There are buffered key events so copy them into the read buffer.
       
   772 		TDes& readBuf = IorReadBuf();
       
   773 		while (iKeyBuffer.Count())
       
   774 			{
       
   775 			const RIoConsoleReadHandle::TConsoleKey& consoleKey = iKeyBuffer[0];
       
   776 			if ((IorwMode() == RIoReadWriteHandle::EText) && (consoleKey.iKeyCode == EKeyEnter))
       
   777 				{
       
   778 				if ((readBuf.Length() + KNewLine().Length()) <= readBuf.MaxLength())
       
   779 					{
       
   780 					// If there's enough room, expand EKeyEnter into "\r\n" (otherwise RIoReadHandle::ELine reads won't complete).
       
   781 					readBuf.Append(KNewLine);
       
   782 					}
       
   783 				else if (readBuf.Length() < readBuf.MaxLength())
       
   784 					{
       
   785 					// Otherwise, just put in the raw code code in the read buffer like normal - the client might be reading into a TBuf<1> (fshell does this for example), in which case there will never be enough room for "\r\n".
       
   786 					TPtrC keyCodePtr((TUint16*)&consoleKey.iKeyCode, 1);
       
   787 					readBuf.Append(keyCodePtr);
       
   788 					}
       
   789 				else
       
   790 					{
       
   791 					break;
       
   792 					}
       
   793 				}
       
   794 			else
       
   795 				{
       
   796 				if (readBuf.Length() < readBuf.MaxLength())
       
   797 					{
       
   798 					TPtrC keyCodePtr((TUint16*)&consoleKey.iKeyCode, 1);
       
   799 					readBuf.Append(keyCodePtr);
       
   800 					}
       
   801 				else
       
   802 					{
       
   803 					break;
       
   804 					}
       
   805 				}
       
   806 			iKeyBuffer.Remove(0);
       
   807 			}
       
   808 		iBuf->Des().SetLength(iBuf->Length() + readBuf.Length());
       
   809 		}
       
   810 
       
   811 	switch (iReadMode)
       
   812 		{
       
   813 		case RIoReadHandle::EFull:
       
   814 			{
       
   815 			if (iBuf->Length() == iMaxReadLength)
       
   816 				{
       
   817 				CompleteRead(KErrNone, iMaxReadLength);
       
   818 				}
       
   819 			break;
       
   820 			}
       
   821 		case RIoReadHandle::ELine:
       
   822 			{
       
   823 			const TDesC* lineSeparator = iLineSeparator;
       
   824 			if (lineSeparator == NULL) lineSeparator = &KLf;
       
   825 
       
   826 			TInt pos = iBuf->Find(*lineSeparator);
       
   827 			if (pos >= 0)
       
   828 				{
       
   829 				CompleteRead(KErrNone, pos + lineSeparator->Length());
       
   830 				}
       
   831 			else if (iBuf->Length() == iMaxReadLength)
       
   832 				{
       
   833 				CompleteRead(KErrNone, iMaxReadLength);
       
   834 				}
       
   835 			else if ((iBuf->Length() > 0) && (iCompleteErr == KErrEof))
       
   836 				{
       
   837 				// the read end point has reached the end of the stream
       
   838 				// there is still some data remaining, but no new line
       
   839 				// to just send the last bit
       
   840 				CompleteRead(KErrNone, iBuf->Length());
       
   841 				}
       
   842 			break;
       
   843 			}
       
   844 		case RIoReadHandle::EOneOrMore:
       
   845 			{
       
   846 			if (iBuf->Length() > 0)
       
   847 				{
       
   848 				CompleteRead(KErrNone, iBuf->Length());
       
   849 				}
       
   850 			break;
       
   851 			}
       
   852 		}
       
   853 	}
       
   854 
       
   855 void CIoReadObject::CompleteRead(TInt aError, TInt aLength)
       
   856 	{
       
   857 	if (IorReadPending())
       
   858 		{
       
   859 		OBJ_NAME(*this);
       
   860 
       
   861 		if ((aError == KErrNone)||(aError == KErrEof))
       
   862 			{
       
   863 			LOG(CIoLog::Printf(_L("Read object \'%S\' writing %d characters"), &objName, aLength));
       
   864 			TPtrC ptr(iBuf->Des().Ptr(), aLength);
       
   865 			LOG(Dump(ptr));
       
   866 			TRAPD(err, MessageWriteL(iReadMessage, 0, ptr));
       
   867 			if (err == KErrNone)
       
   868 				{
       
   869 				iBuf->Des().Delete(0, aLength);
       
   870 				}
       
   871 			else
       
   872 				{
       
   873 				aError = err;
       
   874 				}
       
   875 			}
       
   876 		
       
   877 		LOG(CIoLog::Printf(_L("Read object \'%S\' completing read message with %d"), &objName, aError));
       
   878 		Complete(iReadMessage, aError);
       
   879 		}
       
   880 	else if (aError)
       
   881 		{
       
   882 		iCompleteErr = aError;
       
   883 		}
       
   884 	}
       
   885 
       
   886 void CIoReadObject::CompleteReadKey(TInt aError, RIoConsoleReadHandle::TConsoleKey& aConsoleKey)
       
   887 	{
       
   888 	if (aError == KErrNone)
       
   889 		{
       
   890 		TPckgC<RIoConsoleReadHandle::TConsoleKey> consoleKeyPckg(aConsoleKey);
       
   891 		TRAP(aError, MessageWriteL(iReadKeyMessage, 0, consoleKeyPckg));
       
   892 		}
       
   893 	Complete(iReadKeyMessage, aError);
       
   894 	}
       
   895 
       
   896 MIoReadEndPoint* CIoReadObject::ReadEndPoint() const
       
   897 	{
       
   898 	return static_cast<MIoReadEndPoint*>(iEndPoint);
       
   899 	}
       
   900 
       
   901 CIoReadObject::TCapturedKey::TCapturedKey(TUint aKeyCode, TUint aModifierMask, TUint aModifiers)
       
   902 	: iKeyCode(aKeyCode), iModifierMask(aModifierMask), iModifiers(aModifiers)
       
   903 	{
       
   904 	}
       
   905 
       
   906 
       
   907 //
       
   908 // CIoWriteObject.
       
   909 //
       
   910 
       
   911 CIoWriteObject* CIoWriteObject::NewLC(TInt aId)
       
   912 	{
       
   913 	CIoWriteObject* self = new(ELeave) CIoWriteObject(aId);
       
   914 	LOG(CIoLog::Printf(_L("Write object 0x%08x created"), self));
       
   915 	CleanupClosePushL(*self);
       
   916 	return self;
       
   917 	}
       
   918 
       
   919 CIoWriteObject::~CIoWriteObject()
       
   920 	{
       
   921 	OBJ_NAME(*this);
       
   922 	LOG(CIoLog::Printf(_L("Write object \"%S\" (0x%08x) destroying"), &objName, this));
       
   923 	if (iEndPoint)
       
   924 		{
       
   925 		WriteEndPoint()->IowepDetach(*this);
       
   926 		}
       
   927 
       
   928 	CompleteIfPending(iWriteMessage, KErrSessionClosed);
       
   929 	CompleteIfPending(iGetCursorPosMsg, KErrSessionClosed);
       
   930 	CompleteIfPending(iSetCursorPosAbsMsg, KErrSessionClosed);
       
   931 	CompleteIfPending(iSetCursorPosRelMsg, KErrSessionClosed);
       
   932 	CompleteIfPending(iSetCursorHeightMsg, KErrSessionClosed);
       
   933 	CompleteIfPending(iSetTitleMsg, KErrSessionClosed);
       
   934 	CompleteIfPending(iClearScreenMsg, KErrSessionClosed);
       
   935 	CompleteIfPending(iClearToEndOfLineMsg, KErrSessionClosed);
       
   936 	CompleteIfPending(iGetScreenSizeMsg, KErrSessionClosed);
       
   937 	CompleteIfPending(iSetAttributesMsg, KErrSessionClosed);
       
   938 	}
       
   939 
       
   940 void CIoWriteObject::DuplicateL(const CIoWriteObject& aDuplicate)
       
   941 	{
       
   942 	DoDuplicateL(aDuplicate);
       
   943 	if (aDuplicate.iEndPoint)
       
   944 		{
       
   945 		AttachL(*aDuplicate.WriteEndPoint());
       
   946 		}
       
   947 	iIsStdErr = aDuplicate.iIsStdErr;
       
   948 	}
       
   949 
       
   950 void CIoWriteObject::AttachL(MIoWriteEndPoint& aEndPoint)
       
   951 	{
       
   952 	if (iEndPoint)
       
   953 		{
       
   954 		WriteEndPoint()->IowepDetach(*this);
       
   955 		}
       
   956 
       
   957 	aEndPoint.IowepAttachL(*this);
       
   958 	iEndPoint = &aEndPoint;
       
   959 	}
       
   960 
       
   961 void CIoWriteObject::WriteL(const RMsg& aMessage)
       
   962 	{
       
   963 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicWriteWhenNotAttached));
       
   964 	__ASSERT_RETURN(!MessagePending(iWriteMessage), PanicClient(aMessage, EPanicWriteAlreadyPending));
       
   965 	iWriteMessage = aMessage;
       
   966 	iOffset = 0;
       
   967 	iWriteLength = DesLengthL(iWriteMessage, 0);
       
   968 	WriteEndPoint()->IowepWriteL(*this);
       
   969 	}
       
   970 
       
   971 void CIoWriteObject::WriteCancel(const CIoSession& aSession)
       
   972 	{
       
   973 	if (MessagePending(iWriteMessage) && (iWriteMessage.Session() == &aSession))
       
   974 		{
       
   975 		if (iEndPoint)
       
   976 			{
       
   977 			WriteEndPoint()->IowepWriteCancel(*this);
       
   978 			}
       
   979 		Complete(iWriteMessage, KErrCancel);
       
   980 		}
       
   981 	}
       
   982 
       
   983 TInt CIoWriteObject::IowWriteLength() const
       
   984 	{
       
   985 	ASSERT(MessagePending(iWriteMessage));
       
   986 	return (iWriteLength - iOffset);
       
   987 	}
       
   988 
       
   989 TInt CIoWriteObject::IowWrite(TDes& aBuf)
       
   990 	{
       
   991 	ASSERT(MessagePending(iWriteMessage));
       
   992 	ASSERT(aBuf.Length() <= (iWriteLength - iOffset));
       
   993 	OBJ_NAME(*this);
       
   994 	TRAPD(err, MessageReadL(iWriteMessage, 0, aBuf, iOffset));
       
   995 	if (err == KErrNone)
       
   996 		{
       
   997 		LOG(CIoLog::Printf(_L("Write object \'%S\' read %d characters"), &objName, aBuf.Length()));
       
   998 		LOG(Dump(aBuf));
       
   999 		iOffset += aBuf.Length();
       
  1000 		}
       
  1001 	else
       
  1002 		{
       
  1003 		LOG(CIoLog::Printf(_L("Write object \'%S\' failed to read: %d"), &objName, err));
       
  1004 		}
       
  1005 	return err;
       
  1006 	}
       
  1007 
       
  1008 RIoReadWriteHandle::TMode CIoWriteObject::IowWriteMode() const
       
  1009 	{
       
  1010 	return iMode;
       
  1011 	}
       
  1012 	
       
  1013 void CIoWriteObject::IowCursorPos(TInt aError, TPoint aPos)
       
  1014 	{
       
  1015 	TPckgC<TPoint> posPckg(aPos);
       
  1016 	Complete(iGetCursorPosMsg, aError==KErrNone ? MessageWrite(iGetCursorPosMsg, 0, posPckg) : aError);
       
  1017 	}
       
  1018 
       
  1019 void CIoWriteObject::IowSetCursorPosAbsComplete(TInt aError)
       
  1020 	{
       
  1021 	Complete(iSetCursorPosAbsMsg, aError);
       
  1022 	}
       
  1023 
       
  1024 void CIoWriteObject::IowSetCursorPosRelComplete(TInt aError)
       
  1025 	{
       
  1026 	Complete(iSetCursorPosRelMsg, aError);
       
  1027 	}
       
  1028 	
       
  1029 void CIoWriteObject::IowSetCursorHeightComplete(TInt aError)
       
  1030 	{
       
  1031 	Complete(iSetCursorHeightMsg, aError);
       
  1032 	}
       
  1033 	
       
  1034 void CIoWriteObject::IowSetTitleComplete(TInt aError)
       
  1035 	{
       
  1036 	Complete(iSetTitleMsg, aError);
       
  1037 	}
       
  1038 	
       
  1039 void CIoWriteObject::IowClearScreenComplete(TInt aError)
       
  1040 	{
       
  1041 	Complete(iClearScreenMsg, aError);
       
  1042 	}
       
  1043 
       
  1044 void CIoWriteObject::IowClearToEndOfLineComplete(TInt aError)
       
  1045 	{
       
  1046 	Complete(iClearToEndOfLineMsg, aError);
       
  1047 	}
       
  1048 
       
  1049 void CIoWriteObject::IowScreenSize(TInt aError, TSize aSize)
       
  1050 	{
       
  1051 	if ((aSize == TSize(0, 0)) && Console() && !iTriedConsoleScreenSize)
       
  1052 		{
       
  1053 		iTriedConsoleScreenSize = ETrue;
       
  1054 		TRAPD(err, Console()->IowepScreenSizeL(*this));
       
  1055 		if (err!=KErrNone)
       
  1056 			{
       
  1057 			Complete(iGetScreenSizeMsg, err);
       
  1058 			}
       
  1059 		return;
       
  1060 		}
       
  1061 	TPckgC<TSize> sizePckg(aSize);
       
  1062 	Complete(iGetScreenSizeMsg, aError == KErrNone ? MessageWrite(iGetScreenSizeMsg, 0, sizePckg) : aError);
       
  1063 	}
       
  1064 
       
  1065 void CIoWriteObject::IowSetAttributesComplete(TInt aError)
       
  1066 	{
       
  1067 	Complete(iSetAttributesMsg, aError);
       
  1068 	}
       
  1069 
       
  1070 HBufC* CIoWriteObject::IowTitleLC()
       
  1071 	{
       
  1072 	HBufC* titleBuf = HBufC::NewLC(DesLengthL(iSetTitleMsg, 0));
       
  1073 	TPtr titlePtr(titleBuf->Des());
       
  1074 	MessageReadL(iSetTitleMsg, 0, titlePtr);
       
  1075 	return titleBuf;
       
  1076 	}
       
  1077 
       
  1078 void CIoWriteObject::CursorPosL(const RMsg& aMessage)
       
  1079 	{
       
  1080 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicCursorPosWhenNotAttached));
       
  1081 	__ASSERT_RETURN(iGetCursorPosMsg.IsNull(), PanicClient(aMessage, EPanicCursorPosAlreadyPending));
       
  1082 	iGetCursorPosMsg = aMessage;
       
  1083 	CleanupNullMessagePushL(iGetCursorPosMsg);
       
  1084 	WriteEndPoint()->IowepCursorPosL(*this);
       
  1085 	CleanupStack::Pop(&iGetCursorPosMsg);
       
  1086 	}
       
  1087 
       
  1088 void CIoWriteObject::SetCursorPosAbsL(const RMsg& aMessage)
       
  1089 	{
       
  1090 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicSetCursorPosAbsWhenNotAttached));
       
  1091 	__ASSERT_RETURN(iSetCursorPosAbsMsg.IsNull(), PanicClient(aMessage, EPanicSetCursorPosAlreadyPending));
       
  1092 	TPoint pos;
       
  1093 	TPckg<TPoint> posPckg(pos);
       
  1094 	MessageReadL(aMessage, 0, posPckg);
       
  1095 	iSetCursorPosAbsMsg = aMessage;
       
  1096 	CleanupNullMessagePushL(iSetCursorPosAbsMsg);
       
  1097 	WriteEndPoint()->IowepSetCursorPosAbsL(pos, *this);
       
  1098 	CleanupStack::Pop(&iSetCursorPosAbsMsg);
       
  1099 	}
       
  1100 
       
  1101 void CIoWriteObject::SetCursorPosRelL(const RMsg& aMessage)
       
  1102 	{
       
  1103 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicSetCursorPosRelWhenNotAttached));
       
  1104 	__ASSERT_RETURN(iSetCursorPosRelMsg.IsNull(), PanicClient(aMessage, EPanicSetCursorPosAlreadyPending));
       
  1105 	TPoint pos;
       
  1106 	TPckg<TPoint> posPckg(pos);
       
  1107 	MessageReadL(aMessage, 0, posPckg);
       
  1108 	iSetCursorPosRelMsg = aMessage;
       
  1109 	CleanupNullMessagePushL(iSetCursorPosRelMsg);
       
  1110 	WriteEndPoint()->IowepSetCursorPosRelL(pos, *this);
       
  1111 	CleanupStack::Pop(&iSetCursorPosRelMsg);
       
  1112 	}
       
  1113 
       
  1114 void CIoWriteObject::SetCursorHeightL(const RMsg& aMessage)
       
  1115 	{
       
  1116 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicSetCursorHeightWhenNotAttached));
       
  1117 	__ASSERT_RETURN(iSetCursorHeightMsg.IsNull(), PanicClient(aMessage, EPanicSetCursorHeightAlreadyPending));
       
  1118 	iSetCursorHeightMsg = aMessage;
       
  1119 	CleanupNullMessagePushL(iSetCursorHeightMsg);
       
  1120 	WriteEndPoint()->IowepSetCursorHeightL(aMessage.Int0(), *this);
       
  1121 	CleanupStack::Pop(&iSetCursorHeightMsg);
       
  1122 	}
       
  1123 
       
  1124 void CIoWriteObject::SetTitleL(const RMsg& aMessage)
       
  1125 	{
       
  1126 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicSetTitleWhenNotAttached));
       
  1127 	__ASSERT_RETURN(iSetTitleMsg.IsNull(), PanicClient(aMessage, EPanicSetTitleAlreadyPending));
       
  1128 	iSetTitleMsg = aMessage;
       
  1129 	// if we leave here, the message will be completed by the framework. But we do want to null the message
       
  1130 	// as it will no longer be valid.
       
  1131 	CleanupNullMessagePushL(iSetTitleMsg);
       
  1132 	WriteEndPoint()->IowepSetTitleL(*this);
       
  1133 	CleanupStack::Pop(&iSetTitleMsg);
       
  1134 	}
       
  1135 
       
  1136 void CIoWriteObject::ClearScreen(const RMsg& aMessage)
       
  1137 	{
       
  1138 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicClearScreenWhenNotAttached));
       
  1139 	__ASSERT_RETURN(iClearScreenMsg.IsNull(), PanicClient(aMessage, EPanicClearScreenAlreadyPending));
       
  1140 	iClearScreenMsg = aMessage;
       
  1141 	CleanupNullMessagePushL(iClearScreenMsg);
       
  1142 	WriteEndPoint()->IowepClearScreenL(*this);
       
  1143 	CleanupStack::Pop(&iClearScreenMsg);
       
  1144 	}
       
  1145 
       
  1146 void CIoWriteObject::ClearToEndOfLine(const RMsg& aMessage)
       
  1147 	{
       
  1148 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicClearToEndOfLineWhenNotAttached));
       
  1149 	__ASSERT_RETURN(iClearToEndOfLineMsg.IsNull(), PanicClient(aMessage, EPanicClearToEndOfLineAlreadyPending));
       
  1150 	iClearToEndOfLineMsg = aMessage;
       
  1151 	CleanupNullMessagePushL(iClearToEndOfLineMsg);
       
  1152 	WriteEndPoint()->IowepClearToEndOfLineL(*this);
       
  1153 	CleanupStack::Pop(&iClearToEndOfLineMsg);
       
  1154 	}
       
  1155 
       
  1156 void CIoWriteObject::ScreenSizeL(const RMsg& aMessage)
       
  1157 	{
       
  1158 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicScreenSizeWhenNotAttached));
       
  1159 	__ASSERT_RETURN(iGetScreenSizeMsg.IsNull(), PanicClient(aMessage, EPanicScreenSizeAlreadyPending));
       
  1160 	iGetScreenSizeMsg = aMessage;
       
  1161 	CleanupNullMessagePushL(iGetScreenSizeMsg);
       
  1162 	iTriedConsoleScreenSize = EFalse;
       
  1163 	WriteEndPoint()->IowepScreenSizeL(*this);
       
  1164 	CleanupStack::Pop(&iGetScreenSizeMsg);
       
  1165 	}
       
  1166 
       
  1167 void CIoWriteObject::SetAttributesL(const RMsg& aMessage)
       
  1168 	{
       
  1169 	__ASSERT_RETURN(iEndPoint, PanicClient(aMessage, EPanicSetAttributesWhenNotAttached));
       
  1170 	__ASSERT_RETURN(iSetAttributesMsg.IsNull(), PanicClient(aMessage, EPanicSetAttributesAlreadyPending));
       
  1171 	iSetAttributesMsg = aMessage;
       
  1172 	CleanupNullMessagePushL(iSetAttributesMsg);
       
  1173 	WriteEndPoint()->IowepSetAttributesL((TUint)aMessage.Int0(), (ConsoleAttributes::TColor)aMessage.Int1(), (ConsoleAttributes::TColor)aMessage.Int2(), *this);
       
  1174 	CleanupStack::Pop(&iSetAttributesMsg);
       
  1175 	}
       
  1176 
       
  1177 TBool CIoWriteObject::IsType(RIoHandle::TType aType) const
       
  1178 	{
       
  1179 	return ((aType == RIoHandle::EReadWriteObject) || (aType == RIoHandle::EWriteObject));
       
  1180 	}
       
  1181 
       
  1182 void CIoWriteObject::SessionClosed(const CIoSession& aSession)
       
  1183 	{
       
  1184 	WriteCancel(aSession);
       
  1185 	}
       
  1186 
       
  1187 RIoReadWriteHandle::TMode CIoWriteObject::IorwMode() const
       
  1188 	{
       
  1189 	return iMode;
       
  1190 	}
       
  1191 
       
  1192 void CIoWriteObject::IowComplete(TInt aError)
       
  1193 	{
       
  1194 	ASSERT(MessagePending(iWriteMessage));
       
  1195 	Complete(iWriteMessage, aError);
       
  1196 	iOffset = 0;
       
  1197 	iWriteLength = 0;
       
  1198 	}
       
  1199 
       
  1200 TName CIoWriteObject::IowName()
       
  1201 	{
       
  1202 	return Name();
       
  1203 	}
       
  1204 
       
  1205 CIoWriteObject::CIoWriteObject(TInt aId)
       
  1206 	: CIoReadWriteObject(aId)
       
  1207 	{
       
  1208 	}
       
  1209 
       
  1210 MIoWriteEndPoint* CIoWriteObject::WriteEndPoint() const
       
  1211 	{
       
  1212 	return static_cast<MIoWriteEndPoint*>(iEndPoint);
       
  1213 	}
       
  1214 
       
  1215 void CIoWriteObject::SetIsStdErr(TBool aFlag)
       
  1216 	{
       
  1217 	iIsStdErr = aFlag;
       
  1218 	}
       
  1219 
       
  1220 TBool CIoWriteObject::IowIsStdErr() const
       
  1221 	{
       
  1222 	return iIsStdErr;
       
  1223 	}