STATS.CPP

// --stats.cpp------------------------------------------------------------------ 
//
// C wrappers for the C++ stats library.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------

#include "edk.h"
#include "fldmtrc.h"
#include "jswindow.h"
#include "stats.chk"

extern "C" {

#define INT64_FROM_FILETIME(li) (*((__int64 *)&(li)))
#define FILETIME_FROM_INT64(li) (*((FILETIME *)&(li)))


//$--HrOpenFolderMetrics--------------------------------------------------------
// Prepares a folder for retreiving metrics.
// -----------------------------------------------------------------------------
HRESULT HrOpenFolderMetrics( // RETURNS: HRESULT
IN LPMAPIFOLDER lpFolder, // pointer to target mapi folder
OUT HFLDMTRC *phFolderMetrics) // receives handle to folder metric
{
HRESULT hr = NOERROR;

DEBUGPUBLIC("HrOpenFolderMetrics()\n");

hr = CHK_HrOpenFolderMetrics(lpFolder, phFolderMetrics);
if (FAILED(hr))
RETURN(hr);

if (phFolderMetrics == NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

*phFolderMetrics = (HFLDMTRC *)new CFolderMetrics();

if (*phFolderMetrics == NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}


hr = ((CFolderMetrics *)*phFolderMetrics)->HrReset(lpFolder);

if (FAILED(hr))
{
goto cleanup;
}

cleanup:

if ((FAILED(hr)) && (*phFolderMetrics != NULL))
{
delete (CFolderMetrics *)*phFolderMetrics;

*phFolderMetrics = NULL;
}

RETURN(hr);
}



//$--HrGetFolderMetrics---------------------------------------------------------
// Retrieves the metrics (size, longest wait, total wait) from a folder.
// -----------------------------------------------------------------------------
HRESULT HrGetFolderMetrics( // RETURNS: HRESULT
IN HFLDMTRC hFolderMetrics, // handle created from rcOpenFolderMetrics
IN FILETIME *pftNow, // Current time expressed as FILETIME
IN DWORD fMetric, // Flags for metric requested. May
// be or'ed combination of:
// FM_CMESSAGES
// FM_LONGEST_WAIT
// FM_TOTAL_WAIT
OUT DWORD *pcMessages, // If requested, recieves the number
// of messages in folder. 0 otherwise
OUT FILETIME *pftLongestWait, // If requested, receives the longest
// wait of messages currently in folder.
OUT FILETIME *pftTotalWait) // If requested, receives the total
// wait of all messages in folder.
{

HRESULT hr = NOERROR;
__int64 liNow = 0;

__int64 liLongestWait = 0;
__int64 liTotalWait = 0;

DEBUGPRIVATE("HrGetFolderMetrics()\n");

hr = CHK_HrGetFolderMetrics(
hFolderMetrics,
pftNow,
fMetric,
pcMessages,
pftLongestWait,
pftTotalWait);
if (FAILED(hr))
RETURN(hr);

liNow = INT64_FROM_FILETIME(*pftNow);

hr = ((CFolderMetrics *)hFolderMetrics)->HrGetFolderMetrics(
liNow, fMetric, *pcMessages, liLongestWait, liTotalWait);

if (SUCCEEDED(hr))
{
*pftLongestWait = FILETIME_FROM_INT64(liLongestWait);
*pftTotalWait = FILETIME_FROM_INT64(liTotalWait);
}

RETURN(hr);
}


//$--CloseFolderMetrics---------------------------------------------------------
// Releases resources allocated in OpenFolderMetric.
// -----------------------------------------------------------------------------
VOID CloseFolderMetrics( // RETURNS: nothing
IN HFLDMTRC hFolderMetrics) // handle generated by OpenFolderMetric
{
HRESULT hr = NOERROR;

DEBUGPRIVATE("CloseFolderMetrics()\n");

hr = CHK_CloseFolderMetrics(hFolderMetrics);
if (FAILED(hr))
return;

delete (CFolderMetrics *) hFolderMetrics;
}


//$--HrJSOpen-------------------------------------------------------------
// Opens a JumpSlide windows.
// -----------------------------------------------------------------------------
HRESULT HrJSOpen( // RETURNS: HRESULT
IN JSWINDOWTYPE enType, // The type of window to open
IN FILETIME *pftNow, // The current time expressed as a FILETIME
IN FILETIME *pftResolution, // The resolution of the window. The
// window will jump in intervals of this
// size.
IN DWORD dwWindowDuration, // Duration of window expressed in resoution
// units.
OUT HJSWINDOW *phJSWindow) // Receives handle to newly opened window.
{
HRESULT hr = NOERROR;
__int64 liNow = 0;
__int64 liResolution = 0;

DEBUGPUBLIC("HrJSOpen()\n");

hr = CHK_HrJSOpen(
enType,
pftNow,
pftResolution,
dwWindowDuration,
phJSWindow);
if (FAILED(hr))
RETURN(hr);

switch (enType)
{
case (JSWINDOW_MIN) :
*phJSWindow = (HJSWINDOW) new CJSWindowMin();
break;
case (JSWINDOW_MAX) :
*phJSWindow = (HJSWINDOW) new CJSWindowMax();
break;
case (JSWINDOW_AVERAGE) :
*phJSWindow = (HJSWINDOW) new CJSWindowAverage();
break;
case (JSWINDOW_TOTAL_RATE) :
*phJSWindow = (HJSWINDOW) new CJSWindowTotal();
break;
default:
*phJSWindow = NULL;
}

if (*phJSWindow == NULL)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

liNow = INT64_FROM_FILETIME(*pftNow);
liResolution = INT64_FROM_FILETIME(*pftResolution);

hr = ((CJSWindow *)(*phJSWindow))->HrReset(
liNow, liResolution, dwWindowDuration);

if (FAILED(hr))
{
goto cleanup;
}

cleanup:

if ((FAILED(hr)) && (*phJSWindow!=NULL))
{
delete (CJSWindow *) *phJSWindow;
*phJSWindow = NULL;
}

RETURN(hr);
}


//$--HrJSCollectDataPoint-------------------------------------------------
// Places a new data point into the window.
// -----------------------------------------------------------------------------
HRESULT HrJSCollectDataPoint( // RETURNS: HRESULT
IN HJSWINDOW hJSWindow, // Handle to TARGET JSWindow
IN FILETIME *pftNow, // Current time expressed as FILETIME
IN DWORD dwValue) // Value of data point to add
{
HRESULT hr = NOERROR;
__int64 liNow = 0;

DEBUGPRIVATE("HrJSCollectDataPoint()\n");

hr = CHK_HrJSCollectDataPoint(hJSWindow, pftNow, dwValue);
if (FAILED(hr))
RETURN(hr);

liNow = INT64_FROM_FILETIME(*pftNow);

((CJSWindow *)hJSWindow)->DataPoint(liNow, dwValue);

RETURN(hr);
}


//$--HrJSGetValue---------------------------------------------------------
// Retrieves and interval value from a window.
//
// If the window has not had sufficient time to fill, an estimate of a
// filled window can be made by normalizing the return value. The normalizing
// fraction is returned in the parameters pdwFractionCompleteNum,
// and pdwFractionCompleteDen.
//
// Querying the window value after it has had time to fill will always
// return a fraction complete of 1.
//
// (ie. *pdwFractionCompleteNum/*pdwFractionCompleteDen == 1)
//
// Example:
// A JSWindow of TOTAL type with a duration of 1 hour.
// The window has only been gathering Data points for 30 minutes.
// Calling JSWindowGetValue() will return the total of the data points
// in the last 30 minutes and return a fraction complete of 1/2.
//
// The calling program can turn the returned value into an estimate of
// total of data points over the last period if it normalizes the value
// by the fraction complete. In the above example multiplying the returned
// value by 2 will generate the hourly estimate.
//
// -----------------------------------------------------------------------------
HRESULT HrJSGetValue( // RETURNS: HRESULT
IN HJSWINDOW hJSWindow, // Hand of window.
IN FILETIME *pftNow, // Current time expressed as FILETIME
OUT DWORD *pdwWindowValue, // Window value
OUT DWORD *pdwFractionCompleteNum, // Fraction of window that was filled
// numerator.
OUT DWORD *pdwFractionCompleteDen) // Fraction of window that was filled
// denominator.
{
HRESULT hr = NOERROR;
__int64 liNow = 0;

DEBUGPUBLIC("HrJSGetValue()\n");

hr = CHK_HrJSGetValue(
hJSWindow,
pftNow,
pdwWindowValue,
pdwFractionCompleteNum,
pdwFractionCompleteDen);
if (FAILED(hr))
RETURN(hr);

liNow = INT64_FROM_FILETIME(*pftNow);

hr = ((CJSWindow *)hJSWindow)->HrGetValue(liNow, *pdwWindowValue,
*pdwFractionCompleteNum, *pdwFractionCompleteDen);

if (FAILED(hr))
{
goto cleanup;
}

cleanup:

RETURN(hr);
}


//$--JSClose--------------------------------------------------------------
// Closes and destroys a Jump Slide Window.
// -----------------------------------------------------------------------------
VOID JSClose( // RETURNS: nothing
IN HJSWINDOW hJSWindow) // handle of window to close
{
HRESULT hr = NOERROR;

DEBUGPRIVATE("JSClose()\n");

hr = CHK_JSClose(hJSWindow);
if (FAILED(hr))
return;

delete (CJSWindow *)hJSWindow;
}


//$--HrFileTimeToSeconds--------------------------------------------------------
// Converts a FILETIME to the number of seconds. The FILETIME may
// represent the number of seconds larger than can be represenred in
// a DWORD. In that case, this function will return E_FAIL.
// -----------------------------------------------------------------------------
HRESULT HrFileTimeToSeconds( // RETURNS: HRESULT
IN FILETIME *pft, // file time to convert
OUT DWORD *pdwSec) // receives time in seconds (0 if error)
{
HRESULT hr = NOERROR;
__int64 lift = 0;
__int64 liSec = 0;

DEBUGPUBLIC("HrFileTimeToSeconds()\n");

hr = CHK_HrFileTimeToSeconds(pft, pdwSec);
if (FAILED(hr))
RETURN(hr);

*pdwSec = 0;

lift = INT64_FROM_FILETIME(*pft);

liSec = lift / (DWORD) 10000000L;

if (FILETIME_FROM_INT64(liSec).dwHighDateTime != 0)
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

*pdwSec = (DWORD)liSec;

cleanup:

RETURN(hr);
}

} // extern "C"