diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SDP/src/SdpTimeField.cpp --- /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 +#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; iEncodeL(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& 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; iExternalizeL(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 lines; + lines = SdpUtil::DivideToLinesL(aText, KErrSdpCodecTimeField); + CleanupClosePushL(lines); + RArray 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 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(); + } + +