realtimenetprots/sipfw/SDP/src/SdpTimeField.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SDP/src/SdpTimeField.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,415 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name          : SdpTimeField.h
+// Part of       : SDP Codec
+// Version       : 1.0
+//
+
+
+
+#include <s32strm.h>
+#include "SdpTimeField.h"
+#include "SdpUtil.h"
+#include "SDPCodec.pan"
+#include "_sdpdefs.h"
+#include "SdpRepeatField.h"
+#include "sdpcodecstringconstants.h"
+#include "SdpDocument.h"
+#include "SdpCodecErr.h"
+#include "SdpCodecConstants.h"
+#include "SdpCodecErr.h"
+#include "SdpCodecStringPool.h"
+
+// LOCAL CONSTANTS
+_LIT8(KZeroTime, "0");
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::DecodeL
+// Decodes time field from TDesC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpTimeField * CSdpTimeField::DecodeL(const TDesC8& aText, 
+                                                TBool aRecurse)
+	{
+	CSdpTimeField* obj = DecodeLC(aText, aRecurse);
+	CleanupStack::Pop();
+	return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::DecodeLC
+// Decodes time field from TDesC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpTimeField * CSdpTimeField::DecodeLC(const TDesC8& aText, 
+                                                TBool aRecurse)
+	{
+	CSdpTimeField* obj = new (ELeave) CSdpTimeField();
+	CleanupStack::PushL(obj);
+	obj->ConstructL(aText, aRecurse);
+	return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::NewL
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+EXPORT_C CSdpTimeField * CSdpTimeField::NewL(const TDesC8& aStartTime, 
+                                             const TDesC8& aStopTime)
+	{
+	CSdpTimeField* obj = NewLC(aStartTime, aStopTime);
+	CleanupStack::Pop();
+	return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::NewLC
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+EXPORT_C CSdpTimeField * CSdpTimeField::NewLC(const TDesC8& aStartTime, 
+                                              const TDesC8& aStopTime)
+	{
+	CSdpTimeField* obj = new (ELeave) CSdpTimeField();
+	CleanupStack::PushL(obj);
+	obj->ConstructL(aStartTime, aStopTime);
+	return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::~CSdpTimeField
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpTimeField::~CSdpTimeField ()
+	{
+	iRFields.ResetAndDestroy();
+	delete iStopTime;
+	delete iStartTime;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::EncodeL
+// Writes attributes in proper format to the stream
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSdpTimeField::EncodeL(RWriteStream& aStream, 
+                                     TBool aRecurse) const
+	{
+	__ASSERT_ALWAYS(this->IsValid(), User::Leave(KErrNotReady));
+    const TDesC8& timeName = iStringPool.StringF(SdpCodecStringConstants::ETime, 
+                                        SdpCodecStringConstants::Table).DesC();
+    aStream.WriteL(timeName);
+    aStream.WriteL(*iStartTime);
+    aStream.WriteL(KSPStr);
+    aStream.WriteL(*iStopTime);
+    aStream.WriteL(KCRLFStr);
+    if (aRecurse)
+        {
+        for(TInt i=0; i<iRFields.Count(); i++)
+            {
+            iRFields[i]->EncodeL(aStream);
+            }
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::CloneL
+// Creates an exact copy of the time field
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpTimeField* CSdpTimeField::CloneL(TBool aRecurse) const
+	{
+    CSdpTimeField* obj = CSdpTimeField::NewLC(*this->iStartTime, 
+                                            *this->iStopTime);
+	__TEST_INVARIANT;
+    if (aRecurse)
+        {
+        for (TInt i = 0; i < iRFields.Count(); i++)
+            {
+            CSdpRepeatField* repObj = iRFields[i]->CloneL();
+            CleanupStack::PushL(repObj);
+            User::LeaveIfError(obj->RepeatFields().Append(repObj));
+            CleanupStack::Pop(); // repObj
+            }
+        }
+    CleanupStack::Pop(); //obj
+    return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::operator ==
+// Checks if two time fields are equal
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSdpTimeField::operator == (const CSdpTimeField & aObj) const
+	{
+	__TEST_INVARIANT;
+    return (aObj.StartTime().Compare(this->StartTime()) == 0
+            &&  aObj.StopTime().Compare(this->StopTime()) == 0
+            && RepeatFieldsCompare(aObj));
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::IsValid
+// Checks if start time and stop time are valid
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSdpTimeField::IsValid() const
+    {
+    return 	( (iStartTime->Match(KZeroTime) 
+                && iStopTime->Match(KZeroTime)) 
+            || (iStartTime->Length() != 0 
+                && iStopTime->Length() != 0
+				&& *iStartTime <= *iStopTime));
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::StartTime
+// Returns start time 
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CSdpTimeField::StartTime() const
+	{
+	__TEST_INVARIANT;
+	return *iStartTime;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::StopTime
+// Returns stop time 
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CSdpTimeField::StopTime() const
+	{
+	__TEST_INVARIANT;
+	return *iStopTime;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::SetTimesL
+// Sets start time and stop time if they are valid ones 
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSdpTimeField::SetTimesL(const TDesC8& aStartTime, 
+                                       const TDesC8& aStopTime)
+	{
+	__ASSERT_ALWAYS(
+        (aStartTime.Length() == 1 && aStartTime[0] -'0' == 0
+            && ((aStopTime.Length() == 1 && aStopTime[0] -'0' == 0)
+                || (aStopTime.Length() > 1 
+                    && SdpUtil::IsValidNtpTime(aStopTime))))
+        || (aStartTime.Length() > 1 && SdpUtil::IsValidNtpTime(aStartTime)
+            && aStopTime.Length() > 1 && SdpUtil::IsValidNtpTime(aStopTime)
+            && aStartTime < aStopTime),
+        User::Leave(KErrSdpCodecTimeField));
+    
+    HBufC8* tmpStartTime = aStartTime.AllocL();
+    CleanupStack::PushL(tmpStartTime);
+    HBufC8* tmpStopTime = aStopTime.AllocL();
+	
+    tmpStartTime->Des().Trim();
+	delete iStartTime;
+	iStartTime = tmpStartTime;
+	tmpStopTime->Des().Trim();
+	delete iStopTime;
+	iStopTime = tmpStopTime;
+
+    CleanupStack::Pop(); // tmpStartTime
+	__TEST_INVARIANT;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::RepeatFields
+// Returns repeat fields
+// -----------------------------------------------------------------------------
+//
+EXPORT_C RPointerArray<CSdpRepeatField>& CSdpTimeField::RepeatFields()
+	{
+	__TEST_INVARIANT;
+	return iRFields;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::ExternalizeL
+// Externalizes the object to stream
+// -----------------------------------------------------------------------------
+//
+void CSdpTimeField::ExternalizeL(RWriteStream& aStream) const
+    {
+   	__TEST_INVARIANT;
+    aStream.WriteUint32L(iStartTime->Length());
+    aStream.WriteL(*iStartTime);
+    aStream.WriteUint32L(iStopTime->Length());
+    aStream.WriteL(*iStopTime);
+    aStream.WriteUint32L(iRFields.Count());
+    for(TInt i=0; i<iRFields.Count(); i++)
+       {
+       iRFields[i]->ExternalizeL(aStream);
+       }
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::InternalizeL
+// Internalizes the object from stream
+// -----------------------------------------------------------------------------
+//
+CSdpTimeField* CSdpTimeField::InternalizeL(RReadStream& aStream)
+    {
+    CSdpTimeField* self = new (ELeave) CSdpTimeField();
+    CleanupStack::PushL(self);
+    self->iStringPool = SdpCodecStringPool::StringPoolL();
+
+    self->DoInternalizeL(aStream);
+
+    CleanupStack::Pop(); //self
+
+    return self; 
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::DoInternalizeL
+// Internalizes the object members from stream
+// -----------------------------------------------------------------------------
+//
+void CSdpTimeField::DoInternalizeL(RReadStream& aStream)
+    {
+    
+    TUint32 valueLength = aStream.ReadUint32L();
+	iStartTime = HBufC8::NewL (valueLength);
+	TPtr8 startTime(iStartTime->Des());
+	aStream.ReadL (startTime,valueLength);
+    valueLength = aStream.ReadUint32L();
+	iStopTime = HBufC8::NewL (valueLength);
+	TPtr8 stopTime(iStopTime->Des());
+	aStream.ReadL (stopTime,valueLength);
+    
+    TUint rFieldsCount = aStream.ReadUint32L();
+    for (TUint i = 0; i < rFieldsCount; i++)
+        {
+        CSdpRepeatField* rField = CSdpRepeatField::InternalizeL(aStream);
+        CleanupStack::PushL(rField);
+        User::LeaveIfError(iRFields.Append(rField));
+        CleanupStack::Pop(); //rField
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::CSdpTimeField
+// Constructor
+// -----------------------------------------------------------------------------
+//
+CSdpTimeField::CSdpTimeField()
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSdpTimeField::ConstructL(const TDesC8& aText, TBool aRecurse)
+	{
+    iStringPool = SdpCodecStringPool::StringPoolL();
+    RArray <TPtrC8> lines;
+    lines = SdpUtil::DivideToLinesL(aText, KErrSdpCodecTimeField);
+    CleanupClosePushL(lines);
+    RArray<TPtrC8> timeArray;
+    timeArray = SdpUtil::GetElementsFromLineL(lines[0], KErrSdpCodecTimeField);
+    CleanupClosePushL(timeArray);
+    const TDesC8& timeName = iStringPool.StringF(SdpCodecStringConstants::ETime, 
+        SdpCodecStringConstants::Table).DesC();        
+    __ASSERT_ALWAYS(lines.Count() > 0
+                    && timeArray.Count() == 3
+                    && timeArray[0].Find(timeName) != KErrNotFound,
+                    User::Leave(KErrSdpCodecTimeField));
+
+    SetTimesL(timeArray[1], timeArray[2]);
+
+    if (aRecurse && lines.Count() > 1)
+        {
+        const TDesC8& repeatName = 
+                    iStringPool.StringF(SdpCodecStringConstants::ERepeat,
+                               SdpCodecStringConstants::Table).DesC();   
+        for( TInt i = 1; i<lines.Count(); i++)
+            {
+            RArray<TPtrC8> lineArray;
+            lineArray = SdpUtil::GetElementsFromLineL(lines[i], KErrSdpCodecTimeField);
+            CleanupClosePushL(lineArray);
+            __ASSERT_ALWAYS(lineArray[0].Find(repeatName) != KErrNotFound,
+                User::Leave(KErrSdpCodecTimeField));
+            CSdpRepeatField* repeatField = CSdpRepeatField::DecodeL(lines[i]);
+            CleanupStack::PushL(repeatField);
+            User::LeaveIfError(iRFields.Append(repeatField));
+            CleanupStack::Pop(); // repeatField
+            CleanupStack::PopAndDestroy(); //lineArray
+            }
+        }
+    CleanupStack::PopAndDestroy(2); // timeArray, lines
+    __TEST_INVARIANT;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSdpTimeField::ConstructL(const TDesC8& aStartTime, 
+                               const TDesC8& aStopTime)
+	{
+    iStringPool = SdpCodecStringPool::StringPoolL();
+ 	SetTimesL(aStartTime, aStopTime);
+	__TEST_INVARIANT;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::RepeatFieldsCompare
+// Checks if two time field objects repeat fields are equal 
+// -----------------------------------------------------------------------------
+//
+TBool CSdpTimeField::RepeatFieldsCompare(const CSdpTimeField& aObj) const
+    {
+    TBool returnValue = ETrue;
+    if (iRFields.Count() == aObj.iRFields.Count())
+        {
+        for (TInt i = 0; i < iRFields.Count() && returnValue; i++)
+            {
+            if (!(*iRFields[i] == *aObj.iRFields[i]))
+                returnValue = EFalse;
+            }
+        }
+    
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpTimeField::__DbgTestInvariant
+// Test invariant
+// -----------------------------------------------------------------------------
+//
+void CSdpTimeField::__DbgTestInvariant() const
+	{
+    TBool invariant = 
+        ((iStartTime->Length() == 1 && (iStartTime->Des())[0] -'0' == 0)
+            && ((iStopTime->Length() == 1 && (iStopTime->Des())[0] -'0' == 0)
+                || (iStopTime->Length() > 1 
+                    && SdpUtil::IsValidNtpTime(*iStopTime))))
+        || (iStartTime->Length() > 1 && SdpUtil::IsValidNtpTime(*iStartTime)
+            && iStopTime->Length() > 1 && SdpUtil::IsValidNtpTime(*iStopTime)
+            && *iStartTime < *iStopTime);
+
+	if (!invariant)
+		User::Invariant();
+	}
+
+