Back to index

lightning-sunbird  0.9+nobinonly
calDuration.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Oracle Corporation code.
00016  *
00017  * The Initial Developer of the Original Code is Oracle Corporation
00018  * Portions created by the Initial Developer are Copyright (C) 2005
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Stuart Parmenter <stuart.parmenter@oracle.com>
00023  *   Dan Mosedale <dan.mosedale@oracle.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "calDuration.h"
00040 #include "calBaseCID.h"
00041 
00042 #include "nsComponentManagerUtils.h"
00043 #include "nsServiceManagerUtils.h"
00044 
00045 #ifndef MOZILLA_1_8_BRANCH
00046 #include "nsIClassInfoImpl.h"
00047 #endif
00048 
00049 #include "calUtils.h"
00050 
00051 #define SECONDS_PER_WEEK   604800
00052 #define SECONDS_PER_DAY     86400
00053 #define SECONDS_PER_HOUR     3600
00054 #define SECONDS_PER_MINUTE     60
00055 
00056 NS_IMPL_ISUPPORTS1_CI(calDuration, calIDuration)
00057 
00058 calDuration::calDuration()
00059     : mImmutable(PR_FALSE)
00060 {
00061     Reset();
00062 }
00063 
00064 calDuration::calDuration(const calDuration& cdt)
00065 {
00066     mDuration.is_neg = cdt.mDuration.is_neg;
00067     mDuration.weeks = cdt.mDuration.weeks;
00068     mDuration.days = cdt.mDuration.days;
00069     mDuration.hours = cdt.mDuration.hours;
00070     mDuration.minutes = cdt.mDuration.minutes;
00071     mDuration.seconds = cdt.mDuration.seconds;
00072 
00073     // copies are always mutable
00074     mImmutable = PR_FALSE;
00075 }
00076 
00077 calDuration::calDuration(const struct icaldurationtype * const aDurationPtr)
00078     : mImmutable(PR_FALSE)
00079 {
00080     FromIcalDuration(aDurationPtr);
00081 }
00082 
00083 NS_IMETHODIMP
00084 calDuration::GetIsMutable(PRBool *aResult)
00085 {
00086     NS_ENSURE_ARG_POINTER(aResult);
00087 
00088     *aResult = !mImmutable;
00089     return NS_OK;
00090 }
00091 
00092 NS_IMETHODIMP
00093 calDuration::MakeImmutable()
00094 {
00095     mImmutable = PR_TRUE;
00096     return NS_OK;
00097 }
00098 
00099 NS_IMETHODIMP
00100 calDuration::Clone(calIDuration **aResult)
00101 {
00102     calDuration *cdt = new calDuration(*this);
00103     if (!cdt)
00104         return NS_ERROR_OUT_OF_MEMORY;
00105 
00106     NS_ADDREF(*aResult = cdt);
00107     return NS_OK;
00108 }
00109 
00110 NS_IMETHODIMP
00111 calDuration::Reset()
00112 {
00113     if (mImmutable)
00114         return NS_ERROR_FAILURE;
00115 
00116     mDuration.is_neg = 0;
00117     mDuration.weeks = 0;
00118     mDuration.days = 0;
00119     mDuration.hours = 0;
00120     mDuration.minutes = 0;
00121     mDuration.seconds = 0;
00122 
00123     return NS_OK;
00124 }
00125 
00126 NS_IMETHODIMP calDuration::GetIsNegative(PRBool *_retval)
00127 {
00128     *_retval = mDuration.is_neg;
00129     return NS_OK;
00130 }
00131 NS_IMETHODIMP calDuration::SetIsNegative(PRBool aValue)
00132 {
00133     if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
00134     mDuration.is_neg = aValue;
00135     return NS_OK;
00136 }
00137 
00138 NS_IMETHODIMP calDuration::GetWeeks(PRInt16 *_retval)
00139 {
00140     *_retval = (PRInt16)mDuration.weeks;
00141     return NS_OK;
00142 }
00143 NS_IMETHODIMP calDuration::SetWeeks(PRInt16 aValue)
00144 {
00145     if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
00146     mDuration.weeks = aValue;
00147     return NS_OK;
00148 }
00149 
00150 NS_IMETHODIMP calDuration::GetDays(PRInt16 *_retval)
00151 {
00152     *_retval = (PRInt16)mDuration.days;
00153     return NS_OK;
00154 }
00155 NS_IMETHODIMP calDuration::SetDays(PRInt16 aValue)
00156 {
00157     if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
00158     mDuration.days = aValue;
00159     return NS_OK;
00160 }
00161 
00162 NS_IMETHODIMP calDuration::GetHours(PRInt16 *_retval)
00163 {
00164     *_retval = (PRInt16)mDuration.hours;
00165     return NS_OK;
00166 }
00167 NS_IMETHODIMP calDuration::SetHours(PRInt16 aValue)
00168 {
00169     if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
00170     mDuration.hours = aValue;
00171     return NS_OK;
00172 }
00173 
00174 NS_IMETHODIMP calDuration::GetMinutes(PRInt16 *_retval)
00175 {
00176     *_retval = (PRInt16)mDuration.minutes;
00177     return NS_OK;
00178 }
00179 NS_IMETHODIMP calDuration::SetMinutes(PRInt16 aValue)
00180 {
00181     if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
00182     mDuration.minutes = aValue;
00183     return NS_OK;
00184 }
00185 
00186 NS_IMETHODIMP calDuration::GetSeconds(PRInt16 *_retval)
00187 {
00188     *_retval = (PRInt16)mDuration.seconds;
00189     return NS_OK;
00190 }
00191 NS_IMETHODIMP calDuration::SetSeconds(PRInt16 aValue)
00192 {
00193     if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
00194     mDuration.seconds = aValue;
00195     return NS_OK;
00196 }
00197 
00198 
00199 NS_IMETHODIMP calDuration::GetInSeconds(PRInt32 *_retval)
00200 {
00201        PRInt32 retval =
00202         (((PRInt32)((PRInt16)mDuration.weeks   * SECONDS_PER_WEEK)) + 
00203          ((PRInt32)((PRInt16)mDuration.days    * SECONDS_PER_DAY)) +
00204          ((PRInt32)((PRInt16)mDuration.hours   * SECONDS_PER_HOUR)) +
00205          ((PRInt32)((PRInt16)mDuration.minutes * SECONDS_PER_MINUTE)) +
00206          ((PRInt32)((PRInt16)mDuration.seconds)));
00207     if (mDuration.is_neg)
00208               retval=-retval;
00209     *_retval = retval;
00210 
00211     return NS_OK;
00212 }
00213 NS_IMETHODIMP calDuration::SetInSeconds(PRInt32 aValue)
00214 {
00215     if (mImmutable) return NS_ERROR_CALENDAR_IMMUTABLE;
00216 
00217     mDuration.is_neg = (aValue < 0);
00218     if (mDuration.is_neg)
00219         aValue = -aValue;
00220 
00221     // set weeks exOR days/hours/...
00222     mDuration.weeks = ((aValue % SECONDS_PER_WEEK) == 0 ? aValue / SECONDS_PER_WEEK : 0);
00223     aValue -= (mDuration.weeks * SECONDS_PER_WEEK);
00224 
00225     mDuration.days = aValue / SECONDS_PER_DAY;
00226     aValue -= (mDuration.days * SECONDS_PER_DAY);
00227 
00228     mDuration.hours = aValue / SECONDS_PER_HOUR;
00229     aValue -= (mDuration.hours * SECONDS_PER_HOUR);
00230 
00231     mDuration.minutes = aValue / SECONDS_PER_MINUTE;
00232     aValue -= (mDuration.minutes * SECONDS_PER_MINUTE);
00233 
00234     mDuration.seconds = aValue;
00235 
00236     return NS_OK;
00237 }
00238 
00239 NS_IMETHODIMP calDuration::AddDuration(calIDuration *aDuration)
00240 {
00241     if (mImmutable)
00242         return NS_ERROR_CALENDAR_IMMUTABLE;
00243 
00244     struct icaldurationtype idt;
00245     aDuration->ToIcalDuration(&idt);
00246 
00247     // Calculate the new absolute value of the duration
00248     // For two negative durations, the abs. value will increase,
00249     // so use + in that case.
00250     // Of course, also use + when both durations are positive.
00251     if (idt.is_neg == mDuration.is_neg) {
00252         mDuration.weeks   += idt.weeks;
00253         mDuration.days    += idt.days;
00254         mDuration.hours   += idt.hours;
00255         mDuration.minutes += idt.minutes;
00256         mDuration.seconds += idt.seconds;
00257     } else {
00258         mDuration.weeks   -= idt.weeks;
00259         mDuration.days    -= idt.days;
00260         mDuration.hours   -= idt.hours;
00261         mDuration.minutes -= idt.minutes;
00262         mDuration.seconds -= idt.seconds;
00263     }
00264 
00265     Normalize();
00266 
00267     return NS_OK;
00268 }
00269 
00270 NS_IMETHODIMP
00271 calDuration::Normalize()
00272 {
00273     if (mImmutable)
00274         return NS_ERROR_CALENDAR_IMMUTABLE;
00275 
00276     PRInt32 totalInSeconds;
00277     GetInSeconds(&totalInSeconds);
00278     SetInSeconds(totalInSeconds);
00279 
00280     return NS_OK;
00281 }
00282 
00283 NS_IMETHODIMP
00284 calDuration::ToString(nsACString& aResult)
00285 {
00286     return GetIcalString(aResult);
00287 }
00288 
00289 NS_IMETHODIMP_(void)
00290 calDuration::ToIcalDuration(struct icaldurationtype *icald)
00291 {
00292     icald->is_neg  = mDuration.is_neg;
00293     icald->weeks   = mDuration.weeks;
00294     icald->days    = mDuration.days;
00295     icald->hours   = mDuration.hours;
00296     icald->minutes = mDuration.minutes;
00297     icald->seconds = mDuration.seconds;
00298     return;
00299 }
00300 
00301 void
00302 calDuration::FromIcalDuration(const struct icaldurationtype * const icald)
00303 {
00304     mDuration.is_neg  = icald->is_neg;
00305     mDuration.weeks   = icald->weeks;
00306     mDuration.days    = icald->days;
00307     mDuration.hours   = icald->hours;
00308     mDuration.minutes = icald->minutes;
00309     mDuration.seconds = icald->seconds;
00310     return;
00311 }
00312 
00313 NS_IMETHODIMP
00314 calDuration::GetIcalString(nsACString& aResult)
00315 {
00316     // note that ics is owned by libical, so we don't need to free
00317     const char *ics = icaldurationtype_as_ical_string(mDuration);
00318     
00319     if (ics) {
00320         aResult.Assign(ics);
00321         return NS_OK;
00322     }
00323 
00324     return NS_ERROR_OUT_OF_MEMORY;
00325 }
00326 
00327 NS_IMETHODIMP
00328 calDuration::SetIcalString(const nsACString& aIcalString)
00329 {
00330     mDuration = icaldurationtype_from_string(PromiseFlatCString(aIcalString).get());
00331     return NS_OK;
00332 }
00333 
00334 NS_IMETHODIMP
00335 calDuration::Compare(calIDuration *aOther, PRInt32 *aResult)
00336 {
00337     PRInt32 thisInSeconds, otherInSeconds;
00338 
00339     // cast to void because these calls can't fail
00340     (void)GetInSeconds(&thisInSeconds);
00341     (void)aOther->GetInSeconds(&otherInSeconds);
00342 
00343     if ( thisInSeconds < otherInSeconds ) {
00344       *aResult = -1;
00345     } else if ( thisInSeconds > otherInSeconds ) {
00346       *aResult = 1;
00347     } else {
00348       *aResult = 0;
00349     }
00350 
00351     return NS_OK;
00352 }