File: [OMI] / omi / base / helpers.c
(download)
Revision: 1.1,
Wed May 30 21:47:49 2012 UTC (12 years, 1 month ago) by mike
Branch: MAIN
Initial revision
|
/*
**==============================================================================
**
** Open Management Infrastructure (OMI)
**
** Copyright (c) Microsoft Corporation
**
** Licensed under the Apache License, Version 2.0 (the "License"); you may not
** use this file except in compliance with the License. You may obtain a copy
** of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABLITY OR NON-INFRINGEMENT.
**
** See the Apache 2 License for the specific language governing permissions
** and limitations under the License.
**
**==============================================================================
*/
#include <ctype.h>
#include "helpers.h"
#include "types.h"
#include "strings.h"
#include "alloc.h"
#include "io.h"
#define T MI_T
static const MI_Char* _ParseNumber(const MI_Char* p, unsigned long* n)
{
MI_Char* end;
*n = Ztoul(p, &end, 10);
if (end == p)
return NULL;
return end;
}
static const MI_Char* _ParseDecimalPart(
const MI_Char* p,
unsigned long* n)
{
MI_Char* end;
int i;
MI_Char buf[7];
unsigned long x;
x = Ztoul(p, &end, 10);
if (end == p)
{
/* Zero decimal part */
*n = 0;
return p;
}
for (i = 0; i < 6 && p != end; i++, p++)
buf[i] = *p;
for (; i < 6; i++)
buf[i] = '0';
buf[6] = '\0';
*n = Ztoul(buf, NULL, 10);
return end;
}
static int _ParseWSManDuration(const MI_Char* str, MI_Datetime* x)
{
const MI_Char* p = str;
int foundT = 0;
unsigned long years = 0;
unsigned long months = 0;
unsigned long days = 0;
unsigned long hours = 0;
unsigned long minutes = 0;
unsigned long seconds = 0;
unsigned long microseconds = 0;
/* xs:duration: PnYnMnDTnHnMnS */
if (*p != 'P')
return -1;
/* [xs:duration]
*
* Format: "PnYnMnDTnHnMnS", where
* P - period (required)
* nY - number of years
* nM - number of month
* nD - number of days
* T - start of time section (required for the following)
* nH - number of hours
* nM - number of minutes
* nS - number of seconds
*
* Examples:
* -P10D (rejected)
* -P1347M (rejected)
* P5Y
* P5Y2M10D
* P5Y2M10DT15H
* PT15H
* P1347Y
* P1347M
* P1Y2MT2H
* P0Y1347M
* P0Y1347M0D
* P1Y2M3DT10H30M
*
* Illegal:
* P-1347M (rejected)
* P1Y2MT (tolerated)
*/
p++;
while (*p)
{
unsigned long n = 0;
if (*p == 'T')
{
foundT = 1;
p++;
}
else if (foundT)
{
p = _ParseNumber(p, &n);
if (!p)
break;
switch (*p)
{
case 'H':
hours = n;
break;
case 'M':
minutes = n;
break;
case 'S':
seconds = n;
break;
case '.':
{
p++;
p = _ParseDecimalPart(p, µseconds);
if (*p != 'S')
return -1;
seconds = n;
break;
}
default:
return -1;
}
p++;
}
else
{
p = _ParseNumber(p, &n);
if (!p)
break;
switch (*p)
{
case 'Y':
years = n;
break;
case 'M':
months = n;
break;
case 'D':
days = n;
break;
default:
return -1;
}
p++;
}
}
/* ATTN: check for overflow */
/* Normalize seconds (possibly increasing minutes) */
minutes += seconds / 60;
seconds = seconds % 60;
/* Normalize minutes (possibly increasing hours) */
hours += minutes / 60;
minutes = minutes % 60;
/* Normalize hours (possibly increasing days) */
days += hours / 24;
hours = hours % 24;
/* Approximate days from years-months-days */
days += years * 365;
days += years / 4;
days += months * 30;
days += months / 2;
/* Set CIM datetime fields */
x->isTimestamp = MI_FALSE;
x->u.interval.days = (unsigned int)days;
x->u.interval.hours = (unsigned int)hours;
x->u.interval.minutes = (unsigned int)minutes;
x->u.interval.seconds = (unsigned int)seconds;
x->u.interval.microseconds = microseconds;
return (p && *p == '\0') ? 0 : -1;
}
static const MI_Char* _ParseWSManUTC(const MI_Char* str, MI_Datetime* x)
{
const MI_Char* p = str;
unsigned long utcHours = 0;
unsigned long utcMinutes = 0;
long utcSign = 0; /* '1' is positive, '-1' is negative */
if (*p == 'Z')
{
p++;
return p;
}
else if (*p == '+' || *p == '-')
{
/* Parse UTC "HH:SS" */
const MI_Char* end;
utcSign = (*p == '-') ? -1 : 1;
p++;
end = _ParseNumber(p, &utcHours);
if (!end || (end - p) != 2)
return NULL;
p = end;
if (*p != ':')
return NULL;
p++;
end = _ParseNumber(p, &utcMinutes);
if (!end || (end - p) != 2)
return NULL;
p = end;
}
else
{
return NULL;
}
/* Set CIM datetime fields */
x->u.timestamp.utc = utcSign * ((utcHours * 60) + utcMinutes);
return p;
}
static const MI_Char* _ParseWSManDate(const MI_Char* str, MI_Datetime* x)
{
const MI_Char* p = str;
unsigned long year = 0;
unsigned long month = 0;
unsigned long day = 0;
/* Parse YYYY */
{
const MI_Char* end = _ParseNumber(p, &year);
if (!end || (end - p) != 4)
return NULL;
p = end;
}
/* Expect '-' */
if (*p++ != '-')
return NULL;
/* Parse MM */
{
const MI_Char* end = _ParseNumber(p, &month);
if (!end || (end - p) != 2)
return NULL;
p = end;
}
/* Expect '-' */
if (*p++ != '-')
return NULL;
/* Parse DD */
{
const MI_Char* end = _ParseNumber(p, &day);
if (!end || (end - p) != 2)
return NULL;
p = end;
}
/* Set CIM datetime fields */
memset(x, 0, sizeof(MI_Datetime));
x->isTimestamp = MI_TRUE;
x->u.timestamp.year = (unsigned int)year;
x->u.timestamp.month = (unsigned int)month;
x->u.timestamp.day = (unsigned int)day;
/* Parse UTC part */
if (*p == 'Z' || *p == '+' || *p == '-')
{
p = _ParseWSManUTC(p, x);
if (!p)
return NULL;
}
return p;
}
static const MI_Char* _ParseWSManTime(const MI_Char* str, MI_Datetime* x)
{
const MI_Char* p = str;
unsigned long hour = 0;
unsigned long minute = 0;
unsigned long second = 0;
unsigned long microseconds = 0;
/* Parse "HH" */
{
const MI_Char* end = _ParseNumber(p, &hour);
if (!end || (end - p) != 2)
return NULL;
p = end;
}
/* Expect ':' */
if (*p++ != ':')
return NULL;
/* Parse "MM" */
{
const MI_Char* end = _ParseNumber(p, &minute);
if (!end || (end - p) != 2)
return NULL;
p = end;
}
/* Expect ":" */
if (*p++ != ':')
return NULL;
/* Parse "SS" */
{
const MI_Char* end = _ParseNumber(p, &second);
if (!end || (end - p) != 2)
return NULL;
p = end;
}
/* Parse decimal part */
if (*p == '.')
{
p++;
p = _ParseDecimalPart(p, µseconds);
if (!p)
return NULL;
}
/* Set CIM datetime fields */
x->isTimestamp = MI_TRUE;
x->u.timestamp.hour = (unsigned int)hour;
x->u.timestamp.minute = (unsigned int)minute;
x->u.timestamp.second = (unsigned int)second;
x->u.timestamp.microseconds = (unsigned int)microseconds;
/* Parse UTC part */
if (*p == 'Z' || *p == '+' || *p == '-')
{
p = _ParseWSManUTC(p, x);
if (!p)
return NULL;
}
return p;
}
int ParseWSManDatetime(const MI_Char* str, MI_Datetime* x)
{
const MI_Char* p = str;
/* Clear datetime */
memset(x, 0, sizeof(MI_Datetime));
/* negative xs:duration */
if (*p == '-')
{
/* Negative intervals not supported by CIM */
return -1;
}
/* xs:duration: "PnYnMnDTnHnMnS" */
if (*p == 'P')
{
return _ParseWSManDuration(str, x);
}
/* xs:date: "YYYY-MM-DD" plus UTC */
if (isdigit(p[0]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]))
{
p = _ParseWSManDate(str, x);
if (!p)
return -1;
if (*p == '\0')
return 0;
/* xs:time "HH:MM:SS" plus UTC */
if (*p == 'T')
{
p++;
p = _ParseWSManTime(p, x);
if (!p)
return -1;
if (*p == '\0')
return 0;
}
}
/* xs:time: "HH:MM:SS" plus UTC */
if (isdigit(p[0]) && isdigit(p[1]) && p[2] == ':')
{
p = _ParseWSManTime(str, x);
if (!p)
return -1;
if (*p == '\0')
return 0;
}
/* Failed */
return -1;
}
void FormatWSManDatetime(const MI_Datetime* x, MI_Char buffer[64])
{
int n = 64;
*buffer = '\0';
if (x->isTimestamp)
{
/* Example output: "2010-12-31T12:30:03.123456+06:00" */
int haveDate;
int haveTime;
MI_Char tmpbuf[64];
haveDate = x->u.timestamp.year || x->u.timestamp.month ||
x->u.timestamp.day;
haveTime = x->u.timestamp.hour || x->u.timestamp.minute ||
x->u.timestamp.second || x->u.timestamp.microseconds;
if (haveDate)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("%04u-%02u-%02u"),
x->u.timestamp.year,
x->u.timestamp.month,
x->u.timestamp.day);
Zlcat(buffer, tmpbuf, n);
}
if (haveTime || !haveDate)
{
if (haveDate)
Zlcat(buffer, T("T"), n);
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("%02u:%02u:%02u"),
x->u.timestamp.hour,
x->u.timestamp.minute,
x->u.timestamp.second);
Zlcat(buffer, tmpbuf, n);
if (x->u.timestamp.microseconds)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T(".%06u"),
x->u.timestamp.microseconds);
Zlcat(buffer, tmpbuf, n);
}
}
if (x->u.timestamp.utc > 0)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("+%02u:%02u"),
x->u.timestamp.utc / 60, x->u.timestamp.utc % 60);
Zlcat(buffer, tmpbuf, n);
}
else if (x->u.timestamp.utc < 0)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("-%02u:%02u"),
-x->u.timestamp.utc / 60, -x->u.timestamp.utc % 60);
Zlcat(buffer, tmpbuf, n);
}
}
else
{
MI_Char tmpbuf[64];
/* Example: "P1Y1M22DT10H11M12S" */
Zlcat(buffer, T("P"), n);
if (x->u.interval.days)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("%uD"), x->u.interval.days);
Zlcat(buffer, tmpbuf, n);
}
if (x->u.interval.hours || x->u.interval.minutes ||
x->u.interval.seconds || x->u.interval.microseconds)
{
Zlcat(buffer, T("T"), n);
}
if (x->u.interval.hours)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("%uH"), x->u.interval.hours);
Zlcat(buffer, tmpbuf, n);
}
if (x->u.interval.minutes)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("%uM"), x->u.interval.minutes);
Zlcat(buffer, tmpbuf, n);
}
if (x->u.interval.seconds && x->u.interval.microseconds)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("%u.%06uS"),
x->u.interval.seconds, x->u.interval.microseconds);
Zlcat(buffer, tmpbuf, n);
}
else if (x->u.interval.seconds && !x->u.interval.microseconds)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("%uS"), x->u.interval.seconds);
Zlcat(buffer, tmpbuf, n);
}
else if (!x->u.interval.seconds && x->u.interval.microseconds)
{
Szprintf(tmpbuf, MI_COUNT(tmpbuf), T("0.%06uS"),
x->u.interval.microseconds);
Zlcat(buffer, tmpbuf, n);
}
}
}
static int _StrToU32(const MI_Char* s, size_t offset, size_t size, MI_Uint32* x)
{
MI_Char buf[64];
MI_Char* end;
if (size >= MI_COUNT(buf))
return -1;
memcpy(buf, &s[offset], size * sizeof(MI_Char));
buf[size] = '\0';
*x = (MI_Uint32)Ztoul(buf, &end, 10);
if (*end != '\0')
return -1;
/* Success */
return 0;
}
int StrToChar16(const MI_Char* str, MI_Char16* x)
{
MI_Char* end;
*x = (MI_Char16)Ztoul(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToDatetime(const MI_Char* s, MI_Datetime* x)
{
if (Zlen(s) != 25)
return -1;
memset(x, 0, sizeof(MI_Datetime));
if (s[21] == '+' || s[21] == '-')
{
MI_Uint32 utc;
/* It must be a timestamp (YYYYMMDDHHMMSS.MMMMMMSUTC) */
if (_StrToU32(s, 0, 4, &x->u.timestamp.year) != 0 ||
_StrToU32(s, 4, 2, &x->u.timestamp.month) != 0 ||
_StrToU32(s, 6, 2, &x->u.timestamp.day) != 0 ||
_StrToU32(s, 8, 2, &x->u.timestamp.hour) != 0 ||
_StrToU32(s, 10, 2, &x->u.timestamp.minute) != 0 ||
_StrToU32(s, 12, 2, &x->u.timestamp.second) != 0 ||
s[14] != '.' ||
_StrToU32(s, 15, 6, &x->u.timestamp.microseconds) != 0 ||
_StrToU32(s, 22, 3, &utc) != 0)
{
return -1;
}
if (s[21] == '+')
x->u.timestamp.utc = (MI_Sint32)utc;
else
x->u.timestamp.utc = -(MI_Sint32)utc;
x->isTimestamp = 1;
}
else if (s[21] == ':')
{
/* It must be an interval (DDDDDDDDHHMMSS.MMMMMM:000) */
if (_StrToU32(s, 0, 8, &x->u.interval.days) != 0 ||
_StrToU32(s, 8, 2, &x->u.interval.hours) != 0 ||
_StrToU32(s, 10, 2, &x->u.interval.minutes) != 0 ||
_StrToU32(s, 12, 2, &x->u.interval.seconds) != 0 ||
s[14] != '.' ||
_StrToU32(s, 15, 6, &x->u.interval.microseconds) != 0 ||
s[22] != '0' || s[23] != '0' || s[24] != '0')
{
return -1;
}
x->isTimestamp = 0;
}
else
return -1;
return 0;
}
static int _ParseDatetime(const MI_Char* str, MI_Datetime* x)
{
if (StrToDatetime(str, x) == 0)
return 0;
if (ParseWSManDatetime(str, x) == 0)
return 0;
return -1;
}
int StrToBoolean(const MI_Char* str, MI_Boolean* x)
{
if (Zcasecmp(str, T("true")) == 0)
*x = MI_TRUE;
else if (Zcasecmp(str, T("false")) == 0)
*x = MI_FALSE;
else
return -1;
return 0;
}
int StrToUint8(const MI_Char* str, MI_Uint8* x)
{
MI_Char* end;
*x = (MI_Uint8)Ztoul(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToSint8(const MI_Char* str, MI_Sint8* x)
{
MI_Char* end;
*x = (MI_Sint8)Ztol(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToUint16(const MI_Char* str, MI_Uint16* x)
{
MI_Char* end;
*x = (MI_Uint16)Ztoul(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToSint16(const MI_Char* str, MI_Sint16* x)
{
MI_Char* end;
*x = (MI_Sint16)Ztol(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToUint32(const MI_Char* str, MI_Uint32* x)
{
MI_Char* end;
*x = (MI_Uint32)Ztoul(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToSint32(const MI_Char* str, MI_Sint32* x)
{
MI_Char* end;
*x = (MI_Sint32)Ztol(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToUint64(const MI_Char* str, MI_Uint64* x)
{
MI_Char* end;
*x = (MI_Uint64)Ztoull(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToSint64(const MI_Char* str, MI_Sint64* x)
{
MI_Char* end;
*x = (MI_Sint64)Ztoll(str, &end, 0);
if (*end != '\0')
return -1;
return 0;
}
int StrToReal32(const MI_Char* str, MI_Real32* x)
{
MI_Char* end;
*x = (MI_Real32)Ztod(str, &end);
if (*end != '\0')
return -1;
return 0;
}
int StrToReal64(const MI_Char* str, MI_Real64* x)
{
MI_Char* end;
*x = (MI_Real64)Ztod(str, &end);
if (*end != '\0')
return -1;
return 0;
}
MI_Result MI_CALL Instance_SetElementFromString(
MI_Instance* self,
const MI_Char* name,
const MI_Char* str)
{
/* ATTN: check for integer value truncation (see use of Ztol) */
/* ATTN: implement array types! */
/* ATTN: implement instance and reference types! */
MI_Type type;
MI_Value value;
/* Check arguments */
if (!self || !name || !str)
MI_RETURN(MI_RESULT_INVALID_PARAMETER);
/* Obtain type of named property */
{
MI_Result r = MI_Instance_GetElement(self, name, NULL, &type,
NULL, NULL);
if (r != MI_RESULT_OK)
return r;
}
/* If type is array and value is string,
try to create a single item array from this string
*/
if (0 != (MI_ARRAY_BIT & type))
return Instance_SetElementFromStringA(
self, name, &str, 1);
/* Convert string to value */
switch (type)
{
case MI_BOOLEAN:
{
if (StrToBoolean(str, &value.boolean) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_UINT8:
{
if (StrToUint8(str, &value.uint8) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_SINT8:
{
if (StrToSint8(str, &value.sint8) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_UINT16:
{
if (StrToUint16(str, &value.uint16) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_SINT16:
{
if (StrToSint16(str, &value.sint16) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_UINT32:
{
if (StrToUint32(str, &value.uint32) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_SINT32:
{
if (StrToSint32(str, &value.sint32) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_UINT64:
{
if (StrToUint64(str, &value.uint64) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_SINT64:
{
if (StrToSint64(str, &value.sint64) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_REAL32:
{
if (StrToReal32(str, &value.real32) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_REAL64:
{
if (StrToReal64(str, &value.real64) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_CHAR16:
{
if (StrToUint16(str, &value.char16) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_DATETIME:
{
if (_ParseDatetime(str, &value.datetime) != 0)
MI_RETURN(MI_RESULT_FAILED);
break;
}
case MI_STRING:
{
value.string = (MI_Char*)str;
break;
}
default:
{
MI_RETURN(MI_RESULT_FAILED);
}
}
MI_RETURN(MI_Instance_SetElement(self, name, &value, type, 0));
}
MI_Result MI_CALL Instance_SetElementFromStringA(
MI_Instance* self_,
const MI_Char* name,
const MI_Char** data,
MI_Uint32 size)
{
Instance* self = (Instance*)self_;
MI_Type type = MI_BOOLEAN;
MI_Value v;
MI_Uint32 i;
MI_Result result = MI_RESULT_OK;
MI_Uint32 flags = 0;
/* Clear value first */
memset(&v, 0, sizeof(v));
/* Check arguments */
if (!self || !name || !data)
{
/* return instead of goto failed: 'v' is not initialized yet */
return MI_RESULT_INVALID_PARAMETER;
}
/* Obtain type of named property */
if (MI_Instance_GetElement(self_, name, NULL, &type, NULL, NULL))
{
/* return instead of goto failed: 'v' is not initialized yet */
return MI_RESULT_FAILED;
}
/* Allocate array (allocate extra element for possible empty array) */
if (type == MI_STRINGA)
{
v.array.data = (MI_Char**)data;
v.array.size = size;
}
else
{
MI_Uint32 esize = (MI_Uint32)Type_SizeOf(Type_ScalarOf(type));
v.array.data = BAlloc(self->batch, (size + 1) * esize, CALLSITE);
if (!v.array.data)
{
result = MI_RESULT_FAILED;
goto done;
}
v.array.size = size;
flags |= MI_FLAG_ADOPT;
}
/* Convert string to v */
switch (type)
{
case MI_BOOLEANA:
{
for (i = 0; i < size; i++)
{
if (StrToBoolean(data[i], &v.booleana.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_UINT8A:
{
for (i = 0; i < size; i++)
{
if (StrToUint8(data[i], &v.uint8a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_SINT8A:
{
for (i = 0; i < size; i++)
{
if (StrToSint8(data[i], &v.sint8a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_UINT16A:
{
for (i = 0; i < size; i++)
{
if (StrToUint16(data[i], &v.uint16a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_SINT16A:
{
for (i = 0; i < size; i++)
{
if (StrToSint16(data[i], &v.sint16a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_UINT32A:
{
for (i = 0; i < size; i++)
{
if (StrToUint32(data[i], &v.uint32a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_SINT32A:
{
for (i = 0; i < size; i++)
{
if (StrToSint32(data[i], &v.sint32a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_UINT64A:
{
for (i = 0; i < size; i++)
{
if (StrToUint64(data[i], &v.uint64a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_SINT64A:
{
for (i = 0; i < size; i++)
{
if (StrToSint64(data[i], &v.sint64a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_REAL32A:
{
for (i = 0; i < size; i++)
{
if (StrToReal32(data[i], &v.real32a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_REAL64A:
{
for (i = 0; i < size; i++)
{
if (StrToReal64(data[i], &v.real64a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_CHAR16A:
{
for (i = 0; i < size; i++)
{
if (StrToChar16(data[i], &v.char16a.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_DATETIMEA:
{
for (i = 0; i < size; i++)
{
if (_ParseDatetime(data[i], &v.datetimea.data[i]) != 0)
{
result = MI_RESULT_FAILED;
goto done;
}
}
break;
}
case MI_STRINGA:
{
// Handled above.
break;
}
default:
{
result = MI_RESULT_FAILED;
goto done;
}
}
if (MI_Instance_SetElement(self_, name, &v, type, flags))
{
result = MI_RESULT_FAILED;
goto done;
}
done:
if (result && v.array.data && type != MI_STRINGA)
BFree(self->batch, v.array.data, CALLSITE);
return result;
}
MI_Result MI_CALL Instance_GetValue(
MI_Instance* self,
const MI_Char* name,
void* value,
MI_Type type)
{
MI_Result r;
MI_Value v;
MI_Type t;
MI_Uint32 f;
r = MI_Instance_GetElement(self, name, &v, &t, &f, NULL);
if (r != MI_RESULT_OK)
MI_RETURN(r);
if (t != type)
MI_RETURN(MI_RESULT_TYPE_MISMATCH);
if (f & MI_FLAG_NULL)
MI_RETURN(MI_RESULT_NOT_FOUND);
if (!value)
MI_RETURN(MI_RESULT_INVALID_PARAMETER);
memcpy(value, &v, Type_SizeOf(type));
MI_RETURN(MI_RESULT_OK);
}
void DatetimeToStr(const MI_Datetime* x, MI_Char buf[26])
{
if (x->isTimestamp)
{
const MI_Char FMT[] = MI_T("%04d%02d%02d%02d%02d%02d.%06d%c%03d");
MI_Sint32 utc = x->u.timestamp.utc;
Szprintf(buf, 26, FMT,
x->u.timestamp.year,
x->u.timestamp.month,
x->u.timestamp.day,
x->u.timestamp.hour,
x->u.timestamp.minute,
x->u.timestamp.second,
x->u.timestamp.microseconds,
utc < 0 ? '-' : '+',
utc < 0 ? -utc : utc);
}
else
{
const MI_Char FMT[] = MI_T("%08u%02u%02u%02u.%06u:000");
Szprintf(buf, 26, FMT,
x->u.interval.days,
x->u.interval.hours,
x->u.interval.minutes,
x->u.interval.seconds,
x->u.interval.microseconds);
}
}