jsun%netscape.com d9b95f11c1 Renamed several classes that had Julian in front.
Changed them to nsCal.
i.e. Julian_Duration -> nsCalDuration.
     JulianRecurrenceID -> nsCalRecurrenceID.


git-svn-id: svn://10.0.0.236/trunk@11263 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-28 20:46:22 +00:00

731 lines
21 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// duration.cpp
// John Sun
// 5:52 PM January 28 1998
#include "stdafx.h"
#include "jdefines.h"
#include <assert.h>
#include <ptypes.h>
#include <unistring.h>
#include "duration.h"
#include "jutility.h"
// turn this flag on to allow for parsing of year and month
#define NSCALDURATION_PARSING_YEAR_AND_MONTH 1
//---------------------------------------------------------------------
void nsCalDuration::setInvalidDuration()
{
m_iYear = -1;
m_iMonth = -1;
m_iDay = -1;
m_iHour = -1;
m_iMinute = -1;
m_iSecond = -1;
m_iWeek = -1;
}
//---------------------------------------------------------------------
void nsCalDuration::parse(UnicodeString & us)
{
// NOTE: use a better algorithm like a regexp scanf or something.
UnicodeString sVal;
UnicodeString sSection;
t_bool bErrorInParse = FALSE;
t_int32 startOfParse = 0, indexOfT = 0, endOfParse = 0;
t_int32 day = 0, hour = 0, minute = 0, second = 0, week = 0;
#if NSCALDURATION_PARSING_YEAR_AND_MONTH
t_int32 year = 0, month = 0;
t_int32 indexOfY = 0, indexOfMo = 0;
#endif
t_int32 indexOfD = 0;
t_int32 indexOfH = 0, indexOfMi = 0, indexOfS = 0, indexOfW = 0;
char * cc = 0;
if (us[(TextOffset) 0] != 'P') //!us.startsWith(s_sP))
{
if ('-' == us[(TextOffset) 0] && ('P' == us[(TextOffset) 1]))
{
m_NegativeDuration = TRUE;
startOfParse = 1;
}
else if ('+' == us[(TextOffset) 0] && ('P' == us[(TextOffset) 1]))
{
m_NegativeDuration = FALSE;
startOfParse = 1;
}
else
bErrorInParse = TRUE;
}
if (!bErrorInParse)
{
startOfParse++;
indexOfT = us.indexOf('T');
endOfParse = us.size();
indexOfW = us.indexOf('W');
if (indexOfW == -1)
{
// first parse the date section
if (indexOfT > 0)
{
endOfParse = indexOfT;
}
sSection = us.extractBetween(startOfParse, endOfParse, sSection);
startOfParse = 0;
endOfParse = sSection.size();
#if NSCALDURATION_PARSING_YEAR_AND_MONTH
indexOfY = sSection.indexOf('Y');
if (indexOfY >= 0)
{
sVal = sSection.extractBetween(startOfParse, indexOfY, sVal);
cc = sVal.toCString("");
PR_ASSERT(cc != 0);
year = nsCalUtility::atot_int32(cc,
bErrorInParse, sVal.size());
delete [] cc;
startOfParse = indexOfY + 1;
}
indexOfMo = sSection.indexOf('M');
if (indexOfMo >= 0)
{
sVal = sSection.extractBetween(startOfParse, indexOfMo, sVal);
cc = sVal.toCString("");
PR_ASSERT(cc != 0);
month = nsCalUtility::atot_int32(cc,
bErrorInParse, sVal.size());
delete [] cc;
startOfParse = indexOfMo + 1;
}
#endif
indexOfD = sSection.indexOf('D');
if (indexOfD >= 0)
{
sVal = sSection.extractBetween(startOfParse, indexOfD, sVal);
cc = sVal.toCString("");
PR_ASSERT(cc != 0);
day = nsCalUtility::atot_int32(cc,
bErrorInParse, sVal.size());
delete [] cc;
startOfParse = indexOfD + 1;
}
#if NSCALDURATION_PARSING_YEAR_AND_MONTH
if (sSection.size() >= 1 && indexOfY == -1 &&
indexOfMo == -1 && indexOfD == -1)
{
bErrorInParse = TRUE;
}
else if (indexOfY != -1 && indexOfMo != -1 && indexOfY > indexOfMo)
bErrorInParse = TRUE;
else if (indexOfY != -1 && indexOfD != -1 && indexOfY > indexOfD)
bErrorInParse = TRUE;
else if (indexOfMo != -1 && indexOfD != -1 && indexOfMo > indexOfD)
bErrorInParse = TRUE;
else if (indexOfD != -1 && indexOfD != endOfParse -1)
bErrorInParse = TRUE;
else if (indexOfMo != -1 && indexOfD == -1 && indexOfMo != endOfParse -1)
bErrorInParse = TRUE;
else if (indexOfY != -1 && indexOfD == -1 && indexOfMo == -1 && indexOfY != endOfParse -1)
bErrorInParse = TRUE;
#else
if (sSection.size() >= 1 && indexOfD == -1)
{
bErrorInParse = TRUE;
}
else if (indexOfD != -1 && indexOfD != endOfParse -1)
bErrorInParse = TRUE;
#endif
// now parse time section
if (indexOfT > 0)
{
startOfParse = indexOfT + 1;
endOfParse = us.size();
sSection = us.extractBetween(startOfParse, endOfParse, sSection);
startOfParse = 0;
endOfParse = sSection.size();
indexOfH = sSection.indexOf('H');
if (indexOfH >= 0) {
sVal = sSection.extractBetween(startOfParse, indexOfH, sVal);
cc = sVal.toCString("");
PR_ASSERT(cc != 0);
hour = nsCalUtility::atot_int32(cc,
bErrorInParse, sVal.size());
delete [] cc;
startOfParse = indexOfH + 1;
}
indexOfMi = sSection.indexOf('M');
if (indexOfMi >= 0) {
sVal = sSection.extractBetween(startOfParse, indexOfMi, sVal);
cc = sVal.toCString("");
PR_ASSERT(cc != 0);
minute = nsCalUtility::atot_int32(cc,
bErrorInParse, sVal.size());
delete [] cc;
startOfParse = indexOfMi + 1;
}
indexOfS = sSection.indexOf('S');
if (indexOfS >= 0)
{
sVal = sSection.extractBetween(startOfParse, indexOfS, sVal);
cc = sVal.toCString("");
PR_ASSERT(cc != 0);
second = nsCalUtility::atot_int32(cc,
bErrorInParse, sVal.size());
delete [] cc;
startOfParse = indexOfS + 1;
}
if (sSection.size() > 0 && indexOfH == -1 &&
indexOfMi == -1 && indexOfS == -1)
{
bErrorInParse = TRUE;
}
else if (indexOfH != -1 && indexOfMi != -1 && indexOfH > indexOfMi)
bErrorInParse = TRUE;
else if (indexOfH != -1 && indexOfS != -1 && indexOfH > indexOfS)
bErrorInParse = TRUE;
else if (indexOfMi != -1 && indexOfS != -1 && indexOfMi > indexOfS)
bErrorInParse = TRUE;
else if (indexOfS != -1 && indexOfS != endOfParse -1)
bErrorInParse = TRUE;
else if (indexOfMi != -1 && indexOfS == -1 && indexOfMi != endOfParse -1)
bErrorInParse = TRUE;
else if (indexOfH != -1 && indexOfS == -1 && indexOfMi == -1 && indexOfH != endOfParse -1)
bErrorInParse = TRUE;
}
}
else
{
// week parse
if (us.size() - 1 != indexOfW)
bErrorInParse = TRUE;
sVal = us.extractBetween(1, us.size() - 1, sVal);
cc = sVal.toCString("");
PR_ASSERT(cc != 0);
week = nsCalUtility::atot_int32(cc,
bErrorInParse, sVal.size());
delete [] cc;
}
}
//if (FALSE) TRACE("parse: %d W, %d Y %d M %d D T %d H %d M %d S\r\n", week, year, month, day, hour, minute, second);
#if NSCALDURATION_PARSING_YEAR_AND_MONTH
if (year < 0 || month < 0 || day < 0 ||
hour < 0 || minute < 0 || second < 0 || week < 0)
bErrorInParse = TRUE;
#else
if (day < 0 || hour < 0 || minute < 0 || second < 0 || week < 0)
bErrorInParse = TRUE;
#endif
if (bErrorInParse)
{
// LOG the error
setInvalidDuration();
}
else
{
#if NSCALDURATION_PARSING_YEAR_AND_MONTH
m_iYear = year;
m_iMonth = month;
#else
m_iYear = 0;
m_iMonth = 0;
#endif
m_iDay = day;
m_iHour = hour;
m_iMinute = minute;
m_iSecond = second;
m_iWeek = week;
normalize();
}
}
//---------------------------------------------------------------------
//////////////////////////////
// CONSTRUCTORS
//////////////////////////////
//---------------------------------------------------------------------
nsCalDuration::nsCalDuration()
:
m_iYear(0),m_iMonth(0),m_iDay(0),m_iHour(0),
m_iMinute(0),m_iSecond(0), m_iWeek(0),
m_NegativeDuration(FALSE)
{
}
//---------------------------------------------------------------------
nsCalDuration::nsCalDuration(UnicodeString & us)
:
m_iYear(0),m_iMonth(0),m_iDay(0),m_iHour(0),
m_iMinute(0),m_iSecond(0), m_iWeek(0),
m_NegativeDuration(FALSE)
{
parse(us);
}
//---------------------------------------------------------------------
nsCalDuration::nsCalDuration(t_int32 type, t_int32 value)
:
m_iYear(0),m_iMonth(0),m_iDay(0),m_iHour(0),
m_iMinute(0),m_iSecond(0), m_iWeek(0),
m_NegativeDuration(FALSE)
{
switch (type)
{
case nsCalUtility::RT_MINUTELY:
m_iMinute = value;
break;
case nsCalUtility::RT_HOURLY:
m_iHour = value;
break;
case nsCalUtility::RT_DAILY:
m_iDay = value;
break;
case nsCalUtility::RT_WEEKLY:
m_iWeek = value;
break;
case nsCalUtility::RT_MONTHLY:
m_iMonth = value;
break;
case nsCalUtility::RT_YEARLY:
m_iYear = value;
break;
default:
break;
}
}
//---------------------------------------------------------------------
nsCalDuration::nsCalDuration(nsCalDuration & d)
:
m_iYear(0),m_iMonth(0),m_iDay(0),m_iHour(0),
m_iMinute(0),m_iSecond(0), m_iWeek(0),
m_NegativeDuration(FALSE)
{
t_bool b;
m_iYear = d.m_iYear;
m_iMonth = d.m_iMonth;
m_iDay = d.m_iDay;
m_iHour = d.m_iHour;
m_iMinute = d.m_iMinute;
m_iSecond = d.m_iSecond;
m_iWeek = d.m_iWeek;
m_NegativeDuration = d.m_NegativeDuration;
// check postcondition
b = ((m_iWeek != 0) && (m_iYear != 0 || m_iMonth != 0 ||
m_iDay != 0 || m_iHour !=0 || m_iMinute != 0 ||
m_iSecond != 0));
if (!b) {
//PR_ASSERT(!b);
//JLog::Instance()->logString(ms_sDurationAssertionFailed);
//setInvalidDuration();
}
}
//---------------------------------------------------------------------
nsCalDuration::nsCalDuration(t_int32 year, t_int32 month, t_int32 day,
t_int32 hour, t_int32 min, t_int32 sec,
t_int32 week, t_bool bNegativeDuration)
{
if (week > 0)
{
set(year, month, day, hour, min, sec, bNegativeDuration);
}
else
{
set(week, bNegativeDuration);
}
}
//---------------------------------------------------------------------
///////////////////////////////////
// DESTRUCTORS
///////////////////////////////////
//---------------------------------------------------------------------
nsCalDuration::~nsCalDuration()
{
}
//---------------------------------------------------------------------
///////////////////////////////////
// GETTERS AND SETTERS
///////////////////////////////////
void nsCalDuration::set(t_int32 year, t_int32 month, t_int32 day,
t_int32 hour, t_int32 min, t_int32 sec, t_bool
bNegativeDuration)
{
m_iYear = year;
m_iMonth = month;
m_iDay = day;
m_iHour = hour;
m_iMinute = min;
m_iSecond = sec;
m_NegativeDuration = bNegativeDuration;
m_iWeek = 0;
}
void nsCalDuration::set(t_int32 week, t_bool bNegativeDuration)
{
m_iWeek = week;
m_NegativeDuration = bNegativeDuration;
m_iYear = 0;
m_iMonth = 0;
m_iDay = 0;
m_iHour = 0;
m_iMinute = 0;
m_iSecond = 0;
}
t_int32 nsCalDuration::getYear() const
{
if (m_NegativeDuration)
return (0 - m_iYear);
return m_iYear;
}
t_int32 nsCalDuration::getMonth() const
{
if (m_NegativeDuration)
return (0 - m_iMonth);
return m_iMonth;
}
t_int32 nsCalDuration::getDay() const
{
if (m_NegativeDuration)
return (0 - m_iDay);
return m_iDay;
}
t_int32 nsCalDuration::getHour() const
{
if (m_NegativeDuration)
return (0 - m_iHour);
return m_iHour;
}
t_int32 nsCalDuration::getMinute() const
{
if (m_NegativeDuration)
return (0 - m_iMinute);
return m_iMinute;
}
t_int32 nsCalDuration::getSecond() const
{
if (m_NegativeDuration)
return (0 - m_iSecond);
return m_iSecond;
}
t_int32 nsCalDuration::getWeek() const
{
if (m_NegativeDuration)
return (0 - m_iWeek);
return m_iWeek;
}
//---------------------------------------------------------------------
///////////////////////////////////
// UTILITIES
///////////////////////////////////
//---------------------------------------------------------------------
void nsCalDuration::setDurationString(UnicodeString & s)
{
parse(s);
}
//---------------------------------------------------------------------
// TODO - will work if only normalize works
t_int32 nsCalDuration::compareTo(const nsCalDuration & d)
{
normalize();
if (getYear() != d.getYear())
return ((getYear() > d.getYear()) ? 1 : -1);
if (getMonth() != d.getMonth())
return ((getMonth() > d.getMonth()) ? 1 : -1);
if (getDay() != d.getDay())
return ((getDay() > d.getDay()) ? 1 : -1);
if (getHour() != d.getHour())
return ((getHour() > d.getHour()) ? 1 : -1);
if (getMinute() != d.getMinute())
return ((getMinute() > d.getMinute()) ? 1 : -1);
if (getSecond() != d.getSecond())
return ((getSecond() > d.getSecond()) ? 1 : -1);
if (getWeek() != d.getWeek())
return ((getWeek() > d.getWeek()) ? 1 : -1);
return 0;
}
//---------------------------------------------------------------------
void nsCalDuration::normalize()
{
// TODO: RISKY, assumes 30 days in a month, 12 months in a year
t_int32 temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0, temp5 = 0;
if (m_iSecond >= 60)
{
temp1 = m_iSecond / 60;
m_iSecond = m_iSecond % 60;
}
m_iMinute = m_iMinute + temp1;
if (m_iMinute >= 60) {
temp2 = m_iMinute / 60;
m_iMinute = m_iMinute % 60;
}
m_iHour = m_iHour + temp2;
if (m_iHour >= 24) {
temp3 = m_iHour / 24;
m_iHour = m_iHour % 24;
}
m_iDay = m_iDay + temp3;
if (m_iDay >= 30) {
temp4 = m_iDay / 30;
m_iDay = m_iDay % 30;
}
m_iMonth = m_iMonth + temp4;
if (m_iMonth >= 12) {
temp5 = m_iMonth / 12;
m_iMonth = m_iMonth % 12;
}
m_iYear = m_iYear + temp5;
}
//---------------------------------------------------------------------
void nsCalDuration::unnormalize()
{
// TODO: watch out for overflow
if (m_iYear > 0)
{
m_iMonth += (12 * m_iYear);
m_iYear = 0;
}
if (m_iMonth > 0)
{
m_iDay += (30 * m_iMonth);
m_iMonth = 0;
}
}
//---------------------------------------------------------------------
t_bool
nsCalDuration::isZeroLength()
{
if (m_iYear <= 0 && m_iMonth <= 0 && m_iDay <= 0 &&
m_iHour <= 0 && m_iMinute <= 0 && m_iSecond <= 0 &&
m_iWeek <= 0)
return TRUE;
else
return FALSE;
}
//---------------------------------------------------------------------
UnicodeString nsCalDuration::toString()
{
char sBuf[100];
char sBuf2[100];
sBuf[0] = '\0';
if (m_iWeek != 0)
sprintf(sBuf, "%d weeks", getWeek());
else
{
// Full form
// eyork Still looking into Libnls to see if strings for year, month, etc are there
if (getYear() != 0) { sprintf(sBuf2, getYear() > 1 ? "%d years " : "%d year ", getYear()); strcat(sBuf, sBuf2); }
if (getMonth() != 0) { sprintf(sBuf2, getMonth() > 1 ? "%d months " : "%d month ", getMonth()); strcat(sBuf, sBuf2); }
if (getDay() != 0) { sprintf(sBuf2, getDay() > 1 ? "%d days " : "%d day ", getDay()); strcat(sBuf, sBuf2); }
if (getHour() != 0) { sprintf(sBuf2, getHour() > 1 ? "%d hours " : "%d hour ", getHour()); strcat(sBuf, sBuf2); }
if (getMinute() != 0) { sprintf(sBuf2, getMinute() > 1 ? "%d minutes " : "%d minute ", getMinute()); strcat(sBuf, sBuf2); }
if (getSecond() != 0) { sprintf(sBuf2, getSecond() > 1 ? "%d seconds " : "%d second ", getSecond()); strcat(sBuf, sBuf2); }
/*
sprintf(sBuf,
"%d year, %d month , %d day, %d hour, %d mins, %d secs",
m_iYear, m_iMonth, m_iDay, m_iHour, m_iMinute, m_iSecond);
*/
}
return sBuf;
// return toICALString();
}
//---------------------------------------------------------------------
UnicodeString nsCalDuration::toICALString()
{
//if (FALSE) TRACE("toString: %d W, %d Y %d M %d D T %d H %d M %d S\r\n", m_iYear, m_iMonth, m_iDay, m_iHour, m_im_iMinute, m_iSecond);
if (!isValid())
{
return "INVALID_DURATION";
//sOut = "PT-1H";
//return sOut;
}
else if (m_iWeek != 0)
{
char sNum[20];
sprintf(sNum, "%sP%dW", ((m_NegativeDuration) ? "-" : ""), m_iWeek);
return sNum;
}
else
{
#if 1
// full form
char sNum[100];
#if NSCALDURATION_PARSING_YEAR_AND_MONTH
sprintf(sNum, "%sP%dY%dM%dDT%dH%dM%dS",
((m_NegativeDuration) ? "-" : ""), m_iYear, m_iMonth, m_iDay, m_iHour, m_iMinute, m_iSecond);
#else
unnormalize();
sprintf(sNum, "%sP%dDT%dH%dM%dS",
((m_NegativeDuration) ? "-" : ""), m_iDay, m_iHour, m_iMinute, m_iSecond);
#endif
return sNum;
#else
// condensed form
UnicodeString sOut;
UnicodeString sDate = "", sTime = "";
t_int32 aiDate[] = { m_iYear, m_iMonth, m_iDay };
char asDate[] = { 'Y', 'M', 'D' };
t_int32 aiTime[] = { m_iHour, m_iMinute, m_iSecond };
char asTime[] = { 'H', 'M', 'S' };
t_int32 kSize = 3;
int i;
for (i = 0; i < kSize ; i++) {
if (aiDate[i] != 0) {
char sNum[20];
sprintf(sNum, "%d", aiDate[i]);
sDate += sNum;
sDate += asDate[i];
}
}
for (i = 0; i < kSize ; i++) {
if (aiTime[i] != 0) {
char sNum[20];
sprintf(sNum, "%d", aiTime[i]);
sTime += sNum;
sTime += asTime[i];
}
}
if (sTime.size() > 0) {
sTime.insert(0, "T");
}
sOut = sDate;
sOut += sTime;
if (sOut.size() > 0) {
sOut.insert(0, "P");
if (m_NegativeDuration)
sOut.insert(0, "-");
}
return sOut;
#endif
}
}
//---------------------------------------------------------------------
t_bool nsCalDuration::isValid()
{
if (m_iYear < 0 || m_iMonth < 0 || m_iDay < 0 ||
m_iHour < 0 || m_iMinute < 0 || m_iSecond < 0 ||
m_iWeek < 0)
return FALSE;
else return TRUE;
}
//---------------------------------------------------------------------
////////////////////////////////////
// OVERLOADED OPERATORS
////////////////////////////////////
//---------------------------------------------------------------------
const nsCalDuration & nsCalDuration::operator=(const nsCalDuration& d)
{
m_iYear = d.m_iYear;
m_iMonth = d.m_iMonth;
m_iDay = d.m_iDay;
m_iHour = d.m_iHour;
m_iMinute = d.m_iMinute;
m_iSecond = d.m_iSecond;
m_iWeek = d.m_iWeek;
m_NegativeDuration = d.m_NegativeDuration;
return *this;
}
//---------------------------------------------------------------------
t_bool nsCalDuration::operator==(const nsCalDuration & that)
{
return (compareTo(that) == 0);
}
//---------------------------------------------------------------------
t_bool nsCalDuration::operator!=(const nsCalDuration & that)
{
return (compareTo(that) != 0);
}
//---------------------------------------------------------------------