⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datetime.c

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 C
字号:
//%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.////==============================================================================////%//////////////////////////////////////////////////////////////////////////////*!  \file datetime.c  \brief Native CMPIDateTime implementation.  This is the native CMPIDateTime implementation as used for remote  providers. It reflects the well-defined interface of a regular  CMPIDateTime, however, it works independently from the management broker.  It is part of a native broker implementation that simulates CMPI data  types rather than interacting with the entities in a full-grown CIMOM.  \author Frank Scheffler*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <Pegasus/Provider/CMPI/cmpipl.h>#ifdef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM#define _ALL_SOURCE#endif#include <sys/time.h>#ifdef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM#undef _ALL_SOURCE#endif#include "mm.h"#include "native.h"#ifdef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM#define atoll(X) strtoll(X, NULL, 10)#endif// Adding this to the POSIX 1970 microseconds epoch produces a 1 BCE epoch// as used by CIMDateTime. -V 5885// This POSIX_1970_EPOCH_OFFSET value should be same as the // POSIX_1970_EPOCH_OFFSET value found in CIMDateTime.cpp// ATTN: Need to find the way to sync changes made to POSIX_1970_EPOCH_OFFSET// value in CIMDateTime.cpp here.static const CMPIUint64 POSIX_1970_EPOCH_OFFSET  =                          (CMPIUint64)(62167219200000000);//! Native extension of the CMPIDateTime data type./*!  This structure stores the information needed to represent time for  CMPI providers. */struct native_datetime {	CMPIDateTime dt;	/*!< the inheriting data structure  */	int mem_state;		/*!< states, whether this object is				  registered within the memory mangagement or				  represents a cloned object */	CMPIUint64 msecs;	/*!< microseconds since 01/01/1970 00:00  */	CMPIBoolean interval;	/*!< states if the date-time object is to be				  treated as an interval or as absolute time */};static struct native_datetime * __new_datetime ( int,						 CMPIUint64,						 CMPIBoolean,						 CMPIStatus * );/****************************************************************************///! Releases a previously cloned CMPIDateTime object from memory./*!  To achieve this, the object is simply added to the thread-based memory  management to be freed later.  \param dt the object to be released  \return CMPI_RC_OK. */static CMPIStatus __dtft_release ( CMPIDateTime * dt ){	struct native_datetime * ndt = (struct native_datetime *) dt;	if ( ndt->mem_state == TOOL_MM_NO_ADD ) {		ndt->mem_state = TOOL_MM_ADD;		tool_mm_add ( ndt );		CMReturn ( CMPI_RC_OK );	}	CMReturn ( CMPI_RC_ERR_FAILED );}//! Clones an existing CMPIDateTime object./*!  The function simply calls __new_datetime() with the data fields  extracted from dt.  \param dt the object to be cloned  \param rc return code pointer  \return a copy of the given CMPIDateTime object that won't be freed  from memory before calling __dtft_release(). */static CMPIDateTime * __dtft_clone ( CONST CMPIDateTime * dt, CMPIStatus * rc ){	struct native_datetime * ndt   = (struct native_datetime *) dt;	struct native_datetime * new = __new_datetime ( TOOL_MM_NO_ADD,							ndt->msecs,							ndt->interval,							rc );	return (CMPIDateTime *) new;}//! Extracts the binary time from the encapsulated CMPIDateTime object./*!  \param dt the native CMPIDateTime to be extracted.  \param rc return code pointer  \return an amount of microseconds. */static CMPIUint64 __dtft_getBinaryFormat ( CONST CMPIDateTime * dt,					   CMPIStatus * rc ){	struct native_datetime * ndt   = (struct native_datetime *) dt;	if ( rc ) CMSetStatus ( rc, CMPI_RC_OK );	return ndt->msecs;}//! Gives back a string representation of the time object./*!  \param dt the native CMPIDateTime to be converted.  \param rc return code pointer  \return a string that has one of the following formats:  - yyyymmddhhmmss.mmmmmmsutc (for absolute times)  - ddddddddhhmmss.mmmmmm:000 (for time intervals) */static CMPIString * __dtft_getStringFormat ( CONST CMPIDateTime * dt,					     CMPIStatus * rc ){	struct native_datetime * ndt   = (struct native_datetime *) dt;	time_t secs         = ndt->msecs / 1000000;        unsigned long usecs = ndt->msecs % 1000000;	char str_time[26];	if ( ndt->interval ) {		unsigned long mins, hrs, days;		mins  = secs / 60;		secs %= 60;		hrs   = mins / 60;		mins %= 60;		days  = hrs / 24;		hrs  %= 24;		sprintf ( str_time, "%8.8ld%2.2ld%2.2ld%2.2ld.%6.6ld:000",			   days, hrs, mins, secs, usecs );	} else {		struct tm tm_time;		char us_utc_time[11];		if ( localtime_r ( &secs, &tm_time ) == NULL ) {			if ( rc ) CMSetStatus ( rc, CMPI_RC_ERR_FAILED );			return NULL;		}		tzset ();#ifdef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM		sprintf ( us_utc_time, "%6.6ld%+4.3ld",			   usecs, ( daylight != 0 ) * 60 - timezone / 60 );#else		snprintf ( us_utc_time, 11, "%6.6ld%+4.3ld",			   usecs, ( daylight != 0 ) * 60 - timezone / 60 );#endif		strftime ( str_time, 26, "%Y%m%d%H%M%S.", &tm_time );		strcat ( str_time, us_utc_time );	}	return native_new_CMPIString ( str_time, rc );}//! States, whether the time object represents an interval./*!  \param dt the native CMPIDateTime to be checked.  \param rc return code pointer  \return zero, if it is an absolute time, non-zero for intervals. */static CMPIBoolean __dtft_isInterval ( CONST CMPIDateTime * dt, CMPIStatus * rc ){	struct native_datetime * ndt   = (struct native_datetime *) dt;	if ( rc ) CMSetStatus ( rc, CMPI_RC_OK );	return ndt->interval;}//! Creates a new native_datetime object./*!  The newly allocated object's function table is initialized to point  to the native functions in this file.  \param mm_add TOOL_MM_ADD for a regular object, TOOL_MM_NO_ADD for  cloned ones  \param msecs the binary time to be stored  \param interval the interval flag to be stored  \param rc return code pointer  \return a fully initialized native_datetime object pointer. */static struct native_datetime * __new_datetime ( int mm_add,						 CMPIUint64 msecs,						 CMPIBoolean interval,						 CMPIStatus * rc ){	static CMPIDateTimeFT dtft = {		NATIVE_FT_VERSION,		__dtft_release,		__dtft_clone,		__dtft_getBinaryFormat,		__dtft_getStringFormat,		__dtft_isInterval	};	static CMPIDateTime dt = {		"CMPIDateTime",		&dtft	};	struct native_datetime * ndt =		(struct native_datetime *)		tool_mm_alloc ( mm_add, sizeof ( struct native_datetime ) );	ndt->dt        = dt;	ndt->mem_state = mm_add;	ndt->msecs     = msecs;	ndt->interval  = interval;	if ( rc ) CMSetStatus ( rc, CMPI_RC_OK );	return ndt;}//! Creates a native CMPIDateTime representing the current time./*!  This function calculates the current time and stores it within  a new native_datetime object.  \param rc return code pointer  \return a pointer to a native CMPIDateTime. */// ATTN: This code is copied from actual implementation of  CIMDateTime::// getCurrentDateTime(). Need to find some way to sync the changes made to // CIMDateTime::getCurrentDateTime() here. -V 5885CMPIDateTime * native_new_CMPIDateTime ( CMPIStatus * rc ){    // Get sec and usec:    time_t sec;    CMPIUint64 usec;    // ATTN: if this fails on your platform, use time() to obtain the    // sec element and set usec to zero.    struct timeval tv;#if defined(PEGASUS_OS_VMS)    void *tz = NULL;#else    struct timezone tz;#endif    gettimeofday(&tv, &tz);    sec = tv.tv_sec;    usec = (CMPIUint64) tv.tv_usec;    // Get the localtime    struct tm* tmval;    struct tm tmvalBuffer;    tmval = localtime_r(&sec, &tmvalBuffer);    // Calculate minutes East of GMT.    int tzMinutesEast;    {# if defined(PEGASUS_OS_SOLARIS)        tzMinutesEast =            -(int)((tmval->tm_isdst > 0 && daylight) ? altzone : timezone) / 60;# elif defined(PEGASUS_OS_HPUX)        tzMinutesEast = - (int) timezone / 60;        if ((tmval->tm_isdst > 0) && daylight)        {            // ATTN: It is unclear how to determine the DST offset.            // Assume 1 hour.            tzMinutesEast += 60;        }# elif defined(PEGASUS_OS_LINUX) || defined(PEGASUS_OS_VMS)        tzMinutesEast = (int) tmval->tm_gmtoff/60;# else        tzMinutesEast = -tz.tz_minuteswest;        if (tz.tz_dsttime > 0)        {            // ATTN: It is unclear how to determine the DST offset.            // Assume 1 hour.            tzMinutesEast += 60;        }# endif    }    usec = POSIX_1970_EPOCH_OFFSET +        (CMPIUint64)(sec + tzMinutesEast * 60) * (CMPIUint64) 1000000 +        (CMPIUint64) usec;    return (CMPIDateTime *) __new_datetime ( TOOL_MM_ADD,						 usec,						 0,						 rc );}//! Creates a native CMPIDateTime given a fixed binary time./*!  This calls is simply passed on to __new_datetime().  \param time fixed time-stamp in microseconds  \param interval states, if the time-stamp is to be treated as interval  \param rc return code pointer  \return a pointer to a native CMPIDateTime.  \sa __dtft_getBinaryFormat() */CMPIDateTime * native_new_CMPIDateTime_fromBinary ( CMPIUint64 time,						    CMPIBoolean interval,						    CMPIStatus * rc ){	return (CMPIDateTime *) __new_datetime ( TOOL_MM_ADD,						 time,						 interval,						 rc );}//! Creates a native CMPIDateTime given a fixed time in string representation./*!  This function assumes the given string to have one of the following formats:  - for absolute times: yyyymmddhhmmss.mmmmmmsutc  - for time intervals: ddddddddhhmmss.mmmmmm:000  \param string the time to be converted into internal representation  \param rc return code pointer  \return a pointer to a native CMPIDateTime.  \sa __dtft_getStringFormat() */CMPIDateTime * native_new_CMPIDateTime_fromChars ( const char * string,						   CMPIStatus * rc ){	CMPIUint64 msecs;	CMPIBoolean interval = ( string[21] == ':' );	char * str = strdup ( string );	str[21] = 0;	msecs  = atoll ( str + 15 );	str[14] = 0;	msecs += atoll ( str + 12 ) * 1000000;	str[12] = 0;	msecs += atoll ( str + 10 ) * 1000000 * 60;	str[10] = 0;	msecs += atoll ( str + 8 )  * 1000000 * 60 * 60;	str[8]  = 0;	if ( interval ) {		msecs += atoll ( str )  * 1000000 * 60 * 60 * 24;	} else {		struct tm tmp;		memset ( &tmp, 0, sizeof ( struct tm ) );		tzset ();#ifndef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM		tmp.tm_gmtoff = timezone;#endif		tmp.tm_isdst  = daylight;		tmp.tm_mday   = atoi ( str + 6 );		str[6] = 0;		tmp.tm_mon    = atoi ( str + 4 ) - 1;		str[4] = 0;		tmp.tm_year   = atoi ( str ) - 1900;		msecs += (CMPIUint64) mktime ( &tmp ) * 1000000;	}	free ( str );	return (CMPIDateTime *)		__new_datetime ( TOOL_MM_ADD, msecs, interval, rc );}/****************************************************************************//*** Local Variables:  ***//*** mode: C           ***//*** c-basic-offset: 8 ***//*** End:              ***/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -