|
1 // Copyright (c) 2003-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 // Name : SdpTimeField.h |
|
15 // Part of : SDP Codec |
|
16 // Version : 1.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include <s32strm.h> |
|
22 #include "SdpTimeField.h" |
|
23 #include "SdpUtil.h" |
|
24 #include "SDPCodec.pan" |
|
25 #include "_sdpdefs.h" |
|
26 #include "SdpRepeatField.h" |
|
27 #include "sdpcodecstringconstants.h" |
|
28 #include "SdpDocument.h" |
|
29 #include "SdpCodecErr.h" |
|
30 #include "SdpCodecConstants.h" |
|
31 #include "SdpCodecErr.h" |
|
32 #include "SdpCodecStringPool.h" |
|
33 |
|
34 // LOCAL CONSTANTS |
|
35 _LIT8(KZeroTime, "0"); |
|
36 |
|
37 // ----------------------------------------------------------------------------- |
|
38 // CSdpTimeField::DecodeL |
|
39 // Decodes time field from TDesC |
|
40 // ----------------------------------------------------------------------------- |
|
41 // |
|
42 EXPORT_C CSdpTimeField * CSdpTimeField::DecodeL(const TDesC8& aText, |
|
43 TBool aRecurse) |
|
44 { |
|
45 CSdpTimeField* obj = DecodeLC(aText, aRecurse); |
|
46 CleanupStack::Pop(); |
|
47 return obj; |
|
48 } |
|
49 |
|
50 // ----------------------------------------------------------------------------- |
|
51 // CSdpTimeField::DecodeLC |
|
52 // Decodes time field from TDesC |
|
53 // ----------------------------------------------------------------------------- |
|
54 // |
|
55 EXPORT_C CSdpTimeField * CSdpTimeField::DecodeLC(const TDesC8& aText, |
|
56 TBool aRecurse) |
|
57 { |
|
58 CSdpTimeField* obj = new (ELeave) CSdpTimeField(); |
|
59 CleanupStack::PushL(obj); |
|
60 obj->ConstructL(aText, aRecurse); |
|
61 return obj; |
|
62 } |
|
63 |
|
64 // ----------------------------------------------------------------------------- |
|
65 // CSdpTimeField::NewL |
|
66 // Two-phased constructor |
|
67 // ----------------------------------------------------------------------------- |
|
68 EXPORT_C CSdpTimeField * CSdpTimeField::NewL(const TDesC8& aStartTime, |
|
69 const TDesC8& aStopTime) |
|
70 { |
|
71 CSdpTimeField* obj = NewLC(aStartTime, aStopTime); |
|
72 CleanupStack::Pop(); |
|
73 return obj; |
|
74 } |
|
75 |
|
76 // ----------------------------------------------------------------------------- |
|
77 // CSdpTimeField::NewLC |
|
78 // Two-phased constructor |
|
79 // ----------------------------------------------------------------------------- |
|
80 EXPORT_C CSdpTimeField * CSdpTimeField::NewLC(const TDesC8& aStartTime, |
|
81 const TDesC8& aStopTime) |
|
82 { |
|
83 CSdpTimeField* obj = new (ELeave) CSdpTimeField(); |
|
84 CleanupStack::PushL(obj); |
|
85 obj->ConstructL(aStartTime, aStopTime); |
|
86 return obj; |
|
87 } |
|
88 |
|
89 // ----------------------------------------------------------------------------- |
|
90 // CSdpTimeField::~CSdpTimeField |
|
91 // Destructor |
|
92 // ----------------------------------------------------------------------------- |
|
93 // |
|
94 EXPORT_C CSdpTimeField::~CSdpTimeField () |
|
95 { |
|
96 iRFields.ResetAndDestroy(); |
|
97 delete iStopTime; |
|
98 delete iStartTime; |
|
99 } |
|
100 |
|
101 // ----------------------------------------------------------------------------- |
|
102 // CSdpTimeField::EncodeL |
|
103 // Writes attributes in proper format to the stream |
|
104 // ----------------------------------------------------------------------------- |
|
105 // |
|
106 EXPORT_C void CSdpTimeField::EncodeL(RWriteStream& aStream, |
|
107 TBool aRecurse) const |
|
108 { |
|
109 __ASSERT_ALWAYS(this->IsValid(), User::Leave(KErrNotReady)); |
|
110 const TDesC8& timeName = iStringPool.StringF(SdpCodecStringConstants::ETime, |
|
111 SdpCodecStringConstants::Table).DesC(); |
|
112 aStream.WriteL(timeName); |
|
113 aStream.WriteL(*iStartTime); |
|
114 aStream.WriteL(KSPStr); |
|
115 aStream.WriteL(*iStopTime); |
|
116 aStream.WriteL(KCRLFStr); |
|
117 if (aRecurse) |
|
118 { |
|
119 for(TInt i=0; i<iRFields.Count(); i++) |
|
120 { |
|
121 iRFields[i]->EncodeL(aStream); |
|
122 } |
|
123 } |
|
124 } |
|
125 |
|
126 // ----------------------------------------------------------------------------- |
|
127 // CSdpTimeField::CloneL |
|
128 // Creates an exact copy of the time field |
|
129 // ----------------------------------------------------------------------------- |
|
130 // |
|
131 EXPORT_C CSdpTimeField* CSdpTimeField::CloneL(TBool aRecurse) const |
|
132 { |
|
133 CSdpTimeField* obj = CSdpTimeField::NewLC(*this->iStartTime, |
|
134 *this->iStopTime); |
|
135 __TEST_INVARIANT; |
|
136 if (aRecurse) |
|
137 { |
|
138 for (TInt i = 0; i < iRFields.Count(); i++) |
|
139 { |
|
140 CSdpRepeatField* repObj = iRFields[i]->CloneL(); |
|
141 CleanupStack::PushL(repObj); |
|
142 User::LeaveIfError(obj->RepeatFields().Append(repObj)); |
|
143 CleanupStack::Pop(); // repObj |
|
144 } |
|
145 } |
|
146 CleanupStack::Pop(); //obj |
|
147 return obj; |
|
148 } |
|
149 |
|
150 // ----------------------------------------------------------------------------- |
|
151 // CSdpTimeField::operator == |
|
152 // Checks if two time fields are equal |
|
153 // ----------------------------------------------------------------------------- |
|
154 // |
|
155 EXPORT_C TBool CSdpTimeField::operator == (const CSdpTimeField & aObj) const |
|
156 { |
|
157 __TEST_INVARIANT; |
|
158 return (aObj.StartTime().Compare(this->StartTime()) == 0 |
|
159 && aObj.StopTime().Compare(this->StopTime()) == 0 |
|
160 && RepeatFieldsCompare(aObj)); |
|
161 } |
|
162 |
|
163 // ----------------------------------------------------------------------------- |
|
164 // CSdpTimeField::IsValid |
|
165 // Checks if start time and stop time are valid |
|
166 // ----------------------------------------------------------------------------- |
|
167 // |
|
168 EXPORT_C TBool CSdpTimeField::IsValid() const |
|
169 { |
|
170 return ( (iStartTime->Match(KZeroTime) |
|
171 && iStopTime->Match(KZeroTime)) |
|
172 || (iStartTime->Length() != 0 |
|
173 && iStopTime->Length() != 0 |
|
174 && *iStartTime <= *iStopTime)); |
|
175 } |
|
176 |
|
177 // ----------------------------------------------------------------------------- |
|
178 // CSdpTimeField::StartTime |
|
179 // Returns start time |
|
180 // ----------------------------------------------------------------------------- |
|
181 // |
|
182 EXPORT_C const TDesC8& CSdpTimeField::StartTime() const |
|
183 { |
|
184 __TEST_INVARIANT; |
|
185 return *iStartTime; |
|
186 } |
|
187 |
|
188 // ----------------------------------------------------------------------------- |
|
189 // CSdpTimeField::StopTime |
|
190 // Returns stop time |
|
191 // ----------------------------------------------------------------------------- |
|
192 // |
|
193 EXPORT_C const TDesC8& CSdpTimeField::StopTime() const |
|
194 { |
|
195 __TEST_INVARIANT; |
|
196 return *iStopTime; |
|
197 } |
|
198 |
|
199 // ----------------------------------------------------------------------------- |
|
200 // CSdpTimeField::SetTimesL |
|
201 // Sets start time and stop time if they are valid ones |
|
202 // ----------------------------------------------------------------------------- |
|
203 // |
|
204 EXPORT_C void CSdpTimeField::SetTimesL(const TDesC8& aStartTime, |
|
205 const TDesC8& aStopTime) |
|
206 { |
|
207 __ASSERT_ALWAYS( |
|
208 (aStartTime.Length() == 1 && aStartTime[0] -'0' == 0 |
|
209 && ((aStopTime.Length() == 1 && aStopTime[0] -'0' == 0) |
|
210 || (aStopTime.Length() > 1 |
|
211 && SdpUtil::IsValidNtpTime(aStopTime)))) |
|
212 || (aStartTime.Length() > 1 && SdpUtil::IsValidNtpTime(aStartTime) |
|
213 && aStopTime.Length() > 1 && SdpUtil::IsValidNtpTime(aStopTime) |
|
214 && aStartTime < aStopTime), |
|
215 User::Leave(KErrSdpCodecTimeField)); |
|
216 |
|
217 HBufC8* tmpStartTime = aStartTime.AllocL(); |
|
218 CleanupStack::PushL(tmpStartTime); |
|
219 HBufC8* tmpStopTime = aStopTime.AllocL(); |
|
220 |
|
221 tmpStartTime->Des().Trim(); |
|
222 delete iStartTime; |
|
223 iStartTime = tmpStartTime; |
|
224 tmpStopTime->Des().Trim(); |
|
225 delete iStopTime; |
|
226 iStopTime = tmpStopTime; |
|
227 |
|
228 CleanupStack::Pop(); // tmpStartTime |
|
229 __TEST_INVARIANT; |
|
230 } |
|
231 |
|
232 // ----------------------------------------------------------------------------- |
|
233 // CSdpTimeField::RepeatFields |
|
234 // Returns repeat fields |
|
235 // ----------------------------------------------------------------------------- |
|
236 // |
|
237 EXPORT_C RPointerArray<CSdpRepeatField>& CSdpTimeField::RepeatFields() |
|
238 { |
|
239 __TEST_INVARIANT; |
|
240 return iRFields; |
|
241 } |
|
242 |
|
243 // ----------------------------------------------------------------------------- |
|
244 // CSdpTimeField::ExternalizeL |
|
245 // Externalizes the object to stream |
|
246 // ----------------------------------------------------------------------------- |
|
247 // |
|
248 void CSdpTimeField::ExternalizeL(RWriteStream& aStream) const |
|
249 { |
|
250 __TEST_INVARIANT; |
|
251 aStream.WriteUint32L(iStartTime->Length()); |
|
252 aStream.WriteL(*iStartTime); |
|
253 aStream.WriteUint32L(iStopTime->Length()); |
|
254 aStream.WriteL(*iStopTime); |
|
255 aStream.WriteUint32L(iRFields.Count()); |
|
256 for(TInt i=0; i<iRFields.Count(); i++) |
|
257 { |
|
258 iRFields[i]->ExternalizeL(aStream); |
|
259 } |
|
260 } |
|
261 |
|
262 // ----------------------------------------------------------------------------- |
|
263 // CSdpTimeField::InternalizeL |
|
264 // Internalizes the object from stream |
|
265 // ----------------------------------------------------------------------------- |
|
266 // |
|
267 CSdpTimeField* CSdpTimeField::InternalizeL(RReadStream& aStream) |
|
268 { |
|
269 CSdpTimeField* self = new (ELeave) CSdpTimeField(); |
|
270 CleanupStack::PushL(self); |
|
271 self->iStringPool = SdpCodecStringPool::StringPoolL(); |
|
272 |
|
273 self->DoInternalizeL(aStream); |
|
274 |
|
275 CleanupStack::Pop(); //self |
|
276 |
|
277 return self; |
|
278 } |
|
279 |
|
280 // ----------------------------------------------------------------------------- |
|
281 // CSdpTimeField::DoInternalizeL |
|
282 // Internalizes the object members from stream |
|
283 // ----------------------------------------------------------------------------- |
|
284 // |
|
285 void CSdpTimeField::DoInternalizeL(RReadStream& aStream) |
|
286 { |
|
287 |
|
288 TUint32 valueLength = aStream.ReadUint32L(); |
|
289 iStartTime = HBufC8::NewL (valueLength); |
|
290 TPtr8 startTime(iStartTime->Des()); |
|
291 aStream.ReadL (startTime,valueLength); |
|
292 valueLength = aStream.ReadUint32L(); |
|
293 iStopTime = HBufC8::NewL (valueLength); |
|
294 TPtr8 stopTime(iStopTime->Des()); |
|
295 aStream.ReadL (stopTime,valueLength); |
|
296 |
|
297 TUint rFieldsCount = aStream.ReadUint32L(); |
|
298 for (TUint i = 0; i < rFieldsCount; i++) |
|
299 { |
|
300 CSdpRepeatField* rField = CSdpRepeatField::InternalizeL(aStream); |
|
301 CleanupStack::PushL(rField); |
|
302 User::LeaveIfError(iRFields.Append(rField)); |
|
303 CleanupStack::Pop(); //rField |
|
304 } |
|
305 } |
|
306 |
|
307 // ----------------------------------------------------------------------------- |
|
308 // CSdpTimeField::CSdpTimeField |
|
309 // Constructor |
|
310 // ----------------------------------------------------------------------------- |
|
311 // |
|
312 CSdpTimeField::CSdpTimeField() |
|
313 { |
|
314 } |
|
315 |
|
316 // ----------------------------------------------------------------------------- |
|
317 // CSdpTimeField::ConstructL |
|
318 // Symbian 2nd phase constructor can leave. |
|
319 // ----------------------------------------------------------------------------- |
|
320 // |
|
321 void CSdpTimeField::ConstructL(const TDesC8& aText, TBool aRecurse) |
|
322 { |
|
323 iStringPool = SdpCodecStringPool::StringPoolL(); |
|
324 RArray <TPtrC8> lines; |
|
325 lines = SdpUtil::DivideToLinesL(aText, KErrSdpCodecTimeField); |
|
326 CleanupClosePushL(lines); |
|
327 RArray<TPtrC8> timeArray; |
|
328 timeArray = SdpUtil::GetElementsFromLineL(lines[0], KErrSdpCodecTimeField); |
|
329 CleanupClosePushL(timeArray); |
|
330 const TDesC8& timeName = iStringPool.StringF(SdpCodecStringConstants::ETime, |
|
331 SdpCodecStringConstants::Table).DesC(); |
|
332 __ASSERT_ALWAYS(lines.Count() > 0 |
|
333 && timeArray.Count() == 3 |
|
334 && timeArray[0].Find(timeName) != KErrNotFound, |
|
335 User::Leave(KErrSdpCodecTimeField)); |
|
336 |
|
337 SetTimesL(timeArray[1], timeArray[2]); |
|
338 |
|
339 if (aRecurse && lines.Count() > 1) |
|
340 { |
|
341 const TDesC8& repeatName = |
|
342 iStringPool.StringF(SdpCodecStringConstants::ERepeat, |
|
343 SdpCodecStringConstants::Table).DesC(); |
|
344 for( TInt i = 1; i<lines.Count(); i++) |
|
345 { |
|
346 RArray<TPtrC8> lineArray; |
|
347 lineArray = SdpUtil::GetElementsFromLineL(lines[i], KErrSdpCodecTimeField); |
|
348 CleanupClosePushL(lineArray); |
|
349 __ASSERT_ALWAYS(lineArray[0].Find(repeatName) != KErrNotFound, |
|
350 User::Leave(KErrSdpCodecTimeField)); |
|
351 CSdpRepeatField* repeatField = CSdpRepeatField::DecodeL(lines[i]); |
|
352 CleanupStack::PushL(repeatField); |
|
353 User::LeaveIfError(iRFields.Append(repeatField)); |
|
354 CleanupStack::Pop(); // repeatField |
|
355 CleanupStack::PopAndDestroy(); //lineArray |
|
356 } |
|
357 } |
|
358 CleanupStack::PopAndDestroy(2); // timeArray, lines |
|
359 __TEST_INVARIANT; |
|
360 } |
|
361 |
|
362 // ----------------------------------------------------------------------------- |
|
363 // CSdpTimeField::ConstructL |
|
364 // Symbian 2nd phase constructor can leave. |
|
365 // ----------------------------------------------------------------------------- |
|
366 // |
|
367 void CSdpTimeField::ConstructL(const TDesC8& aStartTime, |
|
368 const TDesC8& aStopTime) |
|
369 { |
|
370 iStringPool = SdpCodecStringPool::StringPoolL(); |
|
371 SetTimesL(aStartTime, aStopTime); |
|
372 __TEST_INVARIANT; |
|
373 } |
|
374 |
|
375 // ----------------------------------------------------------------------------- |
|
376 // CSdpTimeField::RepeatFieldsCompare |
|
377 // Checks if two time field objects repeat fields are equal |
|
378 // ----------------------------------------------------------------------------- |
|
379 // |
|
380 TBool CSdpTimeField::RepeatFieldsCompare(const CSdpTimeField& aObj) const |
|
381 { |
|
382 TBool returnValue = ETrue; |
|
383 if (iRFields.Count() == aObj.iRFields.Count()) |
|
384 { |
|
385 for (TInt i = 0; i < iRFields.Count() && returnValue; i++) |
|
386 { |
|
387 if (!(*iRFields[i] == *aObj.iRFields[i])) |
|
388 returnValue = EFalse; |
|
389 } |
|
390 } |
|
391 |
|
392 return returnValue; |
|
393 } |
|
394 |
|
395 // ----------------------------------------------------------------------------- |
|
396 // CSdpTimeField::__DbgTestInvariant |
|
397 // Test invariant |
|
398 // ----------------------------------------------------------------------------- |
|
399 // |
|
400 void CSdpTimeField::__DbgTestInvariant() const |
|
401 { |
|
402 TBool invariant = |
|
403 ((iStartTime->Length() == 1 && (iStartTime->Des())[0] -'0' == 0) |
|
404 && ((iStopTime->Length() == 1 && (iStopTime->Des())[0] -'0' == 0) |
|
405 || (iStopTime->Length() > 1 |
|
406 && SdpUtil::IsValidNtpTime(*iStopTime)))) |
|
407 || (iStartTime->Length() > 1 && SdpUtil::IsValidNtpTime(*iStartTime) |
|
408 && iStopTime->Length() > 1 && SdpUtil::IsValidNtpTime(*iStopTime) |
|
409 && *iStartTime < *iStopTime); |
|
410 |
|
411 if (!invariant) |
|
412 User::Invariant(); |
|
413 } |
|
414 |
|
415 |