Skip to content

Instantly share code, notes, and snippets.

@dfch
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dfch/9e5a1dfb0e17336fe151 to your computer and use it in GitHub Desktop.
Save dfch/9e5a1dfb0e17336fe151 to your computer and use it in GitHub Desktop.
SCMC
/*
* libmc02.c
*
*/
#include "libmc02.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// version information until we find a better place to put it
// for the stub it is sufficient to have it hard coded
const VERSION_INFORMATION g_VersionInformation =
{
sizeof(VERSION_INFORMATION)
,
1 // Major
,
0 // Minor
,
0 // Build
,
"ACME Metering library." // some nifty description
};
static BOOL g_fInitialised = FALSE;
/*
* This is our synthetic test data
*
* enum METRIC_TYPE defines all possible metrics and for easy implementation
* we define an array of static strings to reference the actual metric from
* the METRIC_TYPE.
*
* In real this data would come from the C++ module that actually performs
* the REST calls to the metering engine.
*
* Note:
* The first and last metrics are pseudo-metrics and cannot be used
*/
static PSTR g_aszMetrics[METRIC_LAST + 1] =
{
"METRIC_ALL" // METRIC_ALL
,
"4.0" // memory
,
"2.5" // currentMemory
,
"3.6" // memoryallocated
,
"3.6" // memoryreserved
,
"3.6" // memorylimit
,
"2.5" // memoryused
,
"1" // vcpu
,
"0.8" // cpuallocated
,
"0.8" // cpureserved
,
"0.8" // cpulimit
,
"0.2" // cpuused
,
"x64" // arch
,
"meanmachine" // machine
,
"bridge0" // bridge0
,
"METRIC_LAST" // METRIC_LAST
};
/*
* Here comes our clever xml serialiser ...
*
* In real the C++ module that actually does the REST communication will
* also do the JSON to binary to XML transform.
*
* For testing purposes this is just fine enough.
*/
CONST PSTR g_szxmlMetrics = "<?xml version='1.0' encoding='UTF-8'?><metrics>%s</metrics>";
CONST PSTR g_szxmlMetric = "<metric context='vm' category='default' type='string' unit='none'><name>%s</name><value>%s</value></metric>";
int scmcInit
(
_IN_OUT_OPTIONAL_ DWORD *pcbVersionInformation
,
_IN_OUT_OPTIONAL_ PVERSION_INFORMATION pVersionInformation
)
{
BOOL fReturn = FALSE;
int nError = ERROR_INVALID_FUNCTION;
// Parameter validation
if(NULL == pcbVersionInformation)
{
nError = ERROR_INVALID_FUNCTION;
goto Error;
}
if(sizeof(VERSION_INFORMATION) > *pcbVersionInformation || NULL == pVersionInformation)
{
*pcbVersionInformation = sizeof(VERSION_INFORMATION);
nError = ERROR_MORE_DATA;
goto Error;
}
// Return version information
*pcbVersionInformation = sizeof(VERSION_INFORMATION);
memcpy(pVersionInformation, &g_VersionInformation, sizeof(VERSION_INFORMATION));
if(!g_fInitialised)
{
/*
* Do anything else incredibly useful here such as initialising the
* connection to the metering engine once and if this will ever be
* completed and running ...
*
* If for any reason this should fail return ERROR_INVALID_FUNCTION.
*/
}
// Mark library as initalised
g_fInitialised = TRUE;
goto Success;
Success:
return ERROR_SUCCESS;
Error:
return nError;
}
int scmcGetMetric
(
_IN_ METRIC_TYPE MetricType
,
_IN_OUT_OPTIONAL_ DWORD *pcbMetric
,
_IN_OUT_OPTIONAL_ PMETRIC pMetric
)
{
BOOL fReturn = FALSE;
int nError = ERROR_INVALID_FUNCTION;
CHAR szxmlMetric1[BUFSIZE] = { 0 };
CHAR szxmlMetric2[sizeof(szxmlMetric1)] = { 0 };
CHAR szxmlMetrics[BUFSIZE];
// Parameter validation
if(NULL == pcbMetric)
{
nError = ERROR_INVALID_FUNCTION;
goto Error;
}
if(METRIC_LAST >= MetricType || METRIC_ALL > MetricType)
{
nError = ERROR_INVALID_FUNCTION;
goto Error;
}
// Convert the requested metrics into XML
// This would be done in the C++ module and not here. This is just the
// C library stub / function entry point.
if(METRIC_ALL != MetricType)
{
sprintf(szxmlMetric1, g_szxmlMetric, g_aszMetrics[MetricType], g_aszMetrics[MetricType]);
// copy <metric/> to <metrics/>
sprintf(szxmlMetrics, g_szxmlMetrics, szxmlMetric1);
// TODO: assertion on target string length or use snprintf
// TODO: return type checks would be nice too ...
}
else
{
// get all metrics
int c = 0;
for(c = METRIC_ALL + 1; c < METRIC_LAST; c++)
{
// high efficient xml string construction ...
sprintf(szxmlMetric1, g_szxmlMetric, g_aszMetrics[c], g_aszMetrics[c]);
sprintf(szxmlMetric2, "%s%s", szxmlMetric2, szxmlMetric1);
// TODO: assertion on target string length or use snprintf
// TODO: return type checks would be nice too ...
}
// copy <metric/> to <metrics/>
sprintf(szxmlMetrics, g_szxmlMetrics, szxmlMetric2);
}
// check if given buffer is still enough for total length
if(strlen(szxmlMetrics) > *pcbMetric)
{
*pcbMetric = strlen(szxmlMetrics);
nError = ERROR_MORE_DATA;
goto Error;
}
// Update Metric buffer from caller
*pcbMetric = strlen(szxmlMetrics);
pMetric->dwVersion = METRIC_VERSION;
pMetric->dwSize = *pcbMetric;
// after memcpy we do not have a C string any more
memcpy(pMetric->pData, szxmlMetrics, *pcbMetric);
goto Success;
Success:
return ERROR_SUCCESS;
Error:
return nError;
}
/*
* libmc02.h
*
*/
#ifndef LIBMC02_H_
#define LIBMC02_H_
#define VOID void
#define CONST const
typedef char CHAR;
typedef CHAR *PSTR;
typedef void *PVOID;
typedef CONST void *PCVOID;
typedef unsigned int UINT;
typedef unsigned long DWORD;
#define BUFSIZE (4096 - 4)
#ifdef FALSE
#undef FALSE
#endif
#define FALSE 0
#ifdef TRUE
#undef TRUE
#endif
#define TRUE 1
typedef int BOOL, *PBOOL, *LPBOOL;
#define _IN_
#define _IN_OUT_
#define _IN_OUT_OPTIONAL_
#define ERROR_SUCCESS 0
#define ERROR_INVALID_FUNCTION 1
#define ERROR_MORE_DATA 234
#define METRIC_VERSION 1
typedef struct _METRIC
{
DWORD dwVersion
;
DWORD dwSize
;
PVOID pData
;
} METRIC,
*PMETRIC,
**PPMETRIC;
typedef enum _METRIC_TYPE
{
METRIC_ALL = 0
,
memory = 1
,
currentMemory
,
memoryallocated
,
memoryreserved
,
memorylimit
,
memoryused
,
vcpu
,
cpuallocated
,
cpureserved
,
cpulimit
,
cpuused
,
arch
,
machine
,
bridge0
//,
// ...
// insert new types _before_ METRIC_LAST
,
METRIC_LAST
} METRIC_TYPE,
*PMETRIC_TYPE,
**PPMETRIC_TYPE;
typedef struct _VERSION_INFORMATION
{
DWORD dwSize // = 1
;
DWORD dwVersionMajor // = 1
;
DWORD dwVersionMinor // = 0
;
DWORD dwVersionBuild // = 0
;
CHAR pszDescription[256] //
;
} VERSION_INFORMATION,
* PVERSION_INFORMATION,
**PPVERSION_INFORMATION;
int scmcGetMetric
(
_IN_ METRIC_TYPE MetricType
,
_IN_OUT_OPTIONAL_ DWORD *pcbMetric
,
_IN_OUT_OPTIONAL_ PMETRIC pMetric
);
int scmcInit
(
_IN_OUT_OPTIONAL_ DWORD *pcbVersionInformation
,
_IN_OUT_OPTIONAL_ PVERSION_INFORMATION pVersionInformation
);
#endif /* LIBMC02_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment