Return to CIMDateTime.cpp CVS log | Up to [Pegasus] / pegasus / src / Pegasus / Common |
File: [Pegasus] / pegasus / src / Pegasus / Common / CIMDateTime.cpp
(download)
Revision: 1.67, Fri Feb 3 19:07:53 2006 UTC (18 years, 5 months ago) by kumpf Branch: MAIN CVS Tags: TASK_PEP233_EmbeddedInstSupport-merge_out_trunk, TASK-PEP250_RPMProvider-root, TASK-PEP250_RPMProvider-merged_out_to_branch, TASK-PEP250_RPMProvider-merged_out_from_trunk, TASK-PEP250_RPMProvider-merged_in_to_trunk, TASK-PEP250_RPMProvider-merged_in_from_branch, TASK-PEP250_RPMProvider-branch, TASK-PEP245_CimErrorInfrastructure-root, TASK-PEP245_CimErrorInfrastructure-merged_out_to_branch, TASK-PEP245_CimErrorInfrastructure-merged_out_from_trunk, TASK-PEP245_CimErrorInfrastructure-merged_in_to_trunk, TASK-PEP245_CimErrorInfrastructure-merged_in_from_branch, TASK-PEP245_CimErrorInfrastructure-branch, TASK-PEP241_OpenPegasusStressTests-root, TASK-PEP241_OpenPegasusStressTests-merged_out_to_branch, TASK-PEP241_OpenPegasusStressTests-merged_out_from_trunk, TASK-PEP241_OpenPegasusStressTests-merged_in_to_trunk, TASK-PEP241_OpenPegasusStressTests-merged_in_from_branch, TASK-PEP241_OpenPegasusStressTests-branch, RELEASE_2_5_5-RC2, RELEASE_2_5_5-RC1, RELEASE_2_5_5, RELEASE_2_5_4-RC2, RELEASE_2_5_4-RC1, RELEASE_2_5_4, RELEASE_2_5_3-RC1, RELEASE_2_5_3, RELEASE_2_5_2-RC1, RELEASE_2_5_2, RELEASE_2_5_1-RC1, RELEASE_2_5_1, RELEASE_2_5-root, RELEASE_2_5-branch Changes since 1.66: +187 -407 lines BUG#: 4742 TITLE: CIMDateTime mishandles leap years DESCRIPTION: Refactor the logic for converting CIMDateTime to and from microseconds, and fix a problem with the handling of leap years in this area. |
//%2006//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation, The Open Group. // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; Symantec Corporation; The Open Group. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //============================================================================== // Author: Mike Brasher (mbrasher@bmc.com) // // Modified By: Sushma Fernandes, Hewlett-Packard Company // (sushma_fernandes@hp.com) // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) // Carol Ann Krug Graves, Hewlett-Packard Company // (carolann_graves@hp.com) // Willis White (whiwill@ibm.com) PEP #192 // Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com) // //%///////////////////////////////////////////////////////////////////////////// #include <time.h> #include <math.h> #include <errno.h> #include "CIMDateTime.h" #include "InternalException.h" #include <Pegasus/Common/AutoPtr.h> #include <Pegasus/Common/Tracer.h> #include <Pegasus/Common/MessageLoader.h> //l10n #include <Pegasus/Common/PegasusAssert.h> #if defined(PEGASUS_OS_TYPE_WINDOWS) # include <Pegasus/Common/CIMDateTimeWindows.cpp> #elif defined(PEGASUS_OS_TYPE_UNIX) # include <Pegasus/Common/CIMDateTimeUnix.cpp> #elif defined(PEGASUS_OS_TYPE_NSK) # include <Pegasus/Common/CIMDateTimeNsk.cpp> #elif defined(PEGASUS_OS_VMS) # include <Pegasus/Common/CIMDateTimeVms.cpp> #else # error "Unsupported platform" #endif PEGASUS_USING_STD; PEGASUS_NAMESPACE_BEGIN #define PEGASUS_ARRAY_T CIMDateTime # include "ArrayImpl.h" #undef PEGASUS_ARRAY_T // ATTN: P3 KS 04/17/02 Need methods for determining inequalities. // ATTN: P3 KS 04/17/02 Need methods for extracting components (e.g., minutes, hours)? // ATTN: P3 KS 04/17/02 Needs constructor that creates from individual elements(year,...) static const char _NULL_INTERVAL_TYPE_STRING[] = "00000000000000.000000:000"; static const char _NULL_DATE_TYPE_STRING[] = "00000000000000.000000-000"; static const Uint64 _TEN_THOUSAND_YEARS = PEGASUS_UINT64_LITERAL(315569520000000000); static const Uint64 _HUNDRED_MILLION_DAYS = PEGASUS_UINT64_LITERAL(8640000000000000000); static const Uint64 _ONE_DAY = PEGASUS_UINT64_LITERAL(86400000000); static const Uint64 _ONE_HOUR = PEGASUS_UINT64_LITERAL(3600000000); static const Uint64 _ONE_MINUTE = 60000000; static const Uint64 _ONE_SECOND = 1000000; static const Uint32 _DAYS_IN_YEAR_0 = 366; // The number of days preceding the (zero-based) specified month (for // non-leap years) static const Uint32 _MONTH_DAYS[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; /* the CIMDateTimeRep class holds the data for the CIMDateTime class as it's protected data members.It also allows for "setting" and "getting" of individual components of date time. */ class CIMDateTimeRep { public: String microSec; String seconds; String minutes; String hours; String days; String month; String year; String utcOffSet; enum { FORMAT_LENGTH = 25 }; // // Length of the string required to store only the date and time without // the UTC sign and UTC offset. // Format is yyyymmddhhmmss. // Note : The size does not include the null byte. // enum { DATE_TIME_LENGTH = 14 }; // // Length of the string required to store the formatted date and time // Format is yyyy:mm:dd:hh:mm:ss. // enum { FORMATTED_DATE_TIME = 20 }; //char buffer_day [5]; // sprintf(yearbuf, "%4d", (days_rem+1)); // day of the month is never 0 (1-31) // ye_mo_da = ye_mo.append(buffer_day); char data[FORMAT_LENGTH + 1]; /* Checks for correctness and sets the MicroSeconds value of CIMDateTimeRep */ Uint16 set_microSec(const String & mS); /* Checks for correctness and sets the UTC offset of CIMDateTimeRep */ Boolean set_utcOffSet(const String & uOff); /*Changes the CIMDateTimeRep data member data[] . @param value - value to be inserted into data[] @param index - position in data[] to start inserting the value @param size - size of the value paramiter (number of characters */ void set_data(const String & value, Uint32 index, Uint32 size); /* these set functions are not used yet. when they become used the enum CIMDateTime::Field should be moved to CIMDateTimeRep */ void set_seconds(const String & sec); void set_minutes(const String & min); void set_hours(const String & ho); void set_days(const String & da); void set_month(const String & mon); void set_year(const String & ye); void copy(const CIMDateTimeRep * cTR); }; /* this method copies the all the information from one CIMDateTimeRep to another */ void CIMDateTimeRep::copy(const CIMDateTimeRep * cTR) { //cout << "Start of Rep::copy" << endl; microSec = cTR->microSec; seconds = cTR->seconds; minutes = cTR->minutes; hours = cTR->hours; days = cTR->days; month = cTR->month; year = cTR->year; utcOffSet = cTR->utcOffSet; memcpy(data, cTR->data, sizeof(data)); //cout << "end of Rep::copy" << endl <<endl; } /* set_microSec checks the format of the string that will be used as the micro seconds value. If the format is correct it sets the micro seconds value */ Uint16 CIMDateTimeRep::set_microSec(const String & mS) { // String fin_data = sum_data.append(mS.subString(21,4)); //cout << "begining of set_microSec" << endl; Uint32 ast_post; ast_post = mS.find("*"); if (ast_post == PEG_NOT_FOUND) { set_data(mS, 15, 6); microSec = mS; return 2; } // cout << "after find block" << endl; Uint32 sub_len = 6 - ast_post; String ast = "******"; String in_comp = mS.subString(ast_post, sub_len); if (!String::compare(in_comp, ast, sub_len)){ set_data(mS, 15, 6); microSec = mS; return 0; } else{ // cout << "error in set_microSec - this is the value " << mS << endl; Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "Error in CIMDateTimeRep::set_microSec - '*' was found in micor second string"); return 1; } } /*set_data set the data member CIMDateTimeRep::set_data */ void CIMDateTimeRep::set_data(const String & value, Uint32 index, Uint32 size) { for (Uint32 i=0; i < size; i++) { data[index+i] = (char) value[i]; } } /* the following 6 methods are not used */ void CIMDateTimeRep::set_seconds(const String & sec) { seconds = sec; } void CIMDateTimeRep::set_minutes(const String & min) { minutes = min; } void CIMDateTimeRep::set_hours(const String & ho) { hours = ho; } void CIMDateTimeRep::set_days(const String & da) { days = da; } void CIMDateTimeRep::set_month(const String & mon) { month = mon; } void CIMDateTimeRep::set_year(const String & ye) { year = ye; } /* set_utcOffSet checks the format of the string representing the UTC offset if it is correct it sets the data member CIMDateTimeRep::utcOffSet */ Boolean CIMDateTimeRep::set_utcOffSet(const String & uOffSet) { if (uOffSet.size() != 4) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "The size of the UTC offset is %d but is but it should be 4", uOffSet.size()); return false; } Char16 ch_one = uOffSet[0]; if (ch_one != ':' && ch_one != '+' && ch_one != '-') { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "The UTC off set must begin with a ':' or '+' or '-'. The value of the first character of UTC offset is %u", static_cast<Uint16>(ch_one)); return false; } // the UTC must not have asterisks in it Uint32 spot = uOffSet.find("*"); if (spot != PEG_NOT_FOUND) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "'*' was found in the UTC offset this is not allowed"); return false; } String uOff_num = uOffSet.subString(1,3); for (int i=0; i < 3; i++) { if ((uOff_num[i] < '0') || (uOff_num[i] > '9')) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "Format is wrong - UTC offset contains non digit character."); return false; } } // intervals (:) must have 000 utc offset if ((ch_one == (char)':') && !String::equal(uOff_num, "000")) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "Trying to incorrectly set a intervals time zone"); return false; } utcOffSet = uOffSet; set_data(uOffSet, 21, 4); // change _rep->data to reflect changes made return true; } /*Constructor */ CIMDateTime::CIMDateTime() { _rep = new CIMDateTimeRep(); AutoPtr<CIMDateTimeRep> rep(_rep); clear(); rep.release(); } /*Takes properly formated string and creates a CIMDateTime out of it */ CIMDateTime::CIMDateTime(const String & str) { _rep = new CIMDateTimeRep(); AutoPtr<CIMDateTimeRep> rep(_rep); if (!_set(str)) { throw InvalidDateTimeFormatException(); } rep.release(); } /*Copy constructor */ CIMDateTime::CIMDateTime(const CIMDateTime& x) { _rep = new CIMDateTimeRep(); AutoPtr<CIMDateTimeRep> rep(_rep); _rep->copy(x._rep); rep.release(); } CIMDateTime::CIMDateTime(Uint64 microSec, Boolean interval) { if (microSec >= _TEN_THOUSAND_YEARS && !interval) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "Cannot create a CIMDateTime time stamp beyond the year 10,000"); throw DateTimeOutOfRangeException(parms); } if (microSec >= _HUNDRED_MILLION_DAYS && interval) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "Cannot create a CIMDateTime interval greater than 100 million " "days"); throw DateTimeOutOfRangeException(parms); } Uint32 year = 0; Uint32 month = 0; Uint32 day = 0; Uint32 hour = 0; Uint32 minute = 0; Uint32 second = 0; Uint32 microsecond = 0; char buffer[26]; microsecond = microSec % 1000000; microSec /= 1000000; second = microSec % 60; microSec /= 60; minute = microSec % 60; microSec /= 60; hour = microSec % 24; microSec /= 24; if (interval) { day = microSec; sprintf( buffer, "%08u%02u%02u%02u.%06u:000", day, hour, minute, second, microsecond); } else { Uint32 daysRemaining = microSec; if (daysRemaining >= _DAYS_IN_YEAR_0) { const Uint32 _DAYS_IN_400_YEARS = 146097; const Uint32 _DAYS_IN_100_YEARS = 36524; const Uint32 _DAYS_IN_4_YEARS = 1461; // Account for year 0 year = 1; daysRemaining -= _DAYS_IN_YEAR_0; year += (daysRemaining / _DAYS_IN_400_YEARS) * 400; daysRemaining -= daysRemaining / _DAYS_IN_400_YEARS * _DAYS_IN_400_YEARS; year += (daysRemaining / _DAYS_IN_100_YEARS) * 100; daysRemaining -= daysRemaining / _DAYS_IN_100_YEARS * _DAYS_IN_100_YEARS; year += (daysRemaining / _DAYS_IN_4_YEARS) * 4; daysRemaining -= daysRemaining / _DAYS_IN_4_YEARS * _DAYS_IN_4_YEARS; year += daysRemaining / 365; daysRemaining -= daysRemaining / 365 * 365; } // Determine whether this is a leap year Boolean leapYear = (((year%4 == 0) && (year%100 != 0)) || (year%400 == 0)); // Calculate the month for (Uint32 m = 12; m > 0; m--) { Uint32 monthDays = _MONTH_DAYS[m-1]; if ((m > 2) && leapYear) { monthDays += 1; } if (daysRemaining >= monthDays) { month = m; daysRemaining -= monthDays; break; } } // Calculate the day (days of the month start with 1) day = daysRemaining + 1; sprintf( buffer, "%04u%02u%02u%02u%02u%02u.%06u+000", year, month, day, hour, minute, second, microsecond); } _rep = new CIMDateTimeRep(); AutoPtr<CIMDateTimeRep> rep(_rep); if (!_set(String(buffer))) { PEGASUS_ASSERT(false); } rep.release(); } /*copies CIMDateTimeRep from passed in paramiter to the the callers CIMDateTimeRep effectivly copies value of one CIMDateTime to another. All data in held in CIMDateTimeRep */ CIMDateTime& CIMDateTime::operator=(const CIMDateTime& x) { //cout << "in copy constructor" << cout; if (&x != this){ _rep->copy(x._rep); } //memcpy(_rep->data, x._rep->data, sizeof(_rep->data)); return *this; } CIMDateTime::~CIMDateTime() { delete _rep; } /* retruns a string holding the CIMDateTime value */ String CIMDateTime::toString () const { return String (_rep->data); } /* sets a CIMDateTime to a zero valued interval */ void CIMDateTime::clear() { //cout << "this is the start of the clear method" << endl; strcpy(_rep->data, _NULL_INTERVAL_TYPE_STRING); String blank = ""; String str = String("000000"); Uint16 dum = _rep->set_microSec(str); _rep->set_seconds("00"); _rep->set_minutes("00"); _rep->set_hours("00"); _rep->set_days("00"); _rep->set_utcOffSet(String(":000")); //cout << "end of the clear method" << endl << endl; } /* this is one of the only ways to create a CIMDateTime object most of the constructors call this method. It checks the value of each filed and returns false if any of them do not have the correct format */ Boolean CIMDateTime::_set(const String & dateTimeStr) { clear(); CString dtStr = dateTimeStr.getCString(); const char* str = dtStr; // Be sure the incoming string is the proper length: if (dateTimeStr.size() != CIMDateTimeRep::FORMAT_LENGTH){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime object string is not of the proper length"); return false; } // Determine the type (date or interval); examine the 21st character; // it must be one of ':' (interval), '+' (date), or '-' (date) const Uint32 SIGN_OFFSET = 21; const Uint32 DOT_OFFSET = 14; Boolean isInterval = (dateTimeStr[SIGN_OFFSET] == ':'); if (!isInterval && dateTimeStr[SIGN_OFFSET] != '+' && dateTimeStr[SIGN_OFFSET] != '-'){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime object has an incorrect format."); return false; } // Check for the decimal place: if (dateTimeStr[DOT_OFFSET] != '.'){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "Incorrect Format - CIMDateTime object dosen't have decimal point in position 14"); return false; } // Check to see if other characters are digits or astrisks (*) for (Uint32 i = 0; i < CIMDateTimeRep::FORMAT_LENGTH; i++) { if (!((i == DOT_OFFSET) || (i == SIGN_OFFSET) || ((dateTimeStr[i] >= '0') && (dateTimeStr[i] <= '9')) || (dateTimeStr[i] == '*'))) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMdateTime object has an incorrect format."); return false; } } // Check to see if the month and day are in range (date only): String buffer; Field ans; if (!isInterval) { //get year /* need to check that the field is valid as far as astrisk (*) are concerned */ buffer = dateTimeStr.subString(0,4); ans = fieldcheck(buffer, _rep->year); if (ans == SOME_WILD_CARDS){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the string is incorrect. "); return false; } else if (ans == ONLY_WILD_CARDS) { if (!restOfFields(4,dateTimeStr)){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the string is incorrect. All fields after the year \ field should be wild cards."); return false; } } // Get the month: buffer = dateTimeStr.subString(4,2); ans = fieldcheck(buffer, _rep->month); if (ans == SOME_WILD_CARDS) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the month field is incorrect.s"); //cout << "one was returned form fieldcheck" << endl << endl; return false; // month field has both wildcards and digits } else if (ans == ONLY_DIGITS) { // month field has only digits long month = atoi(buffer.getCString()); // Allow for zero month - default value processing if (month == 0 || month > 12) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the string is incorrect. Month fild is out of range"); return false; } } else if (ans == ONLY_WILD_CARDS) { if (!restOfFields(6,dateTimeStr)){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the string is incorrect. All fields after the month \ field should ve wild cards."); return false; } } // Get the day: buffer = dateTimeStr.subString(6,2); ans = fieldcheck(buffer, _rep->days); if (ans == SOME_WILD_CARDS) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the day field is incorrect."); return false; // month field has both wildcards and digits } else if (ans == ONLY_DIGITS) { // month field has only digits long day = atoi(buffer.getCString()); // Allow for zero day - 0 "day" values are only allowed for default object /*ATTN: this does not check for the number of days in a particular month */ if (day == 0 || day > 31){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the string is incorrect. Day field is incorrect"); return false; } } else if (ans == ONLY_WILD_CARDS) { if (!restOfFields(6,dateTimeStr)){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the string is incorrect. All fields after day field \ should be only wild cards."); return false; } } //get UTC off set for a Time Stamp buffer = dateTimeStr.subString(21,4); _rep->utcOffSet = buffer; Uint32 spot = buffer.find("*"); //cout << "before if" << endl; if(spot != PEG_NOT_FOUND){ // the UTC must not have astricks in it Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the is incorrect. UTC offset should not have \ a wild card in it."); return false; } } //end of if(!interval) else{ //Object is an Interval //get days if object is an interval buffer = dateTimeStr.subString(0,8); ans = fieldcheck(buffer, _rep->days); if (ans == SOME_WILD_CARDS) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect. Day field must be have all \ wild cards or no wild cards."); return false; } else if (ans == ONLY_WILD_CARDS) { if (!restOfFields(8,dateTimeStr)){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect. All fields after day field \ should be wild cards."); return false; } } //ATTN: this block MAY not be needed // check to make sure UTC for Intervals it '000' buffer = dateTimeStr.subString(21,4); _rep->utcOffSet = buffer; if (!String::equal(_rep->utcOffSet, ":000")) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect. Can not set the \ the UTC off set of an Interval"); // cout << "interval UTC offset is worng" << endl; return false; } } //cout << "after is interval block" << endl; // Check the hours and minutes: buffer = dateTimeStr.subString(8,2); ans = fieldcheck(buffer, _rep->hours); if (ans == SOME_WILD_CARDS) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect.Hour field must have all \ wild cards or no wild cards."); return false; // hour field has both wildcards and digits } else if (ans == ONLY_DIGITS) { // hour field has only digits long hours = atoi(buffer.getCString()); if (hours > 23) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect. Hour value is out of range"); return false; } } else if (ans == ONLY_WILD_CARDS) { if (!restOfFields(10,dateTimeStr)){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect. All fields after the hour field \ should be wild cards."); return false; } } //cout << "this is after getting hours" << endl; buffer = dateTimeStr.subString(10,2); ans = fieldcheck(buffer, _rep->minutes); if (ans == SOME_WILD_CARDS) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect.Minute field must have all \ wild cards or no wild cards."); return false; // minutes field has both wildcards and digits } else if (ans == ONLY_DIGITS) { // minutes field has only digits long minutes = atoi(buffer.getCString()); if (minutes > 59) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect.Minute value is out of range"); return false; } } else if (ans == ONLY_WILD_CARDS) { if (!restOfFields(12,dateTimeStr)){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect. All fields after the minute \ field should be wild cards."); return false; } } // cout << "before getting seconds" << endl; buffer = dateTimeStr.subString(12,2); ans = fieldcheck(buffer, _rep->seconds); if (ans == SOME_WILD_CARDS) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect.Second field must have all \ wild cards or no wild cards."); return false; // seconds field has both wildcards and digits } else if (ans == ONLY_DIGITS) { // minutes field has only digits long seconds = atoi(buffer.getCString()); if (seconds > 59){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect.Minute value is out of range"); return false; } } else if (ans == ONLY_WILD_CARDS) { if (!restOfFields(14,dateTimeStr)){ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of the object is incorrect. All fields after the seconds \ field should have wild cards."); return false; } } //get micro Seconds String buffer_micro = dateTimeStr.subString(15,6); Uint32 answ = _rep->set_microSec(buffer_micro); if (answ == 1) { Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime - Format of micro seconds field is incorrect"); return false; } memcpy(_rep->data, str, sizeof(_rep->data)); return true; } /* If a field has a wild card then all the fields with lower significance should have wild cards. This method makes sure of this. */ Boolean CIMDateTime::restOfFields(Uint32 start_position,const String & inStr) { String splatCDT = "**************.******"; Uint32 placeNum = splatCDT.size() - start_position; String comp = splatCDT.subString(start_position, placeNum); String in_comp = inStr.subString(start_position, placeNum); if (String::compare(comp, in_comp)) return false; else return true; } /*this method is just a public rapper for the _set command */ void CIMDateTime::set(const String & str) { if (!_set(str)){ throw InvalidDateTimeFormatException(); } } /*public rapper for _toMicroSeconds converts object to UTC then it calculates the number of microseconds in the converted object */ Uint64 CIMDateTime::toMicroSeconds() const { CIMDateTime un_norm; //un_norm._rep = new CIMDateTimeRep(); un_norm._rep->copy(_rep); un_norm.convertToUTC(); const Uint64 norm_micSec = un_norm._toMicroSeconds(); return (norm_micSec); } // Returns the number of microseconds represented by a CIMDateTime object Uint64 CIMDateTime::_toMicroSeconds() { Uint64 microseconds = 0; // Retrieve the microseconds component from the CIMDateTime object Uint32 microsecondsSplatIndex = _rep->microSec.find('*'); Uint32 microsecondsComponent = 0; if (microsecondsSplatIndex == PEG_NOT_FOUND) { microsecondsComponent = atol(_rep->microSec.getCString()); } else if (microsecondsSplatIndex > 0) { String subMic = _rep->microSec.subString(0, microsecondsSplatIndex); microsecondsComponent = (Uint32)atol(subMic.getCString()) * (Uint32)pow((double)10,(double)(6-microsecondsSplatIndex)); } else { microsecondsComponent = 0; } microseconds += microsecondsComponent; // Retrieve the seconds component from the CIMDateTime object if (_rep->seconds.find('*') == PEG_NOT_FOUND) { Uint64 secondsComponent = atol(_rep->seconds.getCString()); microseconds += secondsComponent * 1000000; } // Retrieve the minutes component from the CIMDateTime object if (_rep->minutes.find('*') == PEG_NOT_FOUND) { Uint64 minutesComponent = atol(_rep->minutes.getCString()); microseconds += minutesComponent * _ONE_MINUTE; } // Retrieve the hours component from the CIMDateTime object if (_rep->hours.find('*') == PEG_NOT_FOUND) { Uint64 hoursComponent = atol(_rep->hours.getCString()); microseconds += hoursComponent * _ONE_HOUR; } if (isInterval()) { // Retrieve the days component from the CIMDateTime object if (_rep->days.find('*') == PEG_NOT_FOUND) { Uint64 daysComponent = atol(_rep->days.getCString()); microseconds += daysComponent * _ONE_DAY; } } else { // Retrieve the day component from the CIMDateTime object if (_rep->days.find('*') == PEG_NOT_FOUND) { Uint64 dayComponent = atol(_rep->days.getCString()); microseconds += (dayComponent-1) * _ONE_DAY; } // Retrieve the month and year components from the CIMDateTime object if (_rep->year.find('*') == PEG_NOT_FOUND) { Uint64 yearComponent = atol(_rep->year.getCString()); // Retrieve the month component from the CIMDateTime object. if (_rep->month.find('*') == PEG_NOT_FOUND) { Uint32 monthComponent = atol(_rep->month.getCString()); PEGASUS_ASSERT((monthComponent > 0) && (monthComponent < 13)); Uint32 monthDays = _MONTH_DAYS[monthComponent-1]; if ((monthComponent > 2) && ((yearComponent%400 == 0) || ((yearComponent%4 == 0) && (yearComponent%100 != 0)))) { // Add the leap day monthDays += 1; } // Convert months to days and then to microseconds microseconds += monthDays * _ONE_DAY; } if (yearComponent > 0) { // Convert years into microseconds, factoring in leap years yearComponent -= 1; microseconds += (_DAYS_IN_YEAR_0 + yearComponent/400 * 146097 + yearComponent%400/100 * 36524 + yearComponent%100/4 * 1461 + yearComponent%4 * 365) * _ONE_DAY; } } } return microseconds; } /*compare two CIMDateTime objects for equality */ Boolean operator==(const CIMDateTime& x, const CIMDateTime& y) { return x.equal (y); } /* converts Time Stamps to their UTC (GMT) representation. For Intervals it does nothing. */ void CIMDateTime::convertToUTC() { if (isInterval()) { return; //no conversion should not be done on Intervals } Uint64 normNum = 0; Uint64 un_normNum = this->_toMicroSeconds(); // Uint32 unnor = un_normNum/PEGASUS_UINT64_LITERAL(1000000000); // Uint32 runnor = un_normNum%PEGASUS_UINT64_LITERAL(1000000000); // get UTC offSet and change it in microseconds String utcOS = _rep->utcOffSet.subString(1,3); Uint32 offSet = atol((utcOS).getCString()); Uint64 offSet_hor = (offSet/60) * _ONE_HOUR; Uint64 offSet_min = (offSet%60) * _ONE_MINUTE; String mesO = "overflow has occurred in normalization"; MessageLoaderParms parmsOv("Common.CIMDateTime.UTC_OVERFLOW", "overflow has occurred during conversion to UTC"); MessageLoaderParms parmsUn("Common.CIMDateTime.UTC_UNDERFLOW", "underflow has occurred during conversion to UTC"); char sign; // Get the sign and UTC offset. sign = _rep->data[21]; //if there are no wild cards in the minute postion then the entire utc offSet //will effect the CIMDateTime value if (_rep->minutes.find('*') == PEG_NOT_FOUND) { if ( sign == '-' ) { if (_TEN_THOUSAND_YEARS < (un_normNum + (offSet_hor + offSet_min))){ // cout << " this is value " << this->toString() << endl; throw DateTimeOutOfRangeException(parmsOv); } normNum = un_normNum + (offSet_hor + offSet_min); } else{ if (un_normNum < (offSet_hor + offSet_min)) { throw DateTimeOutOfRangeException(parmsUn); } normNum = un_normNum - (offSet_hor + offSet_min); } } //if the hours section has no wild cards but the minutes section does then only on hour //position will be effected by the uct off Set else if (_rep->hours.find('*') == PEG_NOT_FOUND) { if ( sign == '-' ) { if (_TEN_THOUSAND_YEARS < (un_normNum + (offSet_hor))){ throw DateTimeOutOfRangeException(parmsOv); } normNum = un_normNum + (offSet_hor); } else{ if (un_normNum < (offSet_hor)) { throw DateTimeOutOfRangeException(parmsUn); } normNum = un_normNum - (offSet_hor); } } else{ //if this block is executed then the utc offSet has no effect on CIMDateTime value normNum = un_normNum; } CIMDateTime norm_CDT = CIMDateTime(normNum,false); this->_rep->copy(norm_CDT._rep); return; } /*returns true if object is an interval. Note: This method exists only for compatibility reasons. It is superceded by the "const" form of the method. */ Boolean CIMDateTime::isInterval() { return ((const CIMDateTime*)this)->isInterval(); } /*returns true if object is an interval */ Boolean CIMDateTime::isInterval() const { const Uint32 SIGN_OFFSET = 21; Boolean isInterval = strcmp(&_rep->data[SIGN_OFFSET], ":000") == 0 ; return isInterval; } /*compares caller to passed in paramiter for eqaulity */ Boolean CIMDateTime::equal (const CIMDateTime & x) const { if ((x.isInterval() && !this->isInterval()) || (!x.isInterval() && this->isInterval())) { throw TypeMismatchException(); } CIMDateTime current = CIMDateTime((String)_rep->data); CIMDateTime compare = CIMDateTime((String)x._rep->data); // not sure why all this is needed but const has somthing to do with it Uint32 spl_pos = current.getHighestWildCardPosition(compare); current.insert_WildCard(spl_pos); compare.insert_WildCard(spl_pos); if (current.toMicroSeconds() == compare.toMicroSeconds()) { return true; } else return false; } /*subtacts two CIMDateTime objects of like types */ Sint64 CIMDateTime::getDifference(CIMDateTime startTime, CIMDateTime finishTime) { CIMDateTime sta = startTime; CIMDateTime fin = finishTime; CIMDateTime sta_norm; CIMDateTime fin_norm; Uint64 startT_num; Uint64 finishT_num; Sint64 diff_num; /* the throwing of this expceptoin is only needed becasue of back wards compatability issues (i.e. this is the way getDifferance worked before). The operator- does not behave this way. */ if ((sta.isInterval() && (!( fin.isInterval()))) || ((!( sta.isInterval())) && fin.isInterval())) { throw InvalidDateTimeFormatException(); } Uint32 splat_pos; splat_pos = sta.getHighestWildCardPosition(fin); sta.insert_WildCard(splat_pos); fin.insert_WildCard(splat_pos); startT_num = sta.toMicroSeconds(); finishT_num = fin.toMicroSeconds(); diff_num = finishT_num - startT_num; return diff_num; } /* checks to make sure the format of a particular field in the DateTime string is correct. Returns ONLY_WILD_CARDS - field contains all wild cards SOME_WILD_CARDS - field contains some wild cards (error) ONLY_DIGITS - field contains only digits */ CIMDateTime::Field CIMDateTime::fieldcheck(const String & in_p, String & rep_field) { Uint32 post; rep_field = in_p; post = in_p.find("*"); if (post == PEG_NOT_FOUND) { return ONLY_DIGITS; } const String ast = "**********"; String comp = String(ast, in_p.size()); //creates a string of asteriks with the same length as in_p if (!String::compare(in_p, comp)) { return ONLY_WILD_CARDS; //fields is all astriks } else{ return SOME_WILD_CARDS; //error - mix of asterisk and numbers in field } } /* This method does not change the value of object, it only converts the representation form one time zone to the time zone specified. @param cdt Time Stamp object that will be converted @param utc uct-offset in minutes that represents the time zone to be converted to Returns a copy of the calling object modified to represent the same time in a different time zone. */ void CIMDateTime::setUtcOffSet(Sint32 utc) { if(this->isInterval()){ return; } MessageLoaderParms parmsOv("Common.CIMDateTime.UTC_OVERFLOW", "overflow has occurred during conversion to UTC"); MessageLoaderParms parmsUn("Common.CIMDateTime.UTC_UNDERFLOW", "underflow has occurred during conversion to UTC"); // convert CIMDateTime to microseconds. Uint64 cdt_MicroSec = this->toMicroSeconds(); Uint32 offSet = abs(utc); Uint64 offSet_hor = (offSet/60) * _ONE_HOUR; Uint64 offSet_min = (offSet%60) * _ONE_MINUTE; Uint64 cdt_MicroSecSum = 0; String sgn_offset; //Add (if utc is - ) or subtract (if utc is +) utc to/from DateTime. if (utc >= 0) { if (cdt_MicroSec < (offSet_hor + offSet_min)) { throw DateTimeOutOfRangeException(parmsOv); } cdt_MicroSecSum = cdt_MicroSec - (offSet_hor + offSet_min); sgn_offset = "+"; } else{ if (_TEN_THOUSAND_YEARS < (cdt_MicroSec + offSet_hor + offSet_min)) { throw DateTimeOutOfRangeException(parmsUn); } cdt_MicroSecSum = cdt_MicroSec + (offSet_hor + offSet_min); sgn_offset = "-"; } //Create new DateTime from sum of old DateTime and UTC and set UCT of new Date time. CIMDateTime ans = CIMDateTime(cdt_MicroSecSum, false); char utcBuff [5]; sprintf(utcBuff, "%03d", offSet); String utc_str = sgn_offset.append(String(utcBuff)); Boolean res = ans._rep->set_utcOffSet(utc_str); if (res) { this->_rep->copy(ans._rep); // set_utcOffSet worked return; } else{ Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2, "CIMDateTime::setUTCOffSet() failed"); throw InvalidDateTimeFormatException(); } } /* finds the Wild Card in the most significant position and returns that position @param cDT_s gets searched along with calling object to find the wild card in the most significant position */ Uint32 CIMDateTime::getHighestWildCardPosition(const CIMDateTime & cDT_s) { Uint32 spot_s = cDT_s.toString().find('*'); //since this return a Uint32 and PEG_NOT_FOUND=-1 can't do a Uint32 spot_f = this->toString().find('*'); // straight compare if (spot_s == PEG_NOT_FOUND && spot_f == PEG_NOT_FOUND) { //start time have more wild cards then finish time return PEG_NOT_FOUND; } else if (spot_f == PEG_NOT_FOUND) { return spot_s; } else if (spot_s == PEG_NOT_FOUND) { return spot_f; } else{ if (spot_f < spot_s) { return spot_f; } else{ return spot_s; } } } /*inserts wild cards into CIMDateTime object. @param index - position to start placing wild card characters @param cdt - object to be modified Returns a copy of calling object with wild cards starting at position index @exception InvalidDateTimeFormatException because of invalid index (see rules for wild cards) */ void CIMDateTime::insert_WildCard(Uint32 ind) { Uint32 index = ind; if (ind > 20) { index = 21; } Uint32 spot = this->toString().find('*'); if (spot == index) { CIMDateTime cur = CIMDateTime(this->toString()); return; } String splat = String("**************.******"); String cdtStr = this->toString(); String final; if (index != PEG_NOT_FOUND) { String str_cdtStr = cdtStr.subString(0, index); String sub_splat = splat.subString(index, (21-index)); //build result String cdt_Splat = str_cdtStr.append(sub_splat); final = cdt_Splat.append(this->_rep->utcOffSet); } else{ final = splat.append(this->_rep->utcOffSet); } CIMDateTime ans = CIMDateTime(final); this->_rep->copy(ans._rep); return; } CIMDateTime CIMDateTime::operator+(const CIMDateTime & cDT) const { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); CIMDateTime opt_cDT = cDT; Sint32 utc; Boolean isInt = this->isInterval(); // only interval+interval and timeStamp+interval are allowed. Therefor second operand must be interval if (!opt_cDT.isInterval()) { throw TypeMismatchException(); } Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(opt_cDT); Uint64 opt_num = opt_cDT.toMicroSeconds(); Uint64 cur_num = cur_cDT.toMicroSeconds(); Uint64 ans = opt_num + cur_num; CIMDateTime ans_cdt = CIMDateTime(ans, isInt); if (!isInt) { utc = atol((_rep->utcOffSet).getCString()); ans_cdt.setUtcOffSet(utc); } ans_cdt.insert_WildCard(splat_pos); return ans_cdt; } CIMDateTime & CIMDateTime::operator+=(const CIMDateTime & cDT) { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); CIMDateTime opt_cDT = cDT; CIMDateTime sum_cdt = cur_cDT + opt_cDT; _rep->copy(sum_cdt._rep); return *this; } CIMDateTime CIMDateTime::operator-(const CIMDateTime & cDT) const { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); CIMDateTime opt_cDT = cDT; CIMDateTime ans_cdt; Sint32 utc; Boolean cur_isIn = this->isInterval(); Boolean opt_isIn = opt_cDT.isInterval(); // only I-I, T-I and T-T are allowed if (cur_isIn && !opt_isIn) { throw TypeMismatchException(); } Uint64 opt_num = opt_cDT.toMicroSeconds(); Uint64 cur_num = cur_cDT.toMicroSeconds(); if (cur_num < opt_num) { MessageLoaderParms parmsSub("Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "Result of subtracting two CIMDateTimes would be negative."); throw DateTimeOutOfRangeException(parmsSub); } Uint64 diff = cur_num - opt_num; if ((cur_isIn && opt_isIn) || (!cur_isIn && !opt_isIn)) { //don't konw how to do logical xor ans_cdt = CIMDateTime(diff, true); } else{ ans_cdt = CIMDateTime(diff, false); utc = atol((_rep->utcOffSet).getCString()); ans_cdt.setUtcOffSet(utc); } Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(opt_cDT); ans_cdt.insert_WildCard(splat_pos); return ans_cdt; } CIMDateTime & CIMDateTime::operator-=(const CIMDateTime & cDT) { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); CIMDateTime opt_cDT = cDT; CIMDateTime dif_cdt = cur_cDT - opt_cDT; _rep->copy(dif_cdt._rep); return *this; } CIMDateTime CIMDateTime::operator*(Uint64 num) const { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); if (!this->isInterval()){ throw TypeMismatchException(); } Uint64 cur_num = cur_cDT.toMicroSeconds(); Uint64 prod = cur_num * num; CIMDateTime prod_cdt = CIMDateTime(prod, true); CIMDateTime dummy; Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(dummy); prod_cdt.insert_WildCard(splat_pos); return prod_cdt; } CIMDateTime & CIMDateTime::operator*=(Uint64 num) { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); CIMDateTime prod_cdt = cur_cDT * num; _rep->copy(prod_cdt._rep); return *this; } CIMDateTime CIMDateTime::operator/(Uint64 num) const { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); if (!(this->isInterval())){ MessageLoaderParms parmsD("Common.CIMDateTime.INVALID_OPERATION_DIV_INT", "Can not divide a TimeStamp by an integer"); throw TypeMismatchException(parmsD); } if (num == 0) { MessageLoaderParms parmsZ("Common.CIMDateTime.INVALID_OPERATION_DIV_ZERO", "Can not divide CIMDateTime by zero"); throw Exception(parmsZ); } Uint64 cur_num = cur_cDT.toMicroSeconds(); Uint64 prod = cur_num/num; CIMDateTime prod_cdt = CIMDateTime(prod, true); CIMDateTime dummy; Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(CIMDateTime(dummy)); prod_cdt.insert_WildCard(splat_pos); return prod_cdt; } CIMDateTime & CIMDateTime::operator/=(Uint64 num) { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); CIMDateTime ans = cur_cDT/num; _rep->copy(ans._rep); return *this; } Uint64 CIMDateTime::operator/(const CIMDateTime & cDT) const { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); CIMDateTime opt_cDT = cDT; if (!cur_cDT.isInterval() || !opt_cDT.isInterval()) { MessageLoaderParms parmsMM("Common.CIMDateTime.INVALID_OPERATION_DIV_TS", "Can not divide two CIMDateTime objects if one of them is a TimeStamp"); throw TypeMismatchException(parmsMM); } Uint64 opt_num = opt_cDT.toMicroSeconds(); Uint64 cur_num = cur_cDT.toMicroSeconds(); if (opt_num == 0) { MessageLoaderParms parmsDZ("Common.CIMDateTime.INVALID_OPERATION_DIV_ZERO_CDT", "Trying to divide a CIMDateTime object by a zero value CIMDateTime object"); throw Exception(parmsDZ); } Uint64 ans = cur_num/opt_num; return ans; } Boolean CIMDateTime::operator<(const CIMDateTime & cDT) const { CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data)); CIMDateTime opt_cDT = cDT; if ((!cur_cDT.isInterval() && opt_cDT.isInterval()) || (cur_cDT.isInterval() && !opt_cDT.isInterval())) { MessageLoaderParms parms("Common.CIMDateTime.INVALID_OPERATION_COMP_DIF", "Trying to compare CIMDateTime objects of differing types"); throw TypeMismatchException(parms); } Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(opt_cDT); opt_cDT.insert_WildCard(splat_pos); cur_cDT.insert_WildCard(splat_pos); Uint64 opt_num = opt_cDT.toMicroSeconds(); Uint64 cur_num = cur_cDT.toMicroSeconds(); if (cur_num < opt_num) { return true; } else{ return false; } } Boolean CIMDateTime::operator<=(const CIMDateTime & cDT) const { CIMDateTime cur = CIMDateTime((String)(this->_rep->data)); if ((cur < cDT) || (cur == cDT)) { return true; } else{ return false; } } Boolean CIMDateTime::operator>(const CIMDateTime & cDT) const { CIMDateTime cur = CIMDateTime((String)(this->_rep->data)); if ((!(cur < cDT)) && (!(cur == cDT))) { return true; } else{ return false; } } Boolean CIMDateTime::operator>=(const CIMDateTime & cDT) const { CIMDateTime cur = CIMDateTime((String)(this->_rep->data)); if (!(cur < cDT)) { return true; } else{ return false; } } Boolean CIMDateTime::operator!=(const CIMDateTime & cDT) const { CIMDateTime cur = CIMDateTime((String)(this->_rep->data)); if (!(cur == cDT)) { return true; } else{ return false; } } PEGASUS_NAMESPACE_END
No CVS admin address has been configured |
Powered by ViewCVS 0.9.2 |