webservices: Add support for writing WS_DATETIME values.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bacc68822a
commit
503d152bfb
|
@ -2468,32 +2468,15 @@ static HRESULT str_to_guid( const unsigned char *str, ULONG len, GUID *ret )
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TICKS_PER_SEC 10000000
|
|
||||||
#define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC)
|
|
||||||
#define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC)
|
|
||||||
#define TICKS_PER_DAY (86400 * (ULONGLONG)TICKS_PER_SEC)
|
|
||||||
#define TICKS_MAX 3155378975999999999
|
|
||||||
|
|
||||||
static const int month_offsets[2][12] =
|
static const int month_offsets[2][12] =
|
||||||
{
|
{
|
||||||
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
|
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
|
||||||
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
|
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int month_days[2][12] =
|
|
||||||
{
|
|
||||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
|
||||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int is_leap_year( int year )
|
|
||||||
{
|
|
||||||
return !(year % 4) && (year % 100 || !(year % 400));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int valid_day( int year, int month, int day )
|
static inline int valid_day( int year, int month, int day )
|
||||||
{
|
{
|
||||||
return day > 0 && day <= month_days[is_leap_year( year )][month - 1];
|
return day > 0 && day <= month_days[leap_year( year )][month - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int leap_days_before( int year )
|
static inline int leap_days_before( int year )
|
||||||
|
@ -2585,7 +2568,7 @@ static HRESULT str_to_datetime( const unsigned char *bytes, ULONG len, WS_DATETI
|
||||||
else return WS_E_INVALID_FORMAT;
|
else return WS_E_INVALID_FORMAT;
|
||||||
|
|
||||||
ret->ticks = ((year - 1) * 365 + leap_days_before( year )) * TICKS_PER_DAY;
|
ret->ticks = ((year - 1) * 365 + leap_days_before( year )) * TICKS_PER_DAY;
|
||||||
ret->ticks += month_offsets[is_leap_year( year )][month - 1] * TICKS_PER_DAY;
|
ret->ticks += month_offsets[leap_year( year )][month - 1] * TICKS_PER_DAY;
|
||||||
ret->ticks += (day - 1) * TICKS_PER_DAY;
|
ret->ticks += (day - 1) * TICKS_PER_DAY;
|
||||||
ret->ticks += hour * TICKS_PER_HOUR;
|
ret->ticks += hour * TICKS_PER_HOUR;
|
||||||
ret->ticks += min * TICKS_PER_MIN;
|
ret->ticks += min * TICKS_PER_MIN;
|
||||||
|
@ -2610,8 +2593,6 @@ static HRESULT str_to_datetime( const unsigned char *bytes, ULONG len, WS_DATETI
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TICKS_1601_01_01 504911232000000000
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* WsDateTimeToFileTime [webservices.@]
|
* WsDateTimeToFileTime [webservices.@]
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2547,6 +2547,93 @@ static void test_write_option(void)
|
||||||
WsFreeWriter( writer );
|
WsFreeWriter( writer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL check_result( WS_XML_WRITER *writer, const char *expected )
|
||||||
|
{
|
||||||
|
WS_BYTES bytes;
|
||||||
|
ULONG size = sizeof(bytes);
|
||||||
|
int len = strlen( expected );
|
||||||
|
|
||||||
|
memset( &bytes, 0, sizeof(bytes) );
|
||||||
|
WsGetWriterProperty( writer, WS_XML_WRITER_PROPERTY_BYTES, &bytes, size, NULL );
|
||||||
|
if (bytes.length != len) return FALSE;
|
||||||
|
return !memcmp( bytes.bytes, expected, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_datetime(void)
|
||||||
|
{
|
||||||
|
WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
unsigned __int64 ticks;
|
||||||
|
WS_DATETIME_FORMAT format;
|
||||||
|
HRESULT hr;
|
||||||
|
const char *result;
|
||||||
|
const char *result2;
|
||||||
|
}
|
||||||
|
tests[] =
|
||||||
|
{
|
||||||
|
{ 0, WS_DATETIME_FORMAT_UTC, S_OK, "<t>0001-01-01T00:00:00Z</t>" },
|
||||||
|
{ 0, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>0001-01-01T00:00:00+00:00</t>" },
|
||||||
|
{ 0, WS_DATETIME_FORMAT_NONE, S_OK, "<t>0001-01-01T00:00:00</t>" },
|
||||||
|
{ 1, WS_DATETIME_FORMAT_UTC, S_OK, "<t>0001-01-01T00:00:00.0000001Z</t>" },
|
||||||
|
{ 1, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>0001-01-01T00:00:00.0000001+00:00</t>" },
|
||||||
|
{ 1, WS_DATETIME_FORMAT_NONE, S_OK, "<t>0001-01-01T00:00:00.0000001</t>" },
|
||||||
|
{ 0x23c34600, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>0001-01-01T00:01:00+00:00</t>" },
|
||||||
|
{ 0x861c46800, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>0001-01-01T01:00:00+00:00</t>" },
|
||||||
|
{ 0x430e234000, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>0001-01-01T08:00:00+00:00</t>" },
|
||||||
|
{ 0x4b6fe7a800, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>0001-01-01T09:00:00+00:00</t>" },
|
||||||
|
{ 0x989680, WS_DATETIME_FORMAT_NONE, S_OK, "<t>0001-01-01T00:00:01</t>" },
|
||||||
|
{ 0x23c34600, WS_DATETIME_FORMAT_NONE, S_OK, "<t>0001-01-01T00:01:00</t>" },
|
||||||
|
{ 0x861c46800, WS_DATETIME_FORMAT_NONE, S_OK, "<t>0001-01-01T01:00:00</t>" },
|
||||||
|
{ 0xc92a69c000, WS_DATETIME_FORMAT_NONE, S_OK, "<t>0001-01-02T00:00:00</t>" },
|
||||||
|
{ 0x11ed178c6c000, WS_DATETIME_FORMAT_NONE, S_OK, "<t>0002-01-01T00:00:00</t>" },
|
||||||
|
{ 0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC, S_OK, "<t>9999-12-31T23:59:59.9999999Z</t>" },
|
||||||
|
{ 0x2bca2875f4373fff, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>9999-12-31T15:59:59.9999999-08:00</t>",
|
||||||
|
"<t>9999-12-31T17:59:59.9999999-06:00</t>" /* win7 */ },
|
||||||
|
{ 0x2bca2875f4373fff, WS_DATETIME_FORMAT_NONE, S_OK, "<t>9999-12-31T23:59:59.9999999</t>" },
|
||||||
|
{ 0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC, WS_E_INVALID_FORMAT },
|
||||||
|
{ 0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL, WS_E_INVALID_FORMAT },
|
||||||
|
{ 0x2bca2875f4374000, WS_DATETIME_FORMAT_NONE, WS_E_INVALID_FORMAT },
|
||||||
|
{ 0x8d3123e7df74000, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>2015-12-31T16:00:00-08:00</t>",
|
||||||
|
"<t>2015-12-31T18:00:00-06:00</t>" /* win7 */ },
|
||||||
|
{ 0x701ce1722770000, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>1601-01-01T00:00:00+00:00</t>" },
|
||||||
|
{ 0x701ce5a309a4000, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>1601-01-01T00:00:00-08:00</t>",
|
||||||
|
"<t>1601-01-01T02:00:00-06:00</t>" /* win7 */ },
|
||||||
|
{ 0x701ce5e617c7400, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>1601-01-01T00:30:00-08:00</t>",
|
||||||
|
"<t>1601-01-01T02:30:00-06:00</t>" /* win7 */ },
|
||||||
|
{ 0x701ce51ced5d800, WS_DATETIME_FORMAT_LOCAL, S_OK, "<t>1601-01-01T07:00:00+00:00</t>",
|
||||||
|
"<t>1601-01-01T01:00:00-06:00</t>" /* win7 */ },
|
||||||
|
{ 0, WS_DATETIME_FORMAT_NONE + 1, WS_E_INVALID_FORMAT },
|
||||||
|
};
|
||||||
|
HRESULT hr;
|
||||||
|
WS_XML_WRITER *writer;
|
||||||
|
WS_DATETIME date;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
hr = WsCreateWriter( NULL, 0, &writer, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
|
||||||
|
{
|
||||||
|
hr = set_output( writer );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
date.ticks = tests[i].ticks;
|
||||||
|
date.format = tests[i].format;
|
||||||
|
WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
|
||||||
|
hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL, WS_WRITE_REQUIRED_VALUE,
|
||||||
|
&date, sizeof(date), NULL );
|
||||||
|
WsWriteEndElement( writer, NULL );
|
||||||
|
ok( hr == tests[i].hr, "%u: got %08x\n", i, hr );
|
||||||
|
if (hr == S_OK)
|
||||||
|
{
|
||||||
|
ok( check_result( writer, tests[i].result ) || broken(check_result( writer, tests[i].result2 )),
|
||||||
|
"%u: wrong result\n", i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WsFreeWriter( writer );
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(writer)
|
START_TEST(writer)
|
||||||
{
|
{
|
||||||
test_WsCreateWriter();
|
test_WsCreateWriter();
|
||||||
|
@ -2578,4 +2665,5 @@ START_TEST(writer)
|
||||||
test_WsWriteArray();
|
test_WsWriteArray();
|
||||||
test_escapes();
|
test_escapes();
|
||||||
test_write_option();
|
test_write_option();
|
||||||
|
test_datetime();
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,24 @@ HRESULT message_insert_http_headers( WS_MESSAGE *, HINTERNET ) DECLSPEC_HIDDEN;
|
||||||
HRESULT channel_send_message( WS_CHANNEL *, WS_MESSAGE * ) DECLSPEC_HIDDEN;
|
HRESULT channel_send_message( WS_CHANNEL *, WS_MESSAGE * ) DECLSPEC_HIDDEN;
|
||||||
HRESULT channel_receive_message( WS_CHANNEL *, char **, ULONG * ) DECLSPEC_HIDDEN;
|
HRESULT channel_receive_message( WS_CHANNEL *, char **, ULONG * ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
#define TICKS_PER_SEC 10000000
|
||||||
|
#define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC)
|
||||||
|
#define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC)
|
||||||
|
#define TICKS_PER_DAY (86400 * (ULONGLONG)TICKS_PER_SEC)
|
||||||
|
#define TICKS_MAX 3155378975999999999
|
||||||
|
#define TICKS_1601_01_01 504911232000000000
|
||||||
|
|
||||||
|
static const int month_days[2][12] =
|
||||||
|
{
|
||||||
|
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int leap_year( int year )
|
||||||
|
{
|
||||||
|
return !(year % 4) && (year % 100 || !(year % 400));
|
||||||
|
}
|
||||||
|
|
||||||
static inline BOOL is_nil_value( const char *value, ULONG size )
|
static inline BOOL is_nil_value( const char *value, ULONG size )
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
|
@ -1187,6 +1187,68 @@ static ULONG format_double( const double *ptr, unsigned char *buf )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int year_size( int year )
|
||||||
|
{
|
||||||
|
return leap_year( year ) ? 366 : 365;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TZ_OFFSET 8
|
||||||
|
static ULONG format_datetime( const WS_DATETIME *ptr, unsigned char *buf )
|
||||||
|
{
|
||||||
|
static const char fmt[] = "%04u-%02u-%02uT%02u:%02u:%02u";
|
||||||
|
int day, hour, min, sec, sec_frac, month = 1, year = 1, tz_hour;
|
||||||
|
unsigned __int64 ticks, day_ticks;
|
||||||
|
ULONG len;
|
||||||
|
|
||||||
|
if (ptr->format == WS_DATETIME_FORMAT_LOCAL &&
|
||||||
|
ptr->ticks >= TICKS_1601_01_01 + TZ_OFFSET * TICKS_PER_HOUR)
|
||||||
|
{
|
||||||
|
ticks = ptr->ticks - TZ_OFFSET * TICKS_PER_HOUR;
|
||||||
|
tz_hour = TZ_OFFSET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ticks = ptr->ticks;
|
||||||
|
tz_hour = 0;
|
||||||
|
}
|
||||||
|
day = ticks / TICKS_PER_DAY;
|
||||||
|
day_ticks = ticks % TICKS_PER_DAY;
|
||||||
|
hour = day_ticks / TICKS_PER_HOUR;
|
||||||
|
min = (day_ticks % TICKS_PER_HOUR) / TICKS_PER_MIN;
|
||||||
|
sec = (day_ticks % TICKS_PER_MIN) / TICKS_PER_SEC;
|
||||||
|
sec_frac = day_ticks % TICKS_PER_SEC;
|
||||||
|
|
||||||
|
while (day >= year_size( year ))
|
||||||
|
{
|
||||||
|
day -= year_size( year );
|
||||||
|
year++;
|
||||||
|
}
|
||||||
|
while (day >= month_days[leap_year( year )][month])
|
||||||
|
{
|
||||||
|
day -= month_days[leap_year( year )][month];
|
||||||
|
month++;
|
||||||
|
}
|
||||||
|
day++;
|
||||||
|
|
||||||
|
len = sprintf( (char *)buf, fmt, year, month, day, hour, min, sec );
|
||||||
|
if (sec_frac)
|
||||||
|
{
|
||||||
|
static const char fmt_frac[] = ".%07u";
|
||||||
|
len += sprintf( (char *)buf + len, fmt_frac, sec_frac );
|
||||||
|
}
|
||||||
|
if (ptr->format == WS_DATETIME_FORMAT_UTC)
|
||||||
|
{
|
||||||
|
buf[len++] = 'Z';
|
||||||
|
}
|
||||||
|
else if (ptr->format == WS_DATETIME_FORMAT_LOCAL)
|
||||||
|
{
|
||||||
|
static const char fmt_tz[] = "%c%02u:00";
|
||||||
|
len += sprintf( (char *)buf + len, fmt_tz, tz_hour ? '-' : '+', tz_hour );
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static ULONG format_guid( const GUID *ptr, unsigned char *buf )
|
static ULONG format_guid( const GUID *ptr, unsigned char *buf )
|
||||||
{
|
{
|
||||||
static const char fmt[] = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
|
static const char fmt[] = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
|
||||||
|
@ -1284,6 +1346,13 @@ static HRESULT text_to_utf8text( const WS_XML_TEXT *text, WS_XML_UTF8_TEXT **ret
|
||||||
(*ret)->value.length = format_urn( &id->value, (*ret)->value.bytes );
|
(*ret)->value.length = format_urn( &id->value, (*ret)->value.bytes );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
case WS_XML_TEXT_TYPE_DATETIME:
|
||||||
|
{
|
||||||
|
const WS_XML_DATETIME_TEXT *dt = (const WS_XML_DATETIME_TEXT *)text;
|
||||||
|
if (!(*ret = alloc_utf8_text( NULL, 34 ))) return E_OUTOFMEMORY;
|
||||||
|
(*ret)->value.length = format_datetime( &dt->value, (*ret)->value.bytes );
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
FIXME( "unhandled text type %u\n", text->textType );
|
FIXME( "unhandled text type %u\n", text->textType );
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
@ -1666,6 +1735,32 @@ static HRESULT write_type_uint64( struct writer *writer, WS_TYPE_MAPPING mapping
|
||||||
return write_type_text( writer, mapping, &utf8.text );
|
return write_type_text( writer, mapping, &utf8.text );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT write_type_datetime( struct writer *writer, WS_TYPE_MAPPING mapping,
|
||||||
|
const WS_DATETIME_DESCRIPTION *desc, WS_WRITE_OPTION option,
|
||||||
|
const void *value, ULONG size )
|
||||||
|
{
|
||||||
|
WS_XML_UTF8_TEXT utf8;
|
||||||
|
unsigned char buf[34]; /* "0000-00-00T00:00:00.0000000-00:00" */
|
||||||
|
const WS_DATETIME *ptr;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (desc)
|
||||||
|
{
|
||||||
|
FIXME( "description not supported\n" );
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
|
||||||
|
if ((hr = get_value_ptr( option, value, size, sizeof(WS_DATETIME), (const void **)&ptr )) != S_OK) return hr;
|
||||||
|
if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
|
||||||
|
if (ptr->ticks > TICKS_MAX || ptr->format > WS_DATETIME_FORMAT_NONE) return WS_E_INVALID_FORMAT;
|
||||||
|
|
||||||
|
utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
|
||||||
|
utf8.value.bytes = buf;
|
||||||
|
utf8.value.length = format_datetime( ptr, buf );
|
||||||
|
return write_type_text( writer, mapping, &utf8.text );
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT write_type_guid( struct writer *writer, WS_TYPE_MAPPING mapping,
|
static HRESULT write_type_guid( struct writer *writer, WS_TYPE_MAPPING mapping,
|
||||||
const WS_GUID_DESCRIPTION *desc, WS_WRITE_OPTION option,
|
const WS_GUID_DESCRIPTION *desc, WS_WRITE_OPTION option,
|
||||||
const void *value, ULONG size )
|
const void *value, ULONG size )
|
||||||
|
@ -1931,6 +2026,9 @@ static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TY
|
||||||
case WS_UINT64_TYPE:
|
case WS_UINT64_TYPE:
|
||||||
return write_type_uint64( writer, mapping, desc, option, value, size );
|
return write_type_uint64( writer, mapping, desc, option, value, size );
|
||||||
|
|
||||||
|
case WS_DATETIME_TYPE:
|
||||||
|
return write_type_datetime( writer, mapping, desc, option, value, size );
|
||||||
|
|
||||||
case WS_GUID_TYPE:
|
case WS_GUID_TYPE:
|
||||||
return write_type_guid( writer, mapping, desc, option, value, size );
|
return write_type_guid( writer, mapping, desc, option, value, size );
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ typedef struct _WS_OPERATION_CONTEXT WS_OPERATION_CONTEXT;
|
||||||
typedef struct _WS_CALL_PROPERTY WS_CALL_PROPERTY;
|
typedef struct _WS_CALL_PROPERTY WS_CALL_PROPERTY;
|
||||||
typedef struct _WS_DOUBLE_DESCRIPTION WS_DOUBLE_DESCRIPTION;
|
typedef struct _WS_DOUBLE_DESCRIPTION WS_DOUBLE_DESCRIPTION;
|
||||||
typedef struct _WS_DATETIME WS_DATETIME;
|
typedef struct _WS_DATETIME WS_DATETIME;
|
||||||
|
typedef struct _WS_XML_DATETIME_TEXT WS_XML_DATETIME_TEXT;
|
||||||
typedef struct _WS_DATETIME_DESCRIPTION WS_DATETIME_DESCRIPTION;
|
typedef struct _WS_DATETIME_DESCRIPTION WS_DATETIME_DESCRIPTION;
|
||||||
typedef struct _WS_GUID_DESCRIPTION WS_GUID_DESCRIPTION;
|
typedef struct _WS_GUID_DESCRIPTION WS_GUID_DESCRIPTION;
|
||||||
typedef struct _WS_UNIQUE_ID_DESCRIPTION WS_UNIQUE_ID_DESCRIPTION;
|
typedef struct _WS_UNIQUE_ID_DESCRIPTION WS_UNIQUE_ID_DESCRIPTION;
|
||||||
|
@ -1106,6 +1107,11 @@ struct _WS_DATETIME_DESCRIPTION {
|
||||||
WS_DATETIME maxValue;
|
WS_DATETIME maxValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _WS_XML_DATETIME_TEXT {
|
||||||
|
WS_XML_TEXT text;
|
||||||
|
WS_DATETIME value;
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WS_URL_HTTP_SCHEME_TYPE,
|
WS_URL_HTTP_SCHEME_TYPE,
|
||||||
WS_URL_HTTPS_SCHEME_TYPE,
|
WS_URL_HTTPS_SCHEME_TYPE,
|
||||||
|
|
Loading…
Reference in New Issue