|
1 // pipe.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 "log.h" |
|
16 |
|
17 #ifdef IOSRV_LOGGING |
|
18 #define PIPE_NAME TName pipeName(Name()) |
|
19 #define READER_NAME(x) TName readerName((x).IorName()) |
|
20 #define WRITER_NAME(x) TName writerName((x).IowName()) |
|
21 #else |
|
22 #define PIPE_NAME |
|
23 #define READER_NAME(x) |
|
24 #define WRITER_NAME(x) |
|
25 #endif |
|
26 |
|
27 CIoPipe* CIoPipe::NewLC() |
|
28 { |
|
29 CIoPipe* self = new(ELeave) CIoPipe(); |
|
30 LOG(CIoLog::Printf(_L("Pipe 0x%08x created"), self)); |
|
31 CleanupClosePushL(*self); |
|
32 return self; |
|
33 } |
|
34 |
|
35 CIoPipe::~CIoPipe() |
|
36 { |
|
37 iPendingWriters.Close(); |
|
38 } |
|
39 |
|
40 TBool CIoPipe::IsType(RIoHandle::TType aType) const |
|
41 { |
|
42 return ((aType == RIoHandle::EEndPoint) || (aType == RIoHandle::EPipe)); |
|
43 } |
|
44 |
|
45 void CIoPipe::IorepReadL(MIoReader& aReader) |
|
46 { |
|
47 if (&aReader == AttachedReader()) |
|
48 { |
|
49 CheckReady(); |
|
50 DoCopy(); |
|
51 } |
|
52 } |
|
53 |
|
54 void CIoPipe::IowepWriteL(MIoWriter& aWriter) |
|
55 { |
|
56 User::LeaveIfError(iPendingWriters.Append(&aWriter)); |
|
57 CheckReady(); |
|
58 DoCopy(); |
|
59 } |
|
60 |
|
61 void CIoPipe::IowepWriteCancel(MIoWriter& aWriter) |
|
62 { |
|
63 const TInt numPendingWriters = iPendingWriters.Count(); |
|
64 for (TInt i = 0; i < numPendingWriters; ++i) |
|
65 { |
|
66 if (&aWriter == iPendingWriters[i]) |
|
67 { |
|
68 iPendingWriters.Remove(i); |
|
69 break; |
|
70 } |
|
71 } |
|
72 } |
|
73 |
|
74 void CIoPipe::ForegroundReaderChanged() |
|
75 { |
|
76 DoCopy(); |
|
77 } |
|
78 |
|
79 void CIoPipe::HandleReaderDetached(MIoReader&) |
|
80 { |
|
81 CheckReady(); |
|
82 } |
|
83 |
|
84 void CIoPipe::HandleWriterDetached(MIoWriter& aWriter) |
|
85 { |
|
86 const TInt numPendingWriters = iPendingWriters.Count(); |
|
87 for (TInt i = 0; i < numPendingWriters; ++i) |
|
88 { |
|
89 if (&aWriter == iPendingWriters[i]) |
|
90 { |
|
91 iPendingWriters.Remove(i); |
|
92 break; |
|
93 } |
|
94 } |
|
95 CheckReady(); |
|
96 } |
|
97 |
|
98 CIoPipe::CIoPipe() |
|
99 { |
|
100 } |
|
101 |
|
102 void CIoPipe::DoCopy() |
|
103 { |
|
104 if ((AttachedReader() == NULL) || !AttachedReader()->IorReadPending()) |
|
105 { |
|
106 return; |
|
107 } |
|
108 |
|
109 READER_NAME(*AttachedReader()); |
|
110 TInt readBufOffset = 0; |
|
111 TDes& readBuf = AttachedReader()->IorReadBuf(); |
|
112 TBool readBuffered(EFalse); |
|
113 |
|
114 while (iPendingWriters.Count() > 0) |
|
115 { |
|
116 MIoWriter& writer = *(iPendingWriters[0]); |
|
117 WRITER_NAME(writer); |
|
118 const TInt lengthToWrite = writer.IowWriteLength(); |
|
119 const TInt length = Min(lengthToWrite, readBuf.MaxLength() - readBuf.Length()); |
|
120 TPtr readPtr(const_cast<TText*>(readBuf.Ptr()) + readBufOffset, 0, length); |
|
121 TInt err = writer.IowWrite(readPtr); |
|
122 if (err == KErrNone) |
|
123 { |
|
124 LOG(CIoLog::Printf(_L("Copied %d chars from writer \"%S\" (0x%08x) to reader \"%S\" (0x%08x)"), readPtr.Length(), &writerName, &writer, &readerName, AttachedReader())); |
|
125 readBufOffset += readPtr.Length(); |
|
126 readBuf.SetLength(readBufOffset); |
|
127 readBuffered = ETrue; |
|
128 if (lengthToWrite == length) |
|
129 { |
|
130 LOG(CIoLog::Printf(_L("Writer \"%S\" (0x%08x) fully copied"), &writerName, &writer)); |
|
131 writer.IowComplete(KErrNone); |
|
132 iPendingWriters.Remove(0); |
|
133 } |
|
134 else if (readBuf.MaxLength() == readBuf.Length()) |
|
135 { |
|
136 LOG(CIoLog::Printf(_L("Read buffer full (\"%S\" 0x%08x)"), &readerName, AttachedReader())); |
|
137 break; |
|
138 } |
|
139 } |
|
140 else |
|
141 { |
|
142 LOG(CIoLog::Printf(_L("Failed to copy \"%S\" from writer \"%S\" (0x%08x) to reader \"%S\" (0x%08x): %S(%d)"), &readPtr, &writerName, &writer, &readerName, AttachedReader(), CIoLog::StringifyError(err), err)); |
|
143 writer.IowComplete(err); |
|
144 } |
|
145 } |
|
146 |
|
147 if (readBuffered) |
|
148 { |
|
149 AttachedReader()->IorDataBuffered(readBuf.Length()); |
|
150 } |
|
151 } |
|
152 |
|
153 void CIoPipe::CheckReady() |
|
154 { |
|
155 if ((NumAttachedWriters() == 0) && AttachedReader() && AttachedReader()->IorReadPending()) |
|
156 { |
|
157 if (AttachedReader()->IorDataIsBuffered()) |
|
158 { |
|
159 AttachedReader()->IorReadComplete(KErrNone); |
|
160 } |
|
161 else |
|
162 { |
|
163 AttachedReader()->IorReadComplete(KErrEof); |
|
164 } |
|
165 } |
|
166 else if (AttachedReader() == NULL) |
|
167 { |
|
168 while (iPendingWriters.Count()) |
|
169 { |
|
170 MIoWriter* writer = iPendingWriters[0]; |
|
171 iPendingWriters.Remove(0); |
|
172 writer->IowComplete(KErrNotReady); |
|
173 } |
|
174 } |
|
175 } |
|
176 |