|
1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "US_STD.H" |
|
17 |
|
18 EXPORT_C TInt MStreamBuf::Synch() |
|
19 |
|
20 |
|
21 /** Synchronises the stream buffer with the stream, returning any error. |
|
22 |
|
23 In effect, this ensures that buffered data is delivered to the stream. |
|
24 |
|
25 This function calls SynchL() inside a TRAPD harness and returns the leave |
|
26 code if a leave occurs. |
|
27 |
|
28 @return KErrNone, if successful; otherwise one of the other system wide error |
|
29 codes. |
|
30 @see MStreamBuf::SynchL() |
|
31 @see MStreamBuf::DoSynchL() */ |
|
32 { |
|
33 TRAPD(r,SynchL()); |
|
34 return r; |
|
35 } |
|
36 |
|
37 EXPORT_C void MStreamBuf::Close() |
|
38 /** Closes the stream buffer. |
|
39 |
|
40 This function attempts to synchronise buffered data with the stream before |
|
41 freeing any resources. All errors are ignored. |
|
42 |
|
43 @see MStreamBuf::Synch() |
|
44 @see MStreamBuf::Release() */ |
|
45 { |
|
46 Synch(); |
|
47 Release(); |
|
48 } |
|
49 |
|
50 EXPORT_C void MStreamBuf::PushL() |
|
51 /** Puts a cleanup item for this object onto the cleanup stack. |
|
52 |
|
53 This allows allocated resources to be cleaned up if a subsequent leave occurs. */ |
|
54 { |
|
55 CleanupReleasePushL(*this); |
|
56 } |
|
57 |
|
58 EXPORT_C TInt MStreamBuf::Read(TDes8& aDes,TRequestStatus& aStatus) |
|
59 /** Reads data, asynchronously, from the stream buffer into the specified descriptor; |
|
60 request completion is guaranteed, even if request initiation fails. |
|
61 |
|
62 The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) |
|
63 to implement this behaviour. The maximum number of bytes to be read is the |
|
64 value of the maximum length of the descriptor. |
|
65 |
|
66 @param aDes The target descriptor for the data read from the stream buffer. |
|
67 @param aStatus The request status that indicates the completion status of this |
|
68 asynchronous request. |
|
69 @return The maximum number of bytes to be read, as used in this request. This |
|
70 value can be different to the maximum length of the descriptor; this is dependent |
|
71 on the implementation. |
|
72 @see MStreamBuf::DoReadL() */ |
|
73 { |
|
74 return Read(aDes,aDes.MaxLength(),aStatus); |
|
75 } |
|
76 |
|
77 EXPORT_C TInt MStreamBuf::Read(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus) |
|
78 /** Reads data, asynchronously, from the stream buffer into the specified descriptor; |
|
79 request completion is guaranteed, even if request initiation fails. |
|
80 |
|
81 The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) |
|
82 to implement this behaviour. |
|
83 |
|
84 @param aDes The target descriptor for the data read from the stream buffer. |
|
85 @param aMaxLength The maximum number of bytes to be read. |
|
86 @param aStatus The request status that indicates the completion status of this |
|
87 asynchronous request. |
|
88 @return The maximum number of bytes to be read, as used in this request. This |
|
89 can be different to the value supplied in aMaxLength; this is dependent on |
|
90 the implementation. |
|
91 @see MStreamBuf::DoReadL() */ |
|
92 { |
|
93 TInt len=0; |
|
94 TRAPD(r,len=DoReadL(aDes,aMaxLength,aStatus)); |
|
95 if (r!=KErrNone) |
|
96 { |
|
97 TRequestStatus* stat=&aStatus; |
|
98 User::RequestComplete(stat,r); |
|
99 } |
|
100 return len; |
|
101 } |
|
102 |
|
103 EXPORT_C TInt MStreamBuf::ReadL(TDes8& aDes,TRequestStatus& aStatus) |
|
104 /** Reads data, asynchronously, from the stream buffer into the specified descriptor. |
|
105 |
|
106 The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) |
|
107 to implement this behaviour. The maximum number of bytes to be read is the |
|
108 maximum length of the descriptor. |
|
109 |
|
110 If the function leaves, then no read request will have been initiated. |
|
111 |
|
112 @param aDes The target descriptor for the data read from the stream buffer. |
|
113 @param aStatus The request status that indicates the completion status of this |
|
114 asynchronous request. |
|
115 @return The maximum number of bytes to be read, as used in this request. This |
|
116 value can be different to the maximum length of the descriptor; this is dependent |
|
117 on the implementation. |
|
118 @see MStreamBuf::DoReadL() */ |
|
119 { |
|
120 return DoReadL(aDes,aDes.MaxLength(),aStatus); |
|
121 } |
|
122 |
|
123 EXPORT_C TInt MStreamBuf::ReadL(MStreamInput& anInput,TInt aMaxLength) |
|
124 /** Reads data from the stream buffer into the specified data sink. |
|
125 |
|
126 The function uses the virtual function DoReadL(MStreamInput&,TStreamTransfer) |
|
127 to implement this behaviour. |
|
128 |
|
129 @param anInput The data sink which is the target for the read operation. |
|
130 @param aMaxLength The maximum amount of data available to be read. |
|
131 @return The amount of data that was not consumed. */ |
|
132 { |
|
133 return aMaxLength-DoReadL(anInput,TStreamTransfer(aMaxLength)).Left(); |
|
134 } |
|
135 |
|
136 EXPORT_C TInt MStreamBuf::Write(const TDesC8& aDes,TRequestStatus& aStatus) |
|
137 /** Writes data, asynchronously, from the specified descriptor into the stream buffer; |
|
138 request completion is guaranteed, even if request initiation fails. |
|
139 |
|
140 The function calls the virtual function DoWriteL(const TDesC8&,TInt,TRequestStatus&) |
|
141 to implement this behaviour. The maximum number of bytes to be written is |
|
142 the value of the maximum length of the descriptor. |
|
143 |
|
144 @param aDes The source descriptor for the data to be written into the stream |
|
145 buffer. |
|
146 @param aStatus The request status that indicates the completion status of this |
|
147 asynchronous request. |
|
148 @return The maximum number of bytes to be written, as used in this request. |
|
149 This can be different to the value supplied in aMaxLength; this is dependent |
|
150 on the implementation. |
|
151 @see MStreamBuf::DoWriteL() */ |
|
152 { |
|
153 return Write(aDes,aDes.Length(),aStatus); |
|
154 } |
|
155 |
|
156 EXPORT_C TInt MStreamBuf::Write(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus) |
|
157 // |
|
158 // Write up to aMaxLength bytes with guaranteed completion. |
|
159 // |
|
160 { |
|
161 TInt len=0; |
|
162 TRAPD(r,len=DoWriteL(aDes,aMaxLength,aStatus)); |
|
163 if (r!=KErrNone) |
|
164 { |
|
165 TRequestStatus* stat=&aStatus; |
|
166 User::RequestComplete(stat,r); |
|
167 } |
|
168 return len; |
|
169 } |
|
170 |
|
171 EXPORT_C TInt MStreamBuf::WriteL(const TDesC8& aDes,TRequestStatus& aStatus) |
|
172 /** Writes data, asynchronously, from the specified descriptor into the stream buffer. |
|
173 |
|
174 The function calls the virtual function DoWriteL(const TDesC8&,TInt,TRequestStatus&) |
|
175 to implement this behaviour. The maximum number of bytes to be written is |
|
176 the value of the maximum length of the descriptor. |
|
177 |
|
178 If the function leaves, then no write request will have been initiated. |
|
179 |
|
180 @param aDes The source descriptor for the data to be written into the stream |
|
181 buffer. |
|
182 @param aStatus The request status that indicates the completion status of this |
|
183 asynchronous request. |
|
184 @return The maximum number of bytes to be written, as used in this request. |
|
185 This can be different to the maximum length of the descriptor; this is dependent |
|
186 on the implementation. |
|
187 @see MStreamBuf::DoWriteL() */ |
|
188 { |
|
189 return DoWriteL(aDes,aDes.Length(),aStatus); |
|
190 } |
|
191 |
|
192 EXPORT_C TInt MStreamBuf::WriteL(MStreamOutput& anOutput,TInt aMaxLength) |
|
193 /** Writes data into the stream buffer from the specified data source. |
|
194 |
|
195 The function calls the virtual function DoWriteL(MStreamOutput&,TStreamTransfer) |
|
196 to implement this behaviour. |
|
197 |
|
198 @param anOutput The data source for the write operation. |
|
199 @param aMaxLength The maximum amount of data available to be written. |
|
200 @return The amount of data that was not consumed. */ |
|
201 { |
|
202 return aMaxLength-DoWriteL(anOutput,TStreamTransfer(aMaxLength)).Left(); |
|
203 } |
|
204 |
|
205 EXPORT_C void MStreamBuf::DoRelease() |
|
206 /** Frees resources before abandoning the stream buffer. |
|
207 |
|
208 It is called by Release(). |
|
209 |
|
210 This implementation is empty, but classes derived from MStreamBuf can provide |
|
211 their own implementation, if necessary. |
|
212 |
|
213 @see MStreamBuf::Release() */ |
|
214 {} |
|
215 |
|
216 EXPORT_C void MStreamBuf::DoSynchL() |
|
217 /** Synchronises the stream buffer with the stream, leaving if any error occurs. |
|
218 |
|
219 In effect, this ensures that buffered data is delivered to the stream. |
|
220 |
|
221 It is called by SynchL(). |
|
222 |
|
223 This implementation is empty, but classes derived from MStreamBuf can provide |
|
224 their own implementation, if necessary. |
|
225 |
|
226 @see MStreamBuf::SynchL() */ |
|
227 {} |
|
228 |
|
229 EXPORT_C TInt MStreamBuf::DoReadL(TAny*,TInt) |
|
230 // |
|
231 // Cannot read from this stream buffer. |
|
232 // |
|
233 { |
|
234 Panic(EStreamCannotRead); |
|
235 return TInt(); |
|
236 } |
|
237 |
|
238 EXPORT_C TInt MStreamBuf::DoReadL(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus) |
|
239 /** Reads data from the stream buffer into the specified descriptor. |
|
240 |
|
241 This function is called by ReadL(TDes8&,TInt,TRequestStatus&). |
|
242 |
|
243 This implementation deals with the request synchronously, and completes the |
|
244 request with KErrNone. Other implementations may choose to deal with this |
|
245 in a true asynchronous manner. |
|
246 |
|
247 In addition, the read operation itself uses the DoReadL(TAny*,TInt) variant. |
|
248 |
|
249 @param aDes The target descriptor for the data read from the stream buffer. |
|
250 On return, the length of the descriptor is set to the number of bytes read |
|
251 from the stream buffer. |
|
252 @param aMaxLength The maximum number of bytes to be read. This value must not |
|
253 be greater than the maximum length of the descriptor, otherwise the function |
|
254 raises a STORE-Stream 2 panic. |
|
255 @param aStatus The request status that indicates the completion status of this |
|
256 asynchronous request. |
|
257 @return The maximum number of bytes to be read, as used in this request. This |
|
258 implementation uses, and returns, the value supplied in aMaxLength. Other |
|
259 implementations may choose to use a different value. |
|
260 @see MStreamBuf::ReadL() */ |
|
261 { |
|
262 __ASSERT_DEBUG(aMaxLength<=aDes.MaxLength(),Panic(EStreamReadBeyondEnd)); |
|
263 aDes.SetLength(DoReadL((TUint8*)aDes.Ptr(),aMaxLength)); |
|
264 TRequestStatus* stat=&aStatus; |
|
265 User::RequestComplete(stat,KErrNone); |
|
266 return aMaxLength; |
|
267 } |
|
268 |
|
269 EXPORT_C TStreamTransfer MStreamBuf::DoReadL(MStreamInput& anInput,TStreamTransfer aTransfer) |
|
270 /** Reads data from the stream into the specified data sink. |
|
271 |
|
272 It is called by ReadL(MStreamInput&,TStreamTransfer). |
|
273 |
|
274 This implementation calls the sink's ReadFromL() function, which performs |
|
275 the read (transfer) operation. |
|
276 |
|
277 This implementation of DoReadL() is called for streams that do not have buffering |
|
278 capabilities, and that are derived directly from this class. |
|
279 |
|
280 @param anInput The target data sink. |
|
281 @param aTransfer A stream transfer object defining the amount of data available |
|
282 to be read. |
|
283 @return A stream transfer object defining the amount of data that was not consumed. |
|
284 @see MStreamInput::ReadFromL() */ |
|
285 { |
|
286 return anInput.ReadFromL(*this,aTransfer); |
|
287 } |
|
288 |
|
289 EXPORT_C void MStreamBuf::DoWriteL(const TAny*,TInt) |
|
290 // |
|
291 // Cannot write to this stream buffer. |
|
292 // |
|
293 { |
|
294 Panic(EStreamCannotWrite); |
|
295 } |
|
296 |
|
297 EXPORT_C TInt MStreamBuf::DoWriteL(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus) |
|
298 /** Writes data from the specified descriptor into this stream buffer. |
|
299 |
|
300 This function is called by WriteL(const TDesC8&,TInt,TRequestStatus&). |
|
301 |
|
302 This implementation deals with the request synchronously, and completes the |
|
303 request with KErrNone. Other implementations may choose to deal with this |
|
304 in a true asynchronous manner. |
|
305 |
|
306 In addition, the write operation itself uses the DoWriteL(TAny*,TInt) variant. |
|
307 |
|
308 @param aDes The source descriptor for the data to be written into the stream |
|
309 buffer. |
|
310 @param aMaxLength The number of bytes to be written. This value must not be |
|
311 greater than the maximum length of the descriptor, otherwise the function |
|
312 raises a STORE-Stream 6 panic. |
|
313 @param aStatus The request status that indicates the completion status of this |
|
314 asynchronous request. |
|
315 @return The maximum number of bytes to be written, as used in this request. |
|
316 This implementation uses, and returns, the value supplied in aMaxLength. Other |
|
317 implementations may choose to use a different value. |
|
318 @see MStreamBuf::WriteL() */ |
|
319 { |
|
320 __ASSERT_DEBUG(aMaxLength<=aDes.Length(),Panic(EStreamWriteBeyondEnd)); |
|
321 DoWriteL(aDes.Ptr(),aMaxLength); |
|
322 TRequestStatus* stat=&aStatus; |
|
323 User::RequestComplete(stat,KErrNone); |
|
324 return aMaxLength; |
|
325 } |
|
326 |
|
327 EXPORT_C TStreamTransfer MStreamBuf::DoWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer) |
|
328 // |
|
329 // Default implementation turning around to anOutput. |
|
330 // |
|
331 { |
|
332 return anOutput.WriteToL(*this,aTransfer); |
|
333 } |
|
334 |
|
335 EXPORT_C TStreamPos MStreamBuf::DoSeekL(TMark,TStreamLocation,TInt) |
|
336 // |
|
337 // This stream buffer does not support seeking. |
|
338 // |
|
339 { |
|
340 Panic(EStreamCannotSeek); |
|
341 TStreamPos streamPos(-1); |
|
342 return streamPos; |
|
343 } |
|
344 |
|
345 EXPORT_C TStreamBuf::TStreamBuf() |
|
346 : iRPtr(NULL),iREnd(NULL),iWPtr(NULL),iWEnd(NULL) |
|
347 /** Sets the pointers that mark out the read and write areas within the intermediate |
|
348 buffer to null. */ |
|
349 {} |
|
350 |
|
351 EXPORT_C void TStreamBuf::SetBuf(TArea anArea,TUint8* aPtr,TUint8* anEnd) |
|
352 /** Sets the start and end points of the read and/or the write area within the intermediate |
|
353 buffer. |
|
354 |
|
355 A start point is always within an area; an end point is always the first byte |
|
356 beyond the end of an area. |
|
357 |
|
358 @param anArea The areas within the intermediate buffer for which the start |
|
359 and end points are to be set. These can be the read area and/or the write |
|
360 area, as indicated by the ERead and EWrite bits. Only these bits can be set, |
|
361 otherwise the function raises a STORE-Stream 17 panic. |
|
362 @param aPtr The start point. |
|
363 @param anEnd The end point. |
|
364 @see MStreamBuf::TRead |
|
365 @see MStreamBuf::TWrite */ |
|
366 { |
|
367 __ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid)); |
|
368 if (anArea&ERead) |
|
369 SetBuf(ERead,aPtr,anEnd); |
|
370 if (anArea&EWrite) |
|
371 SetBuf(EWrite,aPtr,anEnd); |
|
372 } |
|
373 |
|
374 EXPORT_C void TStreamBuf::SetPtr(TArea anArea,TUint8* aPtr) |
|
375 /** Sets the start point of the read and/or the write area within the intermediate |
|
376 buffer. |
|
377 |
|
378 A start point is always within an area. |
|
379 |
|
380 @param anArea The areas within the intermediate buffer for which the start |
|
381 point is to be set. These can be the read area and/or the write area, as indicated |
|
382 by the ERead and EWrite bits. Only these bits can be set, otherwise the function |
|
383 raises a STORE-Stream 17 panic. |
|
384 @param aPtr The start point. |
|
385 @see MStreamBuf::TRead |
|
386 @see MStreamBuf::TWrite */ |
|
387 { |
|
388 __ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid)); |
|
389 if (anArea&ERead) |
|
390 SetPtr(ERead,aPtr); |
|
391 if (anArea&EWrite) |
|
392 SetPtr(EWrite,aPtr); |
|
393 } |
|
394 |
|
395 EXPORT_C void TStreamBuf::SetEnd(TArea anArea,TUint8* anEnd) |
|
396 // |
|
397 // Set the end pointer for the buffer area(s) indicated by anArea. |
|
398 // |
|
399 { |
|
400 __ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid)); |
|
401 if (anArea&ERead) |
|
402 SetEnd(ERead,anEnd); |
|
403 if (anArea&EWrite) |
|
404 SetEnd(EWrite,anEnd); |
|
405 } |
|
406 |
|
407 EXPORT_C TUint8* TStreamBuf::Ptr(TArea anArea) const |
|
408 /** Gets the current start point of the read or write area within the intermediate |
|
409 buffer. |
|
410 |
|
411 @param anArea The area within the intermediate buffer for which the start |
|
412 point is to be fetched. This can be either the read area or the write area, |
|
413 as indicated by the ERead and EWrite bits. Only one of these can be set, otherwise |
|
414 the function raises a STORE-Stream 17 panic. |
|
415 @return The start point. |
|
416 @see MStreamBuf::TRead |
|
417 @see MStreamBuf::TWrite */ |
|
418 { |
|
419 if (anArea==ERead) |
|
420 return Ptr(ERead); |
|
421 // |
|
422 __ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid)); |
|
423 return Ptr(EWrite); |
|
424 } |
|
425 |
|
426 EXPORT_C TUint8* TStreamBuf::End(TArea anArea) const |
|
427 /** Gets the current end point of the read or write area within the intermediate |
|
428 buffer. |
|
429 |
|
430 An end point is always the first byte beyond the end of an area. |
|
431 |
|
432 @param anArea The area within the intermediate buffer for which the end point |
|
433 is to be fetched. This can be either the read area or the write area, as indicated |
|
434 by the ERead and EWrite bits. Only one of these can be set, otherwise the |
|
435 function raises a STORE-Stream 17 panic. |
|
436 @return The end point. */ |
|
437 { |
|
438 if (anArea==ERead) |
|
439 return End(ERead); |
|
440 // |
|
441 __ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid)); |
|
442 return End(EWrite); |
|
443 } |
|
444 |
|
445 EXPORT_C TInt TStreamBuf::Avail(TArea anArea) const |
|
446 /** Gets the number of bytes available in the read or write area within the intermediate |
|
447 buffer. |
|
448 |
|
449 @param anArea The area within the intermediate buffer for which the number |
|
450 of available bytes is to be fetched. This can be either the read area or the |
|
451 write area, as indicated by the ERead and EWrite bits. Only one of these can |
|
452 be set, otherwise the function raises a STORE-Stream 17 panic. |
|
453 @return The number of bytes available. */ |
|
454 { |
|
455 if (anArea==ERead) |
|
456 return Avail(ERead); |
|
457 // |
|
458 __ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid)); |
|
459 return Avail(EWrite); |
|
460 } |
|
461 |
|
462 EXPORT_C TInt TStreamBuf::DoReadL(TAny* aPtr,TInt aMaxLength) |
|
463 /** Reads data from the intermediate buffer into the specified memory location. |
|
464 |
|
465 The function calls the virtual function UnderfLowL() to give concrete implementations |
|
466 the chance to refill the intermediate buffer, and satisfy the caller's requirements. |
|
467 |
|
468 This implementation overrides the one supplied by the base class MStreamBuf, |
|
469 and is called by, MStreamBuf::ReadL(TAny*,TInt). |
|
470 |
|
471 @param aPtr A pointer to the target memory location for the data read from |
|
472 the intermediate buffer. |
|
473 @param aMaxLength The maximum number of bytes to be read. |
|
474 @return The number of bytes read. This may be less than the amount requested. |
|
475 @see MStreamBuf::ReadL() |
|
476 @see MStreamBuf::DoReadL() */ |
|
477 { |
|
478 __ASSERT_DEBUG(aMaxLength>=0,Panic(EStreamReadLengthNegative)); |
|
479 __ASSERT_DEBUG(aMaxLength>0,Panic(EStreamReadNoTransfer)); |
|
480 __ASSERT_DEBUG(Ptr(ERead)!=NULL||End(ERead)==NULL,Panic(EStreamCannotRead)); |
|
481 TInt left=aMaxLength; |
|
482 TInt avail=Avail(ERead); |
|
483 __ASSERT_DEBUG(avail>=0,User::Invariant()); |
|
484 if (avail==0) |
|
485 goto underflow; |
|
486 // |
|
487 do |
|
488 { |
|
489 __ASSERT_DEBUG(avail==Avail(ERead),Panic(EStreamUnderflowInBreach)); |
|
490 __ASSERT_DEBUG(left>0&&avail>0,User::Invariant()); |
|
491 { |
|
492 TInt len=Min(left,avail); |
|
493 TUint8* ptr=Ptr(ERead); |
|
494 aPtr=Mem::Copy(aPtr,ptr,len); |
|
495 SetPtr(ERead,ptr+len); |
|
496 left-=len; |
|
497 if (left==0) |
|
498 return aMaxLength; // that's it |
|
499 } |
|
500 // |
|
501 underflow: |
|
502 avail=UnderflowL(left); |
|
503 } while (avail>0); |
|
504 __ASSERT_DEBUG(avail==0&&Avail(ERead)==0,Panic(EStreamUnderflowInBreach)); |
|
505 return aMaxLength-left; |
|
506 } |
|
507 |
|
508 EXPORT_C TStreamTransfer TStreamBuf::DoReadL(MStreamInput& anInput,TStreamTransfer aTransfer) |
|
509 /** Reads data from the intermediate buffer and, if necessary, any remaining data |
|
510 from the stream to the specified target stream input object. |
|
511 |
|
512 It is called by ReadL(MStreamInput&,TStreamTransfer). |
|
513 |
|
514 The intermediate buffer is emptied first by calling the target stream input's |
|
515 PushL() function, which performs the read from intermediate buffer operation. |
|
516 Any remaining data is then read from the stream by calling the target stream |
|
517 object's ReadFromL() function, which performs the read from stream operation. |
|
518 |
|
519 This implementation is called for streams that have buffering capabilities |
|
520 and are derived from this class. |
|
521 |
|
522 @param anInput The target stream input object. |
|
523 @param aTransfer A stream transfer object defining the amount of data available |
|
524 to be written. |
|
525 @return The amount of data that was not consumed. |
|
526 @see MStreamInput::ReadFromL() |
|
527 @see MStreamInput::PushL() */ |
|
528 { |
|
529 __ASSERT_DEBUG(aTransfer>0,Panic(EStreamReadNoTransfer)); |
|
530 __ASSERT_DEBUG(Ptr(ERead)!=NULL||End(ERead)==NULL,Panic(EStreamCannotRead)); |
|
531 __ASSERT_DEBUG(Avail(ERead)>=0,User::Invariant()); |
|
532 TInt len=aTransfer[Avail(ERead)]; |
|
533 if (len>0) |
|
534 { |
|
535 __DEBUG(TInt avail=Avail(ERead)); // may be pushing into this streambuf |
|
536 TUint8* ptr=Ptr(ERead); |
|
537 len=anInput.PushL(ptr,len); |
|
538 __ASSERT_DEBUG(len>=0&&len<=aTransfer[avail]&&Ptr(ERead)==ptr&&Avail(ERead)>=avail,Panic(EStreamPushInBreach)); |
|
539 SetPtr(ERead,ptr+len); |
|
540 aTransfer-=len; |
|
541 } |
|
542 if (aTransfer>0) |
|
543 aTransfer=anInput.ReadFromL(*this,aTransfer); |
|
544 return aTransfer; |
|
545 } |
|
546 |
|
547 EXPORT_C void TStreamBuf::DoWriteL(const TAny* aPtr,TInt aLength) |
|
548 /** Writes data from the specified memory location into the intermediate buffer. |
|
549 |
|
550 The function calls the virtual function OverfLowL() to give concrete implementations |
|
551 the chance to forward the intermediate buffer content to its destination. |
|
552 |
|
553 This implementation overrides the one supplied by the base class MStreamBuf, |
|
554 and is called by MStreamBuf::WriteL(const TAny*,TInt). |
|
555 |
|
556 @param aPtr A pointer to the source memory location for the data to be written |
|
557 to the intermediate buffer. |
|
558 @param aLength The number of bytes to be written. |
|
559 @return The number of bytes written. |
|
560 @see MStreamBuf::WriteL() |
|
561 @see MStreamBuf::DoWriteL() */ |
|
562 { |
|
563 __ASSERT_DEBUG(aLength>=0,Panic(EStreamWriteLengthNegative)); |
|
564 __ASSERT_DEBUG(aLength>0,Panic(EStreamWriteNoTransfer)); |
|
565 __ASSERT_DEBUG(Ptr(EWrite)!=NULL||End(EWrite)==NULL,Panic(EStreamCannotWrite)); |
|
566 TInt avail=Avail(EWrite); |
|
567 __ASSERT_DEBUG(avail>=0,User::Invariant()); |
|
568 if (avail==0) |
|
569 goto overflow; |
|
570 // |
|
571 for(;;) |
|
572 { |
|
573 __ASSERT_DEBUG(avail>0,Panic(EStreamOverflowInBreach)); |
|
574 __ASSERT_DEBUG(aLength>0,User::Invariant()); |
|
575 { |
|
576 TInt len=Min(aLength,avail); |
|
577 SetPtr(EWrite,Mem::Copy(Ptr(EWrite),aPtr,len)); |
|
578 aLength-=len; |
|
579 if (aLength==0) |
|
580 return; // done |
|
581 // |
|
582 aPtr=(TUint8*)aPtr+len; |
|
583 } |
|
584 // |
|
585 overflow: |
|
586 OverflowL(); |
|
587 avail=Avail(EWrite); |
|
588 }; |
|
589 } |
|
590 |
|
591 EXPORT_C TStreamTransfer TStreamBuf::DoWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer) |
|
592 // |
|
593 // Default implementation filling the buffer before turning around to anOutput. |
|
594 // |
|
595 { |
|
596 __ASSERT_DEBUG(aTransfer>0,Panic(EStreamWriteNoTransfer)); |
|
597 __ASSERT_DEBUG(Ptr(EWrite)!=NULL||End(EWrite)==NULL,Panic(EStreamCannotWrite)); |
|
598 __ASSERT_DEBUG(Avail(EWrite)>=0,User::Invariant()); |
|
599 TInt len=aTransfer[Avail(EWrite)]; |
|
600 if (len>0) |
|
601 { |
|
602 __DEBUG(TInt avail=Avail(EWrite)); // may be pulling from this streambuf |
|
603 TUint8* ptr=Ptr(EWrite); |
|
604 len=anOutput.PullL(ptr,len); |
|
605 __ASSERT_DEBUG(len>=0&&len<=aTransfer[avail]&&Ptr(EWrite)==ptr&&Avail(EWrite)>=avail,Panic(EStreamPullInBreach)); |
|
606 SetPtr(EWrite,ptr+len); |
|
607 aTransfer-=len; |
|
608 } |
|
609 if (aTransfer>0) |
|
610 aTransfer=anOutput.WriteToL(*this,aTransfer); |
|
611 return aTransfer; |
|
612 } |
|
613 |