Mozilla/mozilla/calendar/base/src/calDuration.cpp
mattwillis%gmail.com 8427ac770d bug 343027 - syncs branch and trunk files. r=jminta
git-svn-id: svn://10.0.0.236/trunk@203707 18797224-902f-48f8-a5cc-f745e15eee43
2006-07-26 00:40:23 +00:00

354 lines
9.1 KiB
C++

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Oracle Corporation code.
*
* The Initial Developer of the Original Code is Oracle Corporation
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <stuart.parmenter@oracle.com>
* Dan Mosedale <dan.mosedale@oracle.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsPrintfCString.h"
#include "calDuration.h"
#include "calBaseCID.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#ifndef MOZILLA_1_8_BRANCH
#include "nsIClassInfoImpl.h"
#endif
#define SECONDS_PER_WEEK 604800
#define SECONDS_PER_DAY 86400
#define SECONDS_PER_HOUR 3600
#define SECONDS_PER_MINUTE 60
NS_IMPL_ISUPPORTS1_CI(calDuration, calIDuration)
calDuration::calDuration()
: mImmutable(PR_FALSE)
{
Reset();
}
calDuration::calDuration(const calDuration& cdt)
{
mDuration.is_neg = cdt.mDuration.is_neg;
mDuration.weeks = cdt.mDuration.weeks;
mDuration.days = cdt.mDuration.days;
mDuration.hours = cdt.mDuration.hours;
mDuration.minutes = cdt.mDuration.minutes;
mDuration.seconds = cdt.mDuration.seconds;
// copies are always mutable
mImmutable = PR_FALSE;
}
calDuration::calDuration(const struct icaldurationtype * const aDurationPtr)
{
FromIcalDuration(aDurationPtr);
}
NS_IMETHODIMP
calDuration::GetIsMutable(PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = !mImmutable;
return NS_OK;
}
NS_IMETHODIMP
calDuration::MakeImmutable()
{
if (mImmutable)
return NS_ERROR_OBJECT_IS_IMMUTABLE;
mImmutable = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
calDuration::Clone(calIDuration **aResult)
{
calDuration *cdt = new calDuration(*this);
if (!cdt)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult = cdt);
return NS_OK;
}
NS_IMETHODIMP
calDuration::Reset()
{
if (mImmutable)
return NS_ERROR_FAILURE;
mDuration.is_neg = 0;
mDuration.weeks = 0;
mDuration.days = 0;
mDuration.hours = 0;
mDuration.minutes = 0;
mDuration.seconds = 0;
return NS_OK;
}
NS_IMETHODIMP calDuration::GetIsNegative(PRBool *_retval)
{
*_retval = mDuration.is_neg;
return NS_OK;
}
NS_IMETHODIMP calDuration::SetIsNegative(PRBool aValue)
{
if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
mDuration.is_neg = aValue;
return NS_OK;
}
NS_IMETHODIMP calDuration::GetWeeks(PRInt16 *_retval)
{
*_retval = (PRInt16)mDuration.weeks;
return NS_OK;
}
NS_IMETHODIMP calDuration::SetWeeks(PRInt16 aValue)
{
if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
mDuration.weeks = aValue;
return NS_OK;
}
NS_IMETHODIMP calDuration::GetDays(PRInt16 *_retval)
{
*_retval = (PRInt16)mDuration.days;
return NS_OK;
}
NS_IMETHODIMP calDuration::SetDays(PRInt16 aValue)
{
if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
mDuration.days = aValue;
return NS_OK;
}
NS_IMETHODIMP calDuration::GetHours(PRInt16 *_retval)
{
*_retval = (PRInt16)mDuration.hours;
return NS_OK;
}
NS_IMETHODIMP calDuration::SetHours(PRInt16 aValue)
{
if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
mDuration.hours = aValue;
return NS_OK;
}
NS_IMETHODIMP calDuration::GetMinutes(PRInt16 *_retval)
{
*_retval = (PRInt16)mDuration.minutes;
return NS_OK;
}
NS_IMETHODIMP calDuration::SetMinutes(PRInt16 aValue)
{
if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
mDuration.minutes = aValue;
return NS_OK;
}
NS_IMETHODIMP calDuration::GetSeconds(PRInt16 *_retval)
{
*_retval = (PRInt16)mDuration.seconds;
return NS_OK;
}
NS_IMETHODIMP calDuration::SetSeconds(PRInt16 aValue)
{
if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
mDuration.seconds = aValue;
return NS_OK;
}
NS_IMETHODIMP calDuration::GetInSeconds(PRInt32 *_retval)
{
PRInt32 retval =
(((PRInt32)((PRInt16)mDuration.weeks * SECONDS_PER_WEEK)) +
((PRInt32)((PRInt16)mDuration.days * SECONDS_PER_DAY)) +
((PRInt32)((PRInt16)mDuration.hours * SECONDS_PER_HOUR)) +
((PRInt32)((PRInt16)mDuration.minutes * SECONDS_PER_MINUTE)) +
((PRInt32)((PRInt16)mDuration.seconds)));
if (mDuration.is_neg)
retval=-retval;
*_retval = retval;
return NS_OK;
}
NS_IMETHODIMP calDuration::SetInSeconds(PRInt32 aValue)
{
if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
mDuration.is_neg = (aValue < 0);
if (mDuration.is_neg)
aValue = -aValue;
mDuration.weeks = aValue / SECONDS_PER_WEEK;
aValue -= (mDuration.weeks * SECONDS_PER_WEEK);
mDuration.days = aValue / SECONDS_PER_DAY;
aValue -= (mDuration.days * SECONDS_PER_DAY);
mDuration.hours = aValue / SECONDS_PER_HOUR;
aValue -= (mDuration.hours * SECONDS_PER_HOUR);
mDuration.minutes = aValue / SECONDS_PER_MINUTE;
aValue -= (mDuration.minutes * SECONDS_PER_MINUTE);
mDuration.seconds = aValue;
return NS_OK;
}
NS_IMETHODIMP calDuration::AddDuration(calIDuration *aDuration)
{
if (mImmutable)
return NS_ERROR_CALENDAR_IMMUTABLE;
struct icaldurationtype idt;
aDuration->ToIcalDuration(&idt);
// Calculate the new absolute value of the duration
// For two negative durations, the abs. value will increase,
// so use + in that case.
// Of course, also use + when both durations are positive.
if (idt.is_neg == mDuration.is_neg) {
mDuration.weeks += idt.weeks;
mDuration.days += idt.days;
mDuration.hours += idt.hours;
mDuration.minutes += idt.minutes;
mDuration.seconds += idt.seconds;
} else {
mDuration.weeks -= idt.weeks;
mDuration.days -= idt.days;
mDuration.hours -= idt.hours;
mDuration.minutes -= idt.minutes;
mDuration.seconds -= idt.seconds;
}
Normalize();
return NS_OK;
}
NS_IMETHODIMP
calDuration::Normalize()
{
if (mImmutable)
return NS_ERROR_CALENDAR_IMMUTABLE;
PRInt32 totalInSeconds;
GetInSeconds(&totalInSeconds);
SetInSeconds(totalInSeconds);
return NS_OK;
}
NS_IMETHODIMP
calDuration::ToString(nsACString& aResult)
{
return GetIcalString(aResult);
}
NS_IMETHODIMP_(void)
calDuration::ToIcalDuration(struct icaldurationtype *icald)
{
icald->is_neg = mDuration.is_neg;
icald->weeks = mDuration.weeks;
icald->days = mDuration.days;
icald->hours = mDuration.hours;
icald->minutes = mDuration.minutes;
icald->seconds = mDuration.seconds;
return;
}
void
calDuration::FromIcalDuration(const struct icaldurationtype * const icald)
{
mDuration.is_neg = icald->is_neg;
mDuration.weeks = icald->weeks;
mDuration.days = icald->days;
mDuration.hours = icald->hours;
mDuration.minutes = icald->minutes;
mDuration.seconds = icald->seconds;
return;
}
NS_IMETHODIMP
calDuration::GetIcalString(nsACString& aResult)
{
// note that ics is owned by libical, so we don't need to free
const char *ics = icaldurationtype_as_ical_string(mDuration);
if (ics) {
aResult.Assign(ics);
return NS_OK;
}
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
calDuration::SetIcalString(const nsACString& aIcalString)
{
mDuration = icaldurationtype_from_string(nsPromiseFlatCString(aIcalString).get());
return NS_OK;
}
NS_IMETHODIMP
calDuration::Compare(calIDuration *aOther, PRInt32 *aResult)
{
PRInt32 thisInSeconds, otherInSeconds;
// cast to void because these calls can't fail
(void)GetInSeconds(&thisInSeconds);
(void)aOther->GetInSeconds(&otherInSeconds);
if ( thisInSeconds < otherInSeconds ) {
*aResult = -1;
} else if ( thisInSeconds > otherInSeconds ) {
*aResult = 1;
} else {
*aResult = 0;
}
return NS_OK;
}