|
1 /* |
|
2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "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 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #ifndef __ACMREADER_H__ |
|
19 #define __ACMREADER_H__ |
|
20 |
|
21 #include <e32std.h> |
|
22 #include <d32comm.h> |
|
23 #include "ReadObserver.h" |
|
24 #include "ReadOneOrMoreObserver.h" |
|
25 #include "NotifyDataAvailableObserver.h" |
|
26 |
|
27 class CCdcAcmClass; |
|
28 class CAcmPort; |
|
29 |
|
30 NONSHARABLE_CLASS(CAcmReader) : public CBase, |
|
31 public MReadObserver, |
|
32 public MReadOneOrMoreObserver, |
|
33 public MNotifyDataAvailableObserver |
|
34 /** |
|
35 * CAcmReader maintains the port's read buffer, fields requests from the port |
|
36 * (its client) for data, and administers getting more data from the LDD. |
|
37 * |
|
38 * It presents an interface for requesting data- whether the required data is |
|
39 * immediately available in the buffer or not, it eventually completes the |
|
40 * client (port)'s request using CPort::IPCWrite and CPort::ReadCompleted. |
|
41 * |
|
42 * It uses the CCdcAcmClass to ask for more data from the host. Consequently |
|
43 * it implements MReadObserver and MReadOneOrMoreObserver to be notified when |
|
44 * data has come in. |
|
45 */ |
|
46 { |
|
47 public: |
|
48 static CAcmReader* NewL(CAcmPort& aPort, |
|
49 TUint aBufSize); |
|
50 ~CAcmReader(); |
|
51 |
|
52 public: // APIs for reading |
|
53 void Read(const TAny* aClientBuffer, TUint aMaxLen); |
|
54 void ReadOneOrMore(const TAny* aClientBuffer, TUint aMaxLen); |
|
55 void ReadCancel(); |
|
56 void NotifyDataAvailable(); |
|
57 void NotifyDataAvailableCancel(); |
|
58 inline TBool IsNotifyDataAvailableQueryPending() const; |
|
59 |
|
60 public: // buffer APIs |
|
61 TUint BufLen() const; |
|
62 inline TUint BufSize() const; |
|
63 void ResetBuffer(); |
|
64 TInt SetBufSize(TUint aSize); |
|
65 void SetTerminators(const TCommConfigV01& aConfig); |
|
66 |
|
67 private: |
|
68 CAcmReader(CAcmPort& aPort, |
|
69 TUint aBufSize); |
|
70 void ConstructL(); |
|
71 |
|
72 private: // from MReadObserver |
|
73 void ReadCompleted(TInt aError); |
|
74 |
|
75 private: // from MReadOneOrMoreObserver |
|
76 void ReadOneOrMoreCompleted(TInt aError); |
|
77 |
|
78 private: // from MNotifyDataAvailableObserver |
|
79 void NotifyDataAvailableCompleted(TInt aError); |
|
80 |
|
81 private: // utilities |
|
82 inline TBool BufWrap() const; |
|
83 void CheckBufferEmptyAndResetPtrs(); |
|
84 void CheckNewRequest(const TAny* aClientBuffer, TUint aMaxLen); |
|
85 void CheckForBufferedTerminatorsAndProceed(); |
|
86 |
|
87 void WriteBackData(TUint aLength); |
|
88 void CompleteRequest(TInt aError); |
|
89 |
|
90 void ReadWithoutTerminators(); |
|
91 void ReadWithTerminators(); |
|
92 |
|
93 void IssueRead(); |
|
94 void IssueReadOneOrMore(); |
|
95 |
|
96 TInt FindTerminator() const; |
|
97 TInt PartialFindTerminator(TUint8* aFrom, TUint8* aTo, TInt& aPos) const; |
|
98 |
|
99 private: // owned- information on the current request from the port (if any) |
|
100 |
|
101 enum TRequestType |
|
102 { |
|
103 ERead, |
|
104 EReadOneOrMore, |
|
105 ENotifyDataAvailable |
|
106 }; |
|
107 |
|
108 NONSHARABLE_STRUCT(TRequestData) |
|
109 { |
|
110 // Pointer to the client's memory to put the data into. This is also |
|
111 // used as a flag for whether we have an outstanding request or not. |
|
112 const TAny* iClientPtr; |
|
113 // type of the current request |
|
114 TRequestType iRequestType; |
|
115 }; |
|
116 // This struct is populated when a new client request comes in. |
|
117 TRequestData iCurrentRequest; |
|
118 |
|
119 private: // owned- information on our attempt to satisfy the current request |
|
120 // from the port (if any) |
|
121 |
|
122 // Starts as the amount of data requested by the client. |
|
123 // This may not be the same as the |
|
124 // amount of data given back to the client when the request is |
|
125 // completed, for instance if the read is a one-or-more, or if |
|
126 // terminators are defined. |
|
127 // Will be the number of bytes remaining to be read before we can |
|
128 // complete the client's request. |
|
129 TUint iLengthToGo; |
|
130 |
|
131 // Offset into iClientPtr to write more data to using IPCWrite. |
|
132 TUint iOffsetIntoClientsMemory; |
|
133 |
|
134 private: // owned- information on the buffer |
|
135 |
|
136 // The current actual size of the buffer. |
|
137 TUint iBufSize; |
|
138 |
|
139 // Our buffer of data. |
|
140 HBufC8* iBuffer; |
|
141 |
|
142 // These TUints are pointers to various places in iBuffer. |
|
143 |
|
144 // Pointer to where data will be placed into our buffer (from the LDD). |
|
145 TUint8* iInPtr; |
|
146 // Pointer to where data will leave our buffer (to go up to the client). |
|
147 TUint8* iOutPtr; |
|
148 // Pointer to the start of the buffer. |
|
149 TUint8* iBufStart; |
|
150 |
|
151 // Descriptor pointer into iBuffer. We use this in Read and ReadOneOrMore |
|
152 // calls to the LDD to get data written into iBuffer. |
|
153 TPtr8 iInBuf; |
|
154 |
|
155 private: // owned- information on the terminator characters |
|
156 TUint iTerminatorCount; |
|
157 TFixedArray<TText8, KConfigMaxTerminators> iTerminator; |
|
158 |
|
159 private: // unowned |
|
160 // Used to access the (RComm) client's memory and to complete their |
|
161 // request. Also accesses the ACM class through the port. (The ACM class |
|
162 // may come and go, following the lifetime of the registration port, not |
|
163 // the ACM port.) |
|
164 CAcmPort& iPort; |
|
165 }; |
|
166 |
|
167 TBool CAcmReader::BufWrap() const |
|
168 /** |
|
169 * This function indicates whether the circular buffer has wrapped. |
|
170 * |
|
171 * @return TBool Indication of whether the buffer has wrapped. |
|
172 */ |
|
173 { |
|
174 TBool ret = EFalse; |
|
175 if ( iOutPtr > iInPtr ) |
|
176 { |
|
177 ret = ETrue; |
|
178 } |
|
179 |
|
180 return ret; |
|
181 } |
|
182 |
|
183 TUint CAcmReader::BufSize() const |
|
184 /** |
|
185 * Accessor for current buffer size. |
|
186 * |
|
187 * @return The current buffer size. |
|
188 */ |
|
189 { |
|
190 return iBufSize; |
|
191 } |
|
192 |
|
193 TBool CAcmReader::IsNotifyDataAvailableQueryPending() const |
|
194 /** |
|
195 * check if a NotifyDataAvailable query is in progress |
|
196 * |
|
197 * @return ETrue if a NotifyDataAvailable query is pending, EFalse if not. |
|
198 */ |
|
199 { |
|
200 return ((iCurrentRequest.iClientPtr)&&(ENotifyDataAvailable==iCurrentRequest.iRequestType)); |
|
201 } |
|
202 |
|
203 #endif // __ACMREADER_H__ |