Back to index

lightning-sunbird  0.9+nobinonly
calDateTime.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Oracle Corporation code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  *  Oracle Corporation
00018  * Portions created by the Initial Developer are Copyright (C) 2004
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
00023  *   Dan Mosedale <dan.mosedale@oracle.com>
00024  *   Michiel van Leeuwen <mvl@exedo.nl>
00025  *   Clint Talbert <cmtalbert@myfastmail.com>
00026  *   Daniel Boelzle <daniel.boelzle@sun.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either the GNU General Public License Version 2 or later (the "GPL"), or
00030  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #include "calDateTime.h"
00043 #include "calBaseCID.h"
00044 
00045 #include "nsServiceManagerUtils.h"
00046 #ifndef MOZILLA_1_8_BRANCH
00047 #include "nsIClassInfoImpl.h"
00048 #endif
00049 
00050 #include "calIErrors.h"
00051 #include "calDuration.h"
00052 
00053 #include "jsdate.h"
00054 #include "prprf.h"
00055 
00056 extern "C" {
00057 #include "ical.h"
00058 }
00059 
00060 #define CAL_ATTR_SET_PRE NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE)
00061 #define CAL_ATTR_SET_POST Normalize()
00062 #include "calAttributeHelpers.h"
00063 
00064 NS_IMPL_ISUPPORTS2_CI(calDateTime, calIDateTime, nsIXPCScriptable)
00065 
00066 calDateTime::calDateTime()
00067     : mImmutable(PR_FALSE)
00068 {
00069     Reset();
00070 }
00071 
00072 calDateTime::calDateTime(icaltimetype const* atimeptr, calITimezone *tz)
00073     : mImmutable(PR_FALSE)
00074 {
00075     FromIcalTime(atimeptr, tz);
00076 }
00077 
00078 NS_IMETHODIMP
00079 calDateTime::GetIsMutable(PRBool *aResult)
00080 {
00081     NS_ENSURE_ARG_POINTER(aResult);
00082     *aResult = !mImmutable;
00083     return NS_OK;
00084 }
00085 
00086 NS_IMETHODIMP
00087 calDateTime::MakeImmutable()
00088 {
00089     mImmutable = PR_TRUE;
00090     return NS_OK;
00091 }
00092 
00093 NS_IMETHODIMP
00094 calDateTime::Clone(calIDateTime **aResult)
00095 {
00096     NS_ENSURE_ARG_POINTER(aResult);
00097     icaltimetype itt;
00098     ToIcalTime(&itt);
00099     calDateTime * const cdt = new calDateTime(&itt, mTimezone);
00100     CAL_ENSURE_MEMORY(cdt);
00101     NS_ADDREF(*aResult = cdt);
00102     return NS_OK;
00103 }
00104 
00105 NS_IMETHODIMP
00106 calDateTime::ResetTo(PRInt16 year,
00107                      PRInt16 month,
00108                      PRInt16 day,
00109                      PRInt16 hour,
00110                      PRInt16 minute,
00111                      PRInt16 second,
00112                      calITimezone * tz)
00113 {
00114     NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
00115     NS_ENSURE_ARG_POINTER(tz);
00116     mYear = year;
00117     mMonth = month;
00118     mDay = day;
00119     mHour = hour;
00120     mMinute = minute;
00121     mSecond = second;
00122     mIsDate = PR_FALSE;
00123     mTimezone = tz;
00124     Normalize();
00125     return NS_OK;
00126 }
00127 
00128 NS_IMETHODIMP
00129 calDateTime::Reset()
00130 {
00131     NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
00132     mYear = 1970;
00133     mMonth = 0;
00134     mDay = 1;
00135     mHour = 0;
00136     mMinute = 0;
00137     mSecond = 0;
00138     mWeekday = 4;
00139     mYearday = 1;
00140     mIsDate = PR_FALSE;
00141     cal::getTimezoneService()->GetUTC(getter_AddRefs(mTimezone));
00142     mNativeTime = 0;
00143     mIsValid = PR_TRUE;
00144     return NS_OK;
00145 }
00146 
00147 CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Year)
00148 CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Month)
00149 CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Day)
00150 CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Hour)
00151 CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Minute)
00152 CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Second)
00153 CAL_VALUETYPE_ATTR(calDateTime, PRBool, IsDate)
00154 CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRBool, IsValid)
00155 CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRTime, NativeTime)
00156 CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRInt16, Weekday)
00157 CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRInt16, Yearday)
00158 
00159 CAL_ISUPPORTS_ATTR_GETTER(calDateTime, calITimezone, Timezone)
00160 
00161 NS_IMETHODIMP calDateTime::SetTimezone(calITimezone *aValue) {
00162     NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
00163     NS_ENSURE_ARG_POINTER(aValue);
00164     mTimezone = aValue;
00165     CAL_ATTR_SET_POST;
00166     return NS_OK;
00167 }
00168 
00169 NS_IMETHODIMP
00170 calDateTime::GetTimezoneOffset(PRInt32 *aResult)
00171 {
00172     NS_ENSURE_ARG_POINTER(aResult);
00173     icaltimetype icalt;
00174     ToIcalTime(&icalt);
00175     int dst;
00176     *aResult = icaltimezone_get_utc_offset(const_cast<icaltimezone *>(icalt.zone), &icalt, &dst);
00177     return NS_OK;
00178 }
00179 
00180 NS_IMETHODIMP
00181 calDateTime::SetNativeTime(PRTime aNativeTime)
00182 {
00183     return SetTimeInTimezone(aNativeTime, cal::UTC());
00184 }
00185 
00186 NS_IMETHODIMP
00187 calDateTime::AddDuration(calIDuration *aDuration)
00188 {
00189     NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
00190     NS_ENSURE_ARG_POINTER(aDuration);
00191 
00192     icaldurationtype idt;
00193     aDuration->ToIcalDuration(&idt);
00194     
00195     icaltimetype itt;
00196     ToIcalTime(&itt);
00197 
00198     icaltimetype const newitt = icaltime_add(itt, idt);
00199     FromIcalTime(&newitt, mTimezone);
00200 
00201     return NS_OK;
00202 }
00203 
00204 NS_IMETHODIMP
00205 calDateTime::SubtractDate(calIDateTime *aDate, calIDuration **aDuration)
00206 {
00207     NS_ENSURE_ARG_POINTER(aDate);
00208     NS_ENSURE_ARG_POINTER(aDuration);
00209 
00210     // same as icaltime_subtract(), but minding timezones:
00211     PRTime t2t;
00212     aDate->GetNativeTime(&t2t);
00213     // for a duration, need to convert the difference in microseconds (prtime)
00214     // to seconds (libical), so divide by one million.
00215     icaldurationtype const idt = icaldurationtype_from_int(
00216         static_cast<int>((mNativeTime - t2t) / PRInt64(PR_USEC_PER_SEC)));
00217 
00218     calDuration * const dur = new calDuration(&idt);
00219     CAL_ENSURE_MEMORY(dur);
00220     NS_ADDREF(*aDuration = dur);
00221     return NS_OK;
00222 }
00223 
00224 NS_IMETHODIMP
00225 calDateTime::ToString(nsACString & aResult)
00226 {
00227     nsCAutoString tzid;
00228     mTimezone->GetTzid(tzid);
00229     char buffer[256];
00230     PRUint32 const length = PR_snprintf(
00231         buffer, sizeof(buffer), "%04hd/%02hd/%02hd %02hd:%02hd:%02hd %s isDate=%01hd",
00232         mYear, mMonth + 1, mDay, mHour, mMinute, mSecond,
00233         tzid.get(), static_cast<PRInt16>(mIsDate));
00234     if (length != static_cast<PRUint32>(-1))
00235         aResult.Assign(buffer, length);
00236     return NS_OK;
00237 }
00238 
00239 NS_IMETHODIMP
00240 calDateTime::SetTimeInTimezone(PRTime aTime, calITimezone * aTimezone)
00241 {
00242     NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
00243     NS_ENSURE_ARG_POINTER(aTimezone);
00244     icaltimetype icalt;
00245     PRTimeToIcaltime(aTime, PR_FALSE, cal::getIcalTimezone(aTimezone), &icalt);
00246     FromIcalTime(&icalt, aTimezone);
00247     return NS_OK;
00248 }
00249 
00250 NS_IMETHODIMP
00251 calDateTime::GetInTimezone(calITimezone * aTimezone, calIDateTime ** aResult)
00252 {
00253     NS_ENSURE_ARG_POINTER(aTimezone);
00254     NS_ENSURE_ARG_POINTER(aResult);
00255 
00256     if (mIsDate) {
00257         // if it's a date, we really just want to make a copy of this
00258         // and set the timezone.
00259         nsresult rv = Clone(aResult);
00260         if (NS_SUCCEEDED(rv)) {
00261             rv = (*aResult)->SetTimezone(aTimezone);
00262         }
00263         return rv;
00264     } else {
00265         icaltimetype icalt;
00266         ToIcalTime(&icalt);
00267 
00268         icaltimezone * tz = cal::getIcalTimezone(aTimezone);
00269         if (icalt.zone == tz) {
00270             return Clone(aResult);
00271         }
00272 
00273         /* If there's a zone, we need to convert; otherwise, we just
00274          * assign, since this item is floating */
00275         if (icalt.zone && tz) {
00276             icaltimezone_convert_time(&icalt, const_cast<icaltimezone *>(icalt.zone), tz);
00277         }
00278         icalt.zone = tz;
00279         icalt.is_utc = (tz && tz == icaltimezone_get_utc_timezone());
00280 
00281         calDateTime * cdt = new calDateTime(&icalt, aTimezone);
00282         CAL_ENSURE_MEMORY(cdt);
00283         NS_ADDREF (*aResult = cdt);
00284         return NS_OK;
00285     }
00286 }
00287 
00288 NS_IMETHODIMP
00289 calDateTime::GetStartOfWeek(calIDateTime ** aResult)
00290 {
00291     NS_ENSURE_ARG_POINTER(aResult);
00292 
00293     icaltimetype icalt;
00294     ToIcalTime(&icalt);
00295     int day_of_week = icaltime_day_of_week(icalt);
00296     if (day_of_week > 1)
00297         icaltime_adjust(&icalt, - (day_of_week - 1), 0, 0, 0);
00298     icalt.is_date = 1;
00299 
00300     calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
00301     CAL_ENSURE_MEMORY(cdt);
00302     NS_ADDREF(*aResult = cdt);
00303     return NS_OK;
00304 }
00305 
00306 NS_IMETHODIMP
00307 calDateTime::GetEndOfWeek(calIDateTime ** aResult)
00308 {
00309     NS_ENSURE_ARG_POINTER(aResult);
00310 
00311     icaltimetype icalt;
00312     ToIcalTime(&icalt);
00313     int day_of_week = icaltime_day_of_week(icalt);
00314     if (day_of_week < 7)
00315         icaltime_adjust(&icalt, 7 - day_of_week, 0, 0, 0);
00316     icalt.is_date = 1;
00317 
00318     calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
00319     CAL_ENSURE_MEMORY(cdt);
00320     NS_ADDREF(*aResult = cdt);
00321     return NS_OK;
00322 }
00323 
00324 NS_IMETHODIMP
00325 calDateTime::GetStartOfMonth(calIDateTime ** aResult)
00326 {
00327     NS_ENSURE_ARG_POINTER(aResult);
00328 
00329     icaltimetype icalt;
00330     ToIcalTime(&icalt);
00331     icalt.day = 1;
00332     icalt.is_date = 1;
00333 
00334     calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
00335     CAL_ENSURE_MEMORY(cdt);
00336     NS_ADDREF(*aResult = cdt);
00337     return NS_OK;
00338 }
00339 
00340 NS_IMETHODIMP
00341 calDateTime::GetEndOfMonth(calIDateTime ** aResult)
00342 {
00343     NS_ENSURE_ARG_POINTER(aResult);
00344 
00345     icaltimetype icalt;
00346     ToIcalTime(&icalt);
00347     icalt.day = icaltime_days_in_month(icalt.month, icalt.year);
00348     icalt.is_date = 1;
00349 
00350     calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
00351     CAL_ENSURE_MEMORY(cdt);
00352     NS_ADDREF(*aResult = cdt);
00353     return NS_OK;
00354 }
00355 
00356 NS_IMETHODIMP
00357 calDateTime::GetStartOfYear(calIDateTime ** aResult)
00358 {
00359     NS_ENSURE_ARG_POINTER(aResult);
00360 
00361     icaltimetype icalt;
00362     ToIcalTime(&icalt);
00363     icalt.month = 1;
00364     icalt.day = 1;
00365     icalt.is_date = 1;
00366 
00367     calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
00368     CAL_ENSURE_MEMORY(cdt);
00369     NS_ADDREF(*aResult = cdt);
00370     return NS_OK;
00371 }
00372 
00373 NS_IMETHODIMP
00374 calDateTime::GetEndOfYear(calIDateTime ** aResult)
00375 {
00376     NS_ENSURE_ARG_POINTER(aResult);
00377 
00378     icaltimetype icalt;
00379     ToIcalTime(&icalt);
00380     icalt.month = 12;
00381     icalt.day = 31;
00382     icalt.is_date = 1;
00383 
00384     calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
00385     CAL_ENSURE_MEMORY(cdt);
00386     NS_ADDREF(*aResult = cdt);
00387     return NS_OK;
00388 }
00389 
00390 NS_IMETHODIMP
00391 calDateTime::GetIcalString(nsACString& aResult)
00392 {
00393     icaltimetype t;
00394     ToIcalTime(&t);
00395 
00396     // note that ics is owned by libical, so we don't need to free
00397     char const * const ics = icaltime_as_ical_string(t);
00398     CAL_ENSURE_MEMORY(ics);
00399     aResult.Assign(ics);
00400     return NS_OK;
00401 }
00402 
00403 NS_IMETHODIMP
00404 calDateTime::SetIcalString(nsACString const& aIcalString)
00405 {
00406     NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
00407     icaltimetype icalt;
00408     icalt = icaltime_from_string(PromiseFlatCString(aIcalString).get());
00409     if (icaltime_is_null_time(icalt)) {
00410         return calIErrors::ICS_ERROR_BASE + icalerrno;
00411     }
00412     FromIcalTime(&icalt, nsnull);
00413     return NS_OK;
00414 }
00415 
00420 // internal Normalize():
00421 void calDateTime::Normalize()
00422 {
00423     icaltimetype icalt;
00424     ToIcalTime(&icalt);
00425     FromIcalTime(&icalt, mTimezone);
00426 }
00427 
00428 NS_IMETHODIMP_(void)
00429 calDateTime::ToIcalTime(struct icaltimetype * icalt)
00430 {
00431     icalt->year = mYear;
00432     icalt->month = mMonth + 1;
00433     icalt->day = mDay;
00434     icalt->hour = mHour;
00435     icalt->minute = mMinute;
00436     icalt->second = mSecond;
00437 
00438     icalt->is_date = mIsDate ? 1 : 0;
00439     icalt->is_daylight = 0;
00440 
00441     icaltimezone * tz = cal::getIcalTimezone(mTimezone);
00442     icalt->zone = tz;
00443     icalt->is_utc = (tz && tz == icaltimezone_get_utc_timezone());
00444     icalt->is_daylight = 0;
00445     // xxx todo: discuss/investigate is_daylight
00446 //     if (tz) {
00447 //         icaltimezone_get_utc_offset(tz, icalt, &icalt->is_daylight);
00448 //     }
00449 }
00450 
00451 void calDateTime::FromIcalTime(icaltimetype const* icalt, calITimezone * tz)
00452 {
00453     icaltimetype t = *icalt;
00454     mIsValid = (icaltime_is_null_time(t) ||
00455                 icaltime_is_valid_time(t) ? PR_TRUE : PR_FALSE);
00456 
00457     mIsDate = t.is_date ? PR_TRUE : PR_FALSE;
00458     if (mIsDate) {
00459         t.hour = 0;
00460         t.minute = 0;
00461         t.second = 0;
00462     }
00463 
00464     if (mIsValid) {
00465         t = icaltime_normalize(t);
00466     }
00467 
00468     mYear = static_cast<PRInt16>(t.year);
00469     mMonth = static_cast<PRInt16>(t.month - 1);
00470     mDay = static_cast<PRInt16>(t.day);
00471     mHour = static_cast<PRInt16>(t.hour);
00472     mMinute = static_cast<PRInt16>(t.minute);
00473     mSecond = static_cast<PRInt16>(t.second);
00474 
00475     if (tz) {
00476         mTimezone = tz;
00477     } else {
00478         mTimezone = cal::detectTimezone(t, nsnull);
00479     }
00480 #if defined(DEBUG)
00481     if (mTimezone) {
00482         if (t.is_utc) {
00483             NS_ASSERTION(SameCOMIdentity(mTimezone, cal::UTC()), "UTC mismatch!");
00484         } else if (!t.zone) {
00485             NS_ASSERTION(SameCOMIdentity(mTimezone, cal::floating()), "floating mismatch!");
00486         } else {
00487             nsCAutoString tzid;
00488             mTimezone->GetTzid(tzid);
00489             NS_ASSERTION(tzid.Equals(icaltimezone_get_tzid(const_cast<icaltimezone *>(t.zone))),
00490                          "tzid mismatch!");
00491         }
00492     }
00493 #endif
00494 
00495     mWeekday = static_cast<PRInt16>(icaltime_day_of_week(t) - 1);
00496     mYearday = static_cast<PRInt16>(icaltime_day_of_year(t));
00497 
00498     // mNativeTime: not moving the existing date to UTC,
00499     // but merely representing it a UTC-based way.
00500     t.is_date = 0;
00501     mNativeTime = IcaltimeToPRTime(&t, icaltimezone_get_utc_timezone());
00502 }
00503 
00504 PRTime calDateTime::IcaltimeToPRTime(icaltimetype const* icalt, icaltimezone const* tz)
00505 {
00506     icaltimetype tt;
00507     PRExplodedTime et;
00508 
00509     /* If the time is the special null time, return 0. */
00510     if (icaltime_is_null_time(*icalt)) {
00511         return 0;
00512     }
00513 
00514     if (tz) {
00515         // use libical for timezone conversion, as it can handle all ics
00516         // timezones. having nspr do it is much harder.
00517         tt = icaltime_convert_to_zone(*icalt, const_cast<icaltimezone *>(tz));
00518     } else {
00519         tt = *icalt;
00520     }
00521 
00522     /* Empty the destination */
00523     memset(&et, 0, sizeof(struct PRExplodedTime));
00524 
00525     /* Fill the fields */
00526     if (icaltime_is_date(tt)) {
00527         et.tm_sec = et.tm_min = et.tm_hour = 0;
00528     } else {
00529         et.tm_sec = tt.second;
00530         et.tm_min = tt.minute;
00531         et.tm_hour = tt.hour;
00532     }
00533     et.tm_mday = static_cast<PRInt16>(tt.day);
00534     et.tm_month = static_cast<PRInt16>(tt.month-1);
00535     et.tm_year = static_cast<PRInt16>(tt.year);
00536 
00537     return PR_ImplodeTime(&et);
00538 }
00539 
00540 void calDateTime::PRTimeToIcaltime(PRTime time, PRBool isdate,
00541                                    icaltimezone const* tz,
00542                                    icaltimetype * icalt)
00543 {
00544     PRExplodedTime et;
00545     PR_ExplodeTime(time, PR_GMTParameters, &et);
00546 
00547     icalt->year   = et.tm_year;
00548     icalt->month  = et.tm_month + 1;
00549     icalt->day    = et.tm_mday;
00550 
00551     if (isdate) { 
00552         icalt->hour    = 0;
00553         icalt->minute  = 0;
00554         icalt->second  = 0;
00555         icalt->is_date = 1;
00556     } else {
00557         icalt->hour   = et.tm_hour;
00558         icalt->minute = et.tm_min;
00559         icalt->second = et.tm_sec;
00560         icalt->is_date = 0;
00561     }
00562 
00563     icalt->zone = tz;
00564     icalt->is_utc = ((tz && tz == icaltimezone_get_utc_timezone()) ? 1 : 0);
00565     icalt->is_daylight = 0;
00566     // xxx todo: discuss/investigate is_daylight
00567 //     if (tz) {
00568 //         icaltimezone_get_utc_offset(tz, icalt, &icalt->is_daylight);
00569 //     }
00570 }
00571 
00572 NS_IMETHODIMP
00573 calDateTime::Compare(calIDateTime * aOther, PRInt32 * aResult)
00574 {
00575     NS_ENSURE_ARG_POINTER(aOther);
00576     NS_ENSURE_ARG_POINTER(aResult);
00577 
00578     PRBool otherIsDate = PR_FALSE;
00579     aOther->GetIsDate(&otherIsDate);
00580 
00581     icaltimetype a, b;
00582     ToIcalTime(&a);
00583     aOther->ToIcalTime(&b);
00584 
00585     // If either this or aOther is floating, both objects are treated
00586     // as floating for the comparison.
00587     if (!a.zone || !b.zone) {
00588         a.zone = NULL;
00589         a.is_utc = 0;
00590         b.zone = NULL;
00591         b.is_utc = 0;
00592     }
00593 
00594     if (mIsDate || otherIsDate) {
00595         *aResult = icaltime_compare_date_only(a, b, cal::getIcalTimezone(mTimezone));
00596     } else {
00597         *aResult = icaltime_compare(a, b);
00598     }
00599 
00600     return NS_OK;
00601 }
00602 
00603 /*
00604  * nsIXPCScriptable impl
00605  */
00606 
00607 /* readonly attribute string className; */
00608 NS_IMETHODIMP
00609 calDateTime::GetClassName(char ** aClassName)
00610 {
00611     NS_ENSURE_ARG_POINTER(aClassName);
00612     *aClassName = static_cast<char *>(nsMemory::Clone(CAL_STRLEN_ARGS("calDateTime") +1));
00613     CAL_ENSURE_MEMORY(*aClassName);
00614     return NS_OK;
00615 }
00616 
00617 /* readonly attribute PRUint32 scriptableFlags; */
00618 NS_IMETHODIMP
00619 calDateTime::GetScriptableFlags(PRUint32 * aScriptableFlags)
00620 {
00621     NS_ENSURE_ARG_POINTER(aScriptableFlags);
00622     *aScriptableFlags = nsIXPCScriptable::WANT_GETPROPERTY |
00623                         nsIXPCScriptable::WANT_SETPROPERTY |
00624                         nsIXPCScriptable::WANT_NEWRESOLVE |
00625                         nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE;
00626     return NS_OK;
00627 }
00628 
00629 /* PRBool getProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in JSValPtr vp); */
00630 NS_IMETHODIMP
00631 calDateTime::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00632                          JSObject * obj_, jsval id, jsval * vp, PRBool *_retval)
00633 {
00634     NS_ENSURE_ARG_POINTER(vp);
00635     NS_ENSURE_ARG_POINTER(_retval);
00636 
00637     if (JSVAL_IS_STRING(id)) {
00638         nsDependentString const jsid(
00639             reinterpret_cast<PRUnichar const*>(
00640                 JS_GetStringChars(JSVAL_TO_STRING(id))),
00641             JS_GetStringLength(JSVAL_TO_STRING(id)));
00642         if (jsid.EqualsLiteral("jsDate")) {
00643             PRTime tmp, thousand;
00644             jsdouble msec;
00645             LL_I2L(thousand, 1000);
00646             LL_DIV(tmp, mNativeTime, thousand);
00647             LL_L2D(msec, tmp);
00648 
00649             JSObject *obj;
00650             PRBool b;
00651             if (NS_SUCCEEDED(mTimezone->GetIsFloating(&b)) && b)
00652                 obj = js_NewDateObject(cx, mYear, mMonth, mDay, mHour, mMinute, mSecond);
00653             else
00654                 obj = js_NewDateObjectMsec(cx, msec);
00655 
00656             *vp = OBJECT_TO_JSVAL(obj);
00657             *_retval = PR_TRUE;
00658             return NS_SUCCESS_I_DID_SOMETHING;
00659         }
00660     }
00661 
00662     *_retval = PR_TRUE;
00663     return NS_OK;
00664 }
00665 
00666 
00667 /* PRBool setProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in JSValPtr vp); */
00668 NS_IMETHODIMP
00669 calDateTime::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00670                          JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
00671 {
00672     NS_ENSURE_ARG_POINTER(_retval);
00673 
00674     if (JSVAL_IS_STRING(id)) {
00675         nsDependentString const jsid(
00676             reinterpret_cast<PRUnichar const*>(
00677                 JS_GetStringChars(JSVAL_TO_STRING(id))),
00678             JS_GetStringLength(JSVAL_TO_STRING(id)));
00679         if (jsid.EqualsLiteral("jsDate") && vp) {
00680             JSObject *dobj;
00681             if (!JSVAL_IS_OBJECT(*vp) ||
00682                 !js_DateIsValid(cx, (dobj = JSVAL_TO_OBJECT(*vp)))) {
00683                 mIsValid = PR_FALSE;
00684             } else {
00685                 jsdouble utcMsec = js_DateGetMsecSinceEpoch(cx, dobj);
00686                 PRTime utcTime, thousands;
00687                 LL_F2L(utcTime, utcMsec);
00688                 LL_I2L(thousands, 1000);
00689                 LL_MUL(utcTime, utcTime, thousands);
00690 
00691                 nsresult rv = SetNativeTime(utcTime);
00692                 if (NS_SUCCEEDED(rv)) {
00693                     mIsValid = PR_TRUE;
00694                 } else {
00695                     mIsValid = PR_FALSE;
00696                 }
00697             }
00698 
00699             *_retval = PR_TRUE;
00700             return NS_SUCCESS_I_DID_SOMETHING;
00701         }
00702     }
00703     *_retval = PR_TRUE;
00704     return NS_OK;
00705 }
00706 
00707 /* void preCreate (in nsISupports nativeObj, in JSContextPtr cx, in JSObjectPtr globalObj, out JSObjectPtr parentObj); */
00708 NS_IMETHODIMP
00709 calDateTime::PreCreate(nsISupports *nativeObj, JSContext * cx,
00710                        JSObject * globalObj, JSObject * *parentObj)
00711 {
00712     return NS_ERROR_NOT_IMPLEMENTED;
00713 }
00714 
00715 /* void create (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
00716 NS_IMETHODIMP
00717 calDateTime::Create(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj)
00718 {
00719     return NS_ERROR_NOT_IMPLEMENTED;
00720 }
00721 
00722 /* void postCreate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
00723 NS_IMETHODIMP
00724 calDateTime::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj)
00725 {
00726     return NS_ERROR_NOT_IMPLEMENTED;
00727 }
00728 
00729 /* PRBool addProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in JSValPtr vp); */
00730 NS_IMETHODIMP
00731 calDateTime::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00732                          JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
00733 {
00734     return NS_ERROR_NOT_IMPLEMENTED;
00735 }
00736 
00737 /* PRBool delProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in JSValPtr vp); */
00738 NS_IMETHODIMP
00739 calDateTime::DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00740                          JSObject * obj, jsval id, jsval * vp, PRBool *_retval)
00741 {
00742     return NS_ERROR_NOT_IMPLEMENTED;
00743 }
00744 
00745 /* PRBool enumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
00746 NS_IMETHODIMP
00747 calDateTime::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00748                        JSObject * obj, PRBool *_retval)
00749 {
00750     return NS_ERROR_NOT_IMPLEMENTED;
00751 }
00752 
00753 /* PRBool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
00754 NS_IMETHODIMP
00755 calDateTime::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00756                           JSObject * obj, PRUint32 enum_op, jsval * statep, jsid *idp, PRBool *_retval)
00757 {
00758     return NS_ERROR_NOT_IMPLEMENTED;
00759 }
00760 
00761 /* PRBool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in PRUint32 flags, out JSObjectPtr objp); */
00762 NS_IMETHODIMP
00763 calDateTime::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00764                         JSObject * obj, jsval id, PRUint32 flags,
00765                         JSObject * *objp, PRBool *_retval)
00766 {
00767     NS_ENSURE_ARG_POINTER(objp);
00768     NS_ENSURE_ARG_POINTER(_retval);
00769 
00770     if (JSVAL_IS_STRING(id)) {
00771         JSString *str = JSVAL_TO_STRING(id);
00772         nsDependentString const name(
00773             reinterpret_cast<PRUnichar const*>(JS_GetStringChars(str)),
00774             JS_GetStringLength(str));
00775         if (name.EqualsLiteral("jsDate")) {
00776             *_retval = JS_DefineUCProperty(cx, obj, JS_GetStringChars(str),
00777                                            JS_GetStringLength(str),
00778                                            JSVAL_VOID,
00779                                            nsnull, nsnull, 0);
00780             *objp = obj;
00781             return *_retval ? NS_OK : NS_ERROR_FAILURE;
00782         }
00783     }
00784 
00785     *_retval = PR_TRUE;
00786     return NS_OK;
00787 }
00788 
00789 /* PRBool convert (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 type, in JSValPtr vp); */
00790 NS_IMETHODIMP
00791 calDateTime::Convert(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00792                      JSObject * obj, PRUint32 type, jsval * vp, PRBool *_retval)
00793 {
00794     return NS_ERROR_NOT_IMPLEMENTED;
00795 }
00796 
00797 /* void finalize (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
00798 NS_IMETHODIMP
00799 calDateTime::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj)
00800 {
00801     return NS_ERROR_NOT_IMPLEMENTED;
00802 }
00803 
00804 /* PRBool checkAccess (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in PRUint32 mode, in JSValPtr vp); */
00805 NS_IMETHODIMP
00806 calDateTime::CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00807                          JSObject * obj, jsval id, PRUint32 mode, jsval * vp, PRBool *_retval)
00808 {
00809     return NS_ERROR_NOT_IMPLEMENTED;
00810 }
00811 
00812 /* PRBool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
00813 NS_IMETHODIMP
00814 calDateTime::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00815                   JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, PRBool *_retval)
00816 {
00817     return NS_ERROR_NOT_IMPLEMENTED;
00818 }
00819 
00820 /* PRBool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
00821 NS_IMETHODIMP
00822 calDateTime::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00823                        JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, PRBool *_retval)
00824 {
00825     return NS_ERROR_NOT_IMPLEMENTED;
00826 }
00827 
00828 /* PRBool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal val, out PRBool bp); */
00829 NS_IMETHODIMP
00830 calDateTime::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00831                          JSObject * obj, jsval val, PRBool *bp, PRBool *_retval)
00832 {
00833     return NS_ERROR_NOT_IMPLEMENTED;
00834 }
00835 
00836 #if defined MOZILLA_1_8_BRANCH
00837 /* PRUint32 mark (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in voidPtr arg); */
00838 NS_IMETHODIMP
00839 calDateTime::Mark(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
00840                   JSObject * obj, void * arg, PRUint32 *_retval)
00841 #else
00842 /* void trace (in nsIXPConnectWrappedNative wrapper, in JSTracePtr trc, in JSObjectPtr obj); */
00843 NS_IMETHODIMP
00844 calDateTime::Trace(nsIXPConnectWrappedNative *wrapper, JSTracer *trc, JSObject *obj)
00845 #endif
00846 {
00847     return NS_ERROR_NOT_IMPLEMENTED;
00848 }
00849 
00850 /* PRBool equality(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal val); */
00851 NS_IMETHODIMP
00852 calDateTime::Equality(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
00853                       JSObject *obj, jsval val, PRBool *_retval)
00854 {
00855     return NS_ERROR_NOT_IMPLEMENTED;
00856 }
00857 
00858 /* JSObjectPtr outerObject(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
00859 NS_IMETHODIMP
00860 calDateTime::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
00861                          JSObject *obj, JSObject **_retval)
00862 {
00863     return NS_ERROR_NOT_IMPLEMENTED;
00864 }
00865 
00866 /* JSObjectPtr innerObject(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
00867 NS_IMETHODIMP
00868 calDateTime::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
00869                          JSObject *obj, JSObject **_retval)
00870 {
00871     return NS_ERROR_NOT_IMPLEMENTED;
00872 }