diff -r 000000000000 -r 62f9d29f7211 webservices/wsutils/src/sendateutils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webservices/wsutils/src/sendateutils.cpp Thu Jan 07 16:19:19 2010 +0200 @@ -0,0 +1,210 @@ +/* +* Copyright (c) 2002-2005 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: +* +*/ + + + + + + + + +// INCLUDE FILES +#include "SenDateUtils.h" + +namespace + { + _LIT8(KXmlDateTimeFormat8, "%04d-%02d-%02dT%02d:%02d:%02dZ"); // prior WS-* MT / SCT timestamp fix (2006-12-06) => Liberty IOP confirmed + _LIT8(KXmlDateTimeFormat82, "%04d-%02d-%02dT%02d:%02d:%02d.%06dZ"); + } + +EXPORT_C TTime SenDateUtils::FromXmlDateTimeL(const TDesC8& aXmlDateTime) + { + // Format: '2004-01-22T15:31:00Z' or '2004-01-22T15:31:00+02:00' + + TInt year; + TInt month; + TInt day; + TInt hour; + TInt min; + TInt sec; + TInt microsec; + + // Try to leave instead of panic in all places + if(aXmlDateTime.Length() < 20) { User::Leave(KErrUnderflow); } + + TLex8 yearLex(aXmlDateTime.Mid(0, 4)); + User::LeaveIfError(yearLex.Val(year)); + + if(aXmlDateTime[4] != '-') { User::Leave(KErrGeneral); } + + TLex8 monthLex(aXmlDateTime.Mid(5, 2)); + User::LeaveIfError(monthLex.Val(month)); + month--; + if(month < 0) { User::Leave(KErrUnderflow); } + if(month >= 12) { User::Leave(KErrOverflow); } + + if(aXmlDateTime[7] != '-') { User::Leave(KErrGeneral); } + + TLex8 dayLex(aXmlDateTime.Mid(8, 2)); + User::LeaveIfError(dayLex.Val(day)); + day--; + if(day < 0) { User::Leave(KErrUnderflow); } + if(day >= 31) { User::Leave(KErrOverflow); } + + if(aXmlDateTime[10] != 'T') { User::Leave(KErrGeneral); } + + TLex8 hourLex(aXmlDateTime.Mid(11, 2)); + User::LeaveIfError(hourLex.Val(hour)); + if(hour < 0) { User::Leave(KErrUnderflow); } + if(hour >= 24) { User::Leave(KErrOverflow); } + + if(aXmlDateTime[13] != ':') { User::Leave(KErrGeneral); } + + TLex8 minLex(aXmlDateTime.Mid(14, 2)); + User::LeaveIfError(minLex.Val(min)); + if(min < 0) { User::Leave(KErrUnderflow); } + if(min >= 60) { User::Leave(KErrOverflow); } + + if(aXmlDateTime[16] != ':') { User::Leave(KErrGeneral); } + + TLex8 secLex(aXmlDateTime.Mid(17, 2)); + User::LeaveIfError(secLex.Val(sec)); + if(sec < 0) { User::Leave(KErrUnderflow); } + if(sec >= 60) { User::Leave(KErrOverflow); } + + TUint16 nextChar = aXmlDateTime[19]; + TUint16 tzChar = aXmlDateTime[19]; + + TInt i = 19; + while((tzChar != 'Z') && (tzChar != '+') && (tzChar != '-')) + { + i++; + if(i < aXmlDateTime.Length()) tzChar = aXmlDateTime[i]; + else { User::Leave(KErrGeneral); } + } + + if(nextChar == '.') + { + TInt lastMicrosec; + if(i > 26) lastMicrosec = 26; + else lastMicrosec = i; + TLex8 microsecLex(aXmlDateTime.Mid(20, lastMicrosec-20)); + User::LeaveIfError(microsecLex.Val(microsec)); + TInt j = 26; + while (j > lastMicrosec) + { + microsec = microsec * 10; + j--; + } + } + else + { + microsec = 0; + } + + TTime time( + TDateTime( + year, + static_cast(month), + day, + hour, + min, + sec, + microsec + ) + ); + + if(tzChar == 'Z') + { + // UTC + if(aXmlDateTime.Length() > i+1) { User::Leave(KErrOverflow); } + } + else + { + // Time zone info is appended + if(aXmlDateTime.Length() < i+6) { User::Leave(KErrUnderflow); } + if(aXmlDateTime.Length() > i+6) { User::Leave(KErrOverflow); } + TInt tzSign = 0; + if(tzChar == '+') { tzSign = +1; } + if(tzChar == '-') { tzSign = -1; } + if(tzSign == 0) { User::Leave(KErrGeneral); } + + TInt tzHour; + TInt tzMin; + + TLex8 tzHourLex(aXmlDateTime.Mid(i+1, 2)); + User::LeaveIfError(tzHourLex.Val(tzHour)); + if(tzHour < 0) { User::Leave(KErrUnderflow); } + if(tzHour >= 24) { User::Leave(KErrOverflow); } + + if(aXmlDateTime[i+3] != ':') { User::Leave(KErrGeneral); } + + TLex8 tzMinLex(aXmlDateTime.Mid(i+4, 2)); + User::LeaveIfError(tzMinLex.Val(tzMin)); + if(tzMin < 0) { User::Leave(KErrUnderflow); } + if(tzMin >= 60) { User::Leave(KErrOverflow); } + + TInt tzShiftMins = tzSign * (tzMin + tzHour * 60); + time += TTimeIntervalMinutes(tzShiftMins); + } + + return time; + } + +EXPORT_C void SenDateUtils::ToXmlDateTimeUtf8L(TDes8& aDest, const TTime& aSrc) + { + if(aDest.MaxLength() < KXmlDateTimeMaxLength) + { + User::Leave(KErrOverflow); + } + + TDateTime dt = aSrc.DateTime(); + aDest.Format( + KXmlDateTimeFormat8, + dt.Year(), + dt.Month() + 1, + dt.Day() + 1, + dt.Hour(), + dt.Minute(), + dt.Second() + ); +} + + +EXPORT_C void SenDateUtils::ToXmlDateTimeUtf82L(TDes8& aDest, const TTime& aSrc) + { + if(aDest.MaxLength() < KXmlDateTimeMaxLength) + { + User::Leave(KErrOverflow); + } + + TDateTime dt = aSrc.DateTime(); + aDest.Format( + KXmlDateTimeFormat82, + dt.Year(), + dt.Month() + 1, + dt.Day() + 1, + dt.Hour(), + dt.Minute(), + dt.Second(), + dt.MicroSecond() // Added in WS-* MT / SCT fix (2006-12-06) + ); + } + + +// End of File +