Last active
August 29, 2015 14:12
-
-
Save dfch/9e5a1dfb0e17336fe151 to your computer and use it in GitHub Desktop.
SCMC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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