|
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 "UM_STD.H" |
|
17 |
|
18 EXPORT_C TMemBuf::TMemBuf() |
|
19 : iBase(NULL) |
|
20 /** Constructs an empty object. |
|
21 |
|
22 Call Set() before using the object. */ |
|
23 {} |
|
24 |
|
25 EXPORT_C void TMemBuf::Set(TUint8* aPtr,TUint8* anEnd,TInt aMode) |
|
26 /** Sets up the stream to use the specified area of plain memory. |
|
27 |
|
28 @param aPtr The start address for the area of plain memory that hosts the |
|
29 stream and that also acts as the intermediate buffer. |
|
30 @param anEnd The end address for the area of plain memory that hosts the stream |
|
31 and that also acts as the intermediate buffer. The addressed byte is outside |
|
32 the memory area. |
|
33 @param aMode The mode in which the stream is to be used. It can be used in |
|
34 either or both read and write modes, represented by ERead and EWrite. |
|
35 @see MStreamBuf::TRead |
|
36 @see MStreamBuf::TWrite */ |
|
37 { |
|
38 if (aPtr==NULL && anEnd==NULL) |
|
39 aPtr=anEnd=(TUint8*)this; // treat null data as seekable zero-length data |
|
40 iBase=aPtr; |
|
41 SetBuf(ERead,(aMode&ERead)?aPtr:NULL,anEnd); |
|
42 SetBuf(EWrite,(aMode&EWrite)?aPtr:NULL,anEnd); |
|
43 } |
|
44 |
|
45 EXPORT_C TInt TMemBuf::UnderflowL(TInt) |
|
46 // |
|
47 // The read buffer is empty. |
|
48 // |
|
49 { |
|
50 return 0; |
|
51 } |
|
52 |
|
53 EXPORT_C void TMemBuf::OverflowL() |
|
54 // |
|
55 // Ran out of write buffer. |
|
56 // |
|
57 { |
|
58 __LEAVE(KErrOverflow); |
|
59 } |
|
60 |
|
61 EXPORT_C TStreamPos TMemBuf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset) |
|
62 // |
|
63 // Position the mark(s) indicated by aMark at anOffset from aLocation. |
|
64 // |
|
65 { |
|
66 TUint8* ptr=0; |
|
67 switch (aLocation) |
|
68 { |
|
69 case EStreamBeginning: |
|
70 ptr=Base()+anOffset; |
|
71 break; |
|
72 case EStreamMark: |
|
73 ptr=Ptr(aMark)+anOffset; |
|
74 break; |
|
75 case EStreamEnd: |
|
76 ptr=End()+anOffset; |
|
77 break; |
|
78 default: |
|
79 Panic(EMemLocationInvalid); |
|
80 break; |
|
81 } |
|
82 TInt r=KErrNone; |
|
83 if (ptr>End()) |
|
84 { |
|
85 ptr=End(); |
|
86 r=KErrEof; |
|
87 } |
|
88 else if (ptr<Base()) |
|
89 { |
|
90 ptr=Base(); |
|
91 r=KErrEof; |
|
92 } |
|
93 // |
|
94 SetPtr(aMark,ptr); |
|
95 __LEAVE_IF_ERROR(r); |
|
96 return TStreamPos(ptr-Base()); |
|
97 } |
|
98 |
|
99 EXPORT_C TDesBuf::TDesBuf() |
|
100 : iDes(NULL) |
|
101 /** Constructs an empty object. |
|
102 |
|
103 Call Set() before using the object. */ |
|
104 {} |
|
105 |
|
106 EXPORT_C void TDesBuf::Set(TDes8& aDes,TInt aMode) |
|
107 /** Sets up the stream to use the specified descriptor. |
|
108 |
|
109 @param aDes The descriptor that hosts the stream and that also acts as the |
|
110 intermediate buffer. |
|
111 @param aMode The mode in which the buffer is to be used. It can be used in |
|
112 either or both read and write modes, represented by ERead and EWrite. |
|
113 @see TDes8 |
|
114 @see MStreamBuf::TRead |
|
115 @see MStreamBuf::TWrite */ |
|
116 { |
|
117 iDes=&aDes; |
|
118 TUint8* ptr=(TUint8*)aDes.Ptr(); |
|
119 SetBuf(ERead,(aMode&ERead)?ptr:NULL,ptr+aDes.Length()); |
|
120 SetBuf(EWrite,(aMode&EWrite)?ptr:NULL,ptr+aDes.MaxLength()); |
|
121 } |
|
122 |
|
123 EXPORT_C TInt TDesBuf::UnderflowL(TInt) |
|
124 // |
|
125 // Check if there's any more to be read. |
|
126 // |
|
127 { |
|
128 Consolidate(); |
|
129 return Avail(ERead); |
|
130 } |
|
131 |
|
132 EXPORT_C void TDesBuf::OverflowL() |
|
133 // |
|
134 // Ran out of write buffer. |
|
135 // |
|
136 { |
|
137 __LEAVE(KErrOverflow); |
|
138 } |
|
139 |
|
140 EXPORT_C void TDesBuf::DoSynchL() |
|
141 // |
|
142 // Synchronise descriptor and stream buffer. |
|
143 // |
|
144 { |
|
145 Consolidate(); |
|
146 } |
|
147 |
|
148 EXPORT_C TStreamPos TDesBuf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset) |
|
149 // |
|
150 // Position the mark(s) indicated by aMark at anOffset from aLocation. |
|
151 // |
|
152 { |
|
153 Consolidate(); |
|
154 TUint8* ptr=0; |
|
155 switch (aLocation) |
|
156 { |
|
157 case EStreamBeginning: |
|
158 ptr=Base()+anOffset; |
|
159 break; |
|
160 case EStreamMark: |
|
161 ptr=Ptr(aMark)+anOffset; |
|
162 break; |
|
163 case EStreamEnd: |
|
164 ptr=End(ERead)+anOffset; |
|
165 break; |
|
166 default: |
|
167 Panic(EMemLocationInvalid); |
|
168 break; |
|
169 } |
|
170 TInt r=KErrNone; |
|
171 if (ptr>End(ERead)) |
|
172 { |
|
173 ptr=End(ERead); |
|
174 r=KErrEof; |
|
175 } |
|
176 else if (ptr<Base()) |
|
177 { |
|
178 ptr=Base(); |
|
179 r=KErrEof; |
|
180 } |
|
181 // |
|
182 SetPtr(aMark,ptr); |
|
183 __LEAVE_IF_ERROR(r); |
|
184 return TStreamPos(ptr-Base()); |
|
185 } |
|
186 |
|
187 void TDesBuf::Consolidate() |
|
188 // |
|
189 // Update the descriptor's length as well as the read limit. |
|
190 // |
|
191 { |
|
192 TUint8* ptr=Ptr(EWrite); |
|
193 if (ptr==NULL) |
|
194 return; // ERead only desbuf |
|
195 TUint8* base=Base(); |
|
196 TInt len=Max(Des().Length(),ptr-base); |
|
197 Des().SetLength(len); |
|
198 SetEnd(ERead,base+len); |
|
199 } |
|
200 |
|
201 EXPORT_C TBufBuf::TBufBuf() |
|
202 : iBuf(NULL) |
|
203 /** Constructs an empty object. |
|
204 |
|
205 Call Set() before using the object. */ |
|
206 {} |
|
207 |
|
208 EXPORT_C void TBufBuf::Set(CBufBase& aBuf,TInt aPos,TInt aMode) |
|
209 /** Sets up the stream to use the specified dynamic buffer. |
|
210 |
|
211 @param aBuf The dynamic buffer that hosts the stream and that also acts as |
|
212 the intermediate buffer. |
|
213 @param aPos The offset within the dynamic buffer where the stream starts. |
|
214 @param aMode The mode in which the stream is to be used. It can be used in |
|
215 either or both read and write modes, represented by ERead and EWrite. In addition, |
|
216 specify TBufBuf::EInsert to imply insert mode; specify TBufBuf::ETruncate |
|
217 to imply truncate mode. If neither TBufBuf::EInsert nor TBufBuf::ETruncate |
|
218 are specified, then overwrite mode is implied. Both TBufBuf::EInsert and TBufBuf::ETruncate |
|
219 imply EWrite. |
|
220 @see CBufBase |
|
221 @see MStreamBuf::TRead |
|
222 @see MStreamBuf::TWrite */ |
|
223 { |
|
224 iBuf=&aBuf; |
|
225 SetPos(ERead|EWrite,aPos); |
|
226 if (aMode&(ETruncate|EInsert)) |
|
227 aMode|=EWrite; // truncate and insert imply write |
|
228 iMode=aMode; |
|
229 //Initialize base class data members. |
|
230 //The first Read/Write call will reinitialize them with non NULL values. |
|
231 TStreamBuf::SetBuf(iMode & (EWrite | ERead), NULL, NULL); |
|
232 } |
|
233 |
|
234 EXPORT_C TInt TBufBuf::UnderflowL(TInt) |
|
235 // |
|
236 // Establish the buffer's read area. |
|
237 // |
|
238 { |
|
239 __ASSERT_ALWAYS(iMode&ERead,Panic(EMemCannotRead)); |
|
240 __ASSERT_DEBUG(Ptr(ERead)==End(ERead),User::Invariant()); |
|
241 TInt pos=Pos(ERead); |
|
242 TPtr8 seg=Buf().Ptr(pos); |
|
243 TUint8* ptr=(TUint8*)seg.Ptr(); |
|
244 TInt len=seg.Length(); |
|
245 if (iMode&ETruncate) |
|
246 { |
|
247 TInt left=Pos(EWrite)-pos; |
|
248 __ASSERT_DEBUG(left>=0,User::Invariant()); |
|
249 if (left<len) |
|
250 len=left; |
|
251 } |
|
252 SetBuf(ERead,ptr,ptr+len); |
|
253 SetPos(ERead,pos+len); |
|
254 return len; |
|
255 } |
|
256 |
|
257 EXPORT_C void TBufBuf::OverflowL() |
|
258 // |
|
259 // Establish the buffer's write area. |
|
260 // |
|
261 { |
|
262 __ASSERT_ALWAYS(iMode&EWrite,Panic(EMemCannotWrite)); |
|
263 __ASSERT_DEBUG(Ptr(EWrite)==End(EWrite)&&Pos(EWrite)<Buf().Size(),User::Invariant()); |
|
264 TInt pos=Pos(EWrite); |
|
265 TPtr8 seg=Buf().Ptr(pos); |
|
266 TUint8* ptr=(TUint8*)seg.Ptr(); |
|
267 TInt len=seg.Length(); |
|
268 SetBuf(EWrite,ptr,ptr+len); |
|
269 SetPos(EWrite,pos+len); |
|
270 } |
|
271 |
|
272 EXPORT_C void TBufBuf::DoSynchL() |
|
273 // |
|
274 // Synchronise buffer and stream buffer and compress. |
|
275 // |
|
276 { |
|
277 Consolidate(); |
|
278 Buf().Compress(); |
|
279 } |
|
280 |
|
281 EXPORT_C void TBufBuf::DoWriteL(const TAny* aPtr,TInt aLength) |
|
282 // |
|
283 // Consume aLength bytes, taking care of any reallocation. |
|
284 // |
|
285 { |
|
286 __ASSERT_ALWAYS(iMode&EWrite,Panic(EMemCannotWrite)); |
|
287 __ASSERT_DEBUG(aLength>=0,Panic(EMemWriteLengthNegative)); |
|
288 __ASSERT_DEBUG(aLength>0,Panic(EMemWriteNoTransfer)); |
|
289 TInt len=(iMode&EInsert?0:Min(aLength,Buf().Size()-Mark(EWrite))); |
|
290 if (len>0) |
|
291 { |
|
292 TStreamBuf::DoWriteL(aPtr,len); |
|
293 aPtr=(TUint8*)aPtr+len; |
|
294 aLength-=len; |
|
295 } |
|
296 if (aLength>0) |
|
297 { |
|
298 Consolidate(); |
|
299 TInt pos=Pos(EWrite); |
|
300 Buf().InsertL(pos,aPtr,aLength); |
|
301 if (Pos(ERead)>pos) |
|
302 MovePos(ERead,aLength); |
|
303 SetPos(EWrite,pos+aLength); |
|
304 } |
|
305 } |
|
306 |
|
307 EXPORT_C TStreamPos TBufBuf::DoSeekL(TMark aMark,TStreamLocation aLocation,TInt anOffset) |
|
308 // |
|
309 // Position the mark(s) indicated by aMark at anOffset from aLocation. |
|
310 // |
|
311 { |
|
312 Consolidate(); |
|
313 TInt size=Buf().Size(); |
|
314 switch (aLocation) |
|
315 { |
|
316 case EStreamBeginning: |
|
317 break; |
|
318 case EStreamMark: |
|
319 anOffset+=Pos(aMark); |
|
320 break; |
|
321 case EStreamEnd: |
|
322 anOffset+=size; |
|
323 break; |
|
324 default: |
|
325 Panic(EMemLocationInvalid); |
|
326 break; |
|
327 } |
|
328 TInt r=KErrNone; |
|
329 if (anOffset>size) |
|
330 { |
|
331 anOffset=size; |
|
332 r=KErrEof; |
|
333 } |
|
334 else if (anOffset<0) |
|
335 { |
|
336 anOffset=0; |
|
337 r=KErrEof; |
|
338 } |
|
339 // |
|
340 SetPos(aMark,anOffset); |
|
341 __LEAVE_IF_ERROR(r); |
|
342 return TStreamPos(anOffset); |
|
343 } |
|
344 |
|
345 void TBufBuf::Consolidate() |
|
346 // |
|
347 // Empty buffer areas and, in truncate mode, cut off at the current write position. |
|
348 // |
|
349 { |
|
350 MovePos(ERead,-Avail(ERead)); |
|
351 MovePos(EWrite,-Avail(EWrite)); |
|
352 SetBuf(ERead|EWrite,NULL,NULL); |
|
353 if (iMode&ETruncate) |
|
354 { |
|
355 Buf().Delete(Pos(EWrite),Buf().Size()-Pos(EWrite)); |
|
356 iMode&=~ETruncate; |
|
357 } |
|
358 } |
|
359 |
|
360 void TBufBuf::SetPos(TMark aMark,TInt aPos) |
|
361 // |
|
362 // Set the buffer position for the mark(s) indicated by aMark |
|
363 // |
|
364 { |
|
365 __ASSERT_ALWAYS(!(aMark&~(ERead|EWrite)),Panic(EMemMarkInvalid)); |
|
366 if (aMark&ERead) |
|
367 SetPos(ERead,aPos); |
|
368 if (aMark&EWrite) |
|
369 SetPos(EWrite,aPos); |
|
370 } |
|
371 |
|
372 TInt TBufBuf::Pos(TMark aMark) const |
|
373 // |
|
374 // Return the buffer position for the mark indicated by aMark. |
|
375 // |
|
376 { |
|
377 if (aMark==ERead) |
|
378 return Pos(ERead); |
|
379 // |
|
380 __ASSERT_ALWAYS(aMark==EWrite,Panic(EMemMarkInvalid)); |
|
381 return Pos(EWrite); |
|
382 } |
|
383 |