Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
40196828
Commit
40196828
authored
Jun 22, 2017
by
Hans Leidekker
Committed by
Alexandre Julliard
Jun 22, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
webservices: Add support for dynamic string callbacks.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
f7488ac6
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
118 additions
and
18 deletions
+118
-18
writer.c
dlls/webservices/tests/writer.c
+79
-2
writer.c
dlls/webservices/writer.c
+39
-16
No files found.
dlls/webservices/tests/writer.c
View file @
40196828
...
...
@@ -3649,6 +3649,34 @@ static const WS_XML_STRING *init_xmlstring_dict( WS_XML_DICTIONARY *dict, ULONG
return
str
;
}
static
HRESULT
CALLBACK
dict_cb
(
void
*
state
,
const
WS_XML_STRING
*
str
,
BOOL
*
found
,
ULONG
*
id
,
WS_ERROR
*
error
)
{
ULONG
*
call_count
=
state
;
(
*
call_count
)
++
;
switch
(
str
->
bytes
[
0
])
{
case
't'
:
*
id
=
1
;
*
found
=
TRUE
;
break
;
case
'n'
:
*
id
=
2
;
*
found
=
TRUE
;
break
;
case
'v'
:
*
found
=
FALSE
;
return
WS_E_OTHER
;
default:
*
found
=
FALSE
;
break
;
}
return
S_OK
;
}
static
void
test_dictionary
(
void
)
{
static
const
char
res
[]
=
...
...
@@ -3659,6 +3687,12 @@ static void test_dictionary(void)
{
0x53
,
0x06
,
0x0b
,
0x01
,
'p'
,
0x0a
,
0x01
};
static
const
char
res4
[]
=
{
0x43
,
0x02
,
'p'
,
'2'
,
0x06
,
0x0b
,
0x02
,
'p'
,
'2'
,
0x0a
,
0x01
};
static
const
char
res5
[]
=
{
0x42
,
0x03
,
0x0a
,
0x05
,
0x01
};
static
const
char
res6
[]
=
{
0x40
,
0x01
,
0x75
,
0x0a
,
0x05
,
0x01
};
static
const
char
res7
[]
=
{
0x40
,
0x01
,
0x76
,
0x0a
,
0x05
,
0x01
};
static
const
char
res100
[]
=
{
0x42
,
0x06
,
0x06
,
0x06
,
0x98
,
0x00
,
0x01
};
static
const
char
res101
[]
=
...
...
@@ -3672,7 +3706,7 @@ static void test_dictionary(void)
WS_XML_DICTIONARY
dict
;
WS_XML_WRITER
*
writer
;
HRESULT
hr
;
ULONG
i
;
ULONG
i
,
call_count
;
static
const
struct
{
ULONG
prefix
;
...
...
@@ -3768,12 +3802,55 @@ static void test_dictionary(void)
hr
=
WsWriteStartAttribute
(
writer
,
prefix_ptr
,
localname_ptr
,
ns_ptr
,
FALSE
,
NULL
);
ok
(
hr
==
S_OK
,
"%u: got %08x
\n
"
,
i
,
hr
);
hr
=
WsWriteEndAttribute
(
writer
,
NULL
);
ok
(
hr
==
S_OK
,
"
got %08x
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"
%u: got %08x
\n
"
,
i
,
hr
);
hr
=
WsWriteEndElement
(
writer
,
NULL
);
ok
(
hr
==
S_OK
,
"%u: got %08x
\n
"
,
i
,
hr
);
if
(
hr
==
S_OK
)
check_output_bin
(
writer
,
attr_tests
[
i
].
result
,
attr_tests
[
i
].
len_result
,
__LINE__
);
}
/* callback */
bin
.
staticDictionary
=
NULL
;
bin
.
dynamicStringCallback
=
dict_cb
;
bin
.
dynamicStringCallbackState
=
&
call_count
;
hr
=
WsSetOutput
(
writer
,
&
bin
.
encoding
,
&
buf
.
output
,
NULL
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
init_xmlstring
(
"t"
,
&
localname
);
init_xmlstring
(
"ns"
,
&
ns
);
call_count
=
0
;
hr
=
WsWriteStartElement
(
writer
,
NULL
,
&
localname
,
&
ns
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsWriteEndElement
(
writer
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
ok
(
call_count
==
2
,
"got %u
\n
"
,
call_count
);
check_output_bin
(
writer
,
res5
,
sizeof
(
res5
),
__LINE__
);
/* unknown string */
hr
=
WsSetOutput
(
writer
,
&
bin
.
encoding
,
&
buf
.
output
,
NULL
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
init_xmlstring
(
"u"
,
&
localname
);
init_xmlstring
(
"ns"
,
&
ns
);
call_count
=
0
;
hr
=
WsWriteStartElement
(
writer
,
NULL
,
&
localname
,
&
ns
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsWriteEndElement
(
writer
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
ok
(
call_count
==
2
,
"got %u
\n
"
,
call_count
);
check_output_bin
(
writer
,
res6
,
sizeof
(
res6
),
__LINE__
);
/* unknown string, error return from callback */
hr
=
WsSetOutput
(
writer
,
&
bin
.
encoding
,
&
buf
.
output
,
NULL
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
init_xmlstring
(
"v"
,
&
localname
);
init_xmlstring
(
"ns"
,
&
ns
);
call_count
=
0
;
hr
=
WsWriteStartElement
(
writer
,
NULL
,
&
localname
,
&
ns
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsWriteEndElement
(
writer
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
ok
(
call_count
==
2
,
"got %u
\n
"
,
call_count
);
check_output_bin
(
writer
,
res7
,
sizeof
(
res7
),
__LINE__
);
WsFreeWriter
(
writer
);
}
...
...
dlls/webservices/writer.c
View file @
40196828
...
...
@@ -85,6 +85,8 @@ struct writer
struct
xmlbuf
*
output_buf
;
WS_HEAP
*
output_heap
;
WS_XML_DICTIONARY
*
dict
;
WS_DYNAMIC_STRING_CALLBACK
dict_cb
;
void
*
dict_cb_state
;
ULONG
prop_count
;
struct
prop
prop
[
sizeof
(
writer_props
)
/
sizeof
(
writer_props
[
0
])];
};
...
...
@@ -168,6 +170,8 @@ static HRESULT init_writer( struct writer *writer )
writer
->
output_enc
=
WS_XML_WRITER_ENCODING_TYPE_TEXT
;
writer
->
output_charset
=
WS_CHARSET_UTF8
;
writer
->
dict
=
NULL
;
writer
->
dict_cb
=
NULL
;
writer
->
dict_cb_state
=
NULL
;
return
S_OK
;
}
...
...
@@ -388,6 +392,8 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING
writer
->
output_enc
=
WS_XML_WRITER_ENCODING_TYPE_BINARY
;
writer
->
output_charset
=
0
;
writer
->
dict
=
bin
->
staticDictionary
;
writer
->
dict_cb
=
bin
->
dynamicStringCallback
;
writer
->
dict_cb_state
=
bin
->
dynamicStringCallbackState
;
break
;
}
default:
...
...
@@ -638,8 +644,8 @@ static HRESULT write_string( struct writer *writer, const BYTE *bytes, ULONG len
static
HRESULT
write_dict_string
(
struct
writer
*
writer
,
ULONG
id
)
{
HRESULT
hr
;
if
(
id
>
0x
3
fffffff
)
return
E_INVALIDARG
;
if
((
hr
=
write_int31
(
writer
,
id
<<
1
))
!=
S_OK
)
return
hr
;
if
(
id
>
0x
7
fffffff
)
return
E_INVALIDARG
;
if
((
hr
=
write_int31
(
writer
,
id
))
!=
S_OK
)
return
hr
;
return
S_OK
;
}
...
...
@@ -678,6 +684,23 @@ static HRESULT write_attribute_value_bin( struct writer *writer, const WS_XML_TE
}
}
static
BOOL
lookup_string_id
(
struct
writer
*
writer
,
const
WS_XML_STRING
*
str
,
ULONG
*
id
)
{
if
(
writer
->
dict
&&
str
->
dictionary
==
writer
->
dict
)
{
*
id
=
str
->
id
<<
1
;
return
TRUE
;
}
if
(
writer
->
dict_cb
)
{
BOOL
found
=
FALSE
;
writer
->
dict_cb
(
writer
->
dict_cb_state
,
str
,
&
found
,
id
,
NULL
);
if
(
found
)
*
id
=
(
*
id
<<
1
)
|
1
;
return
found
;
}
return
FALSE
;
}
static
enum
record_type
get_attr_record_type
(
const
WS_XML_ATTRIBUTE
*
attr
,
BOOL
use_dict
)
{
if
(
!
attr
->
prefix
||
!
attr
->
prefix
->
length
)
...
...
@@ -696,8 +719,8 @@ static enum record_type get_attr_record_type( const WS_XML_ATTRIBUTE *attr, BOOL
static
HRESULT
write_attribute_bin
(
struct
writer
*
writer
,
const
WS_XML_ATTRIBUTE
*
attr
)
{
BOOL
use_dict
=
(
writer
->
dict
&&
attr
->
localName
->
dictionary
==
writer
->
dict
)
;
enum
record_type
type
=
get_attr_record_type
(
attr
,
use_dict
);
ULONG
id
;
enum
record_type
type
=
get_attr_record_type
(
attr
,
lookup_string_id
(
writer
,
attr
->
localName
,
&
id
)
);
HRESULT
hr
;
if
((
hr
=
write_grow_buffer
(
writer
,
1
))
!=
S_OK
)
return
hr
;
...
...
@@ -710,7 +733,7 @@ static HRESULT write_attribute_bin( struct writer *writer, const WS_XML_ATTRIBUT
}
if
(
type
>=
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_A
&&
type
<=
RECORD_PREFIX_DICTIONARY_ATTRIBUTE_Z
)
{
if
((
hr
=
write_dict_string
(
writer
,
attr
->
localName
->
id
))
!=
S_OK
)
return
hr
;
if
((
hr
=
write_dict_string
(
writer
,
id
))
!=
S_OK
)
return
hr
;
return
write_attribute_value_bin
(
writer
,
attr
->
value
);
}
...
...
@@ -726,12 +749,12 @@ static HRESULT write_attribute_bin( struct writer *writer, const WS_XML_ATTRIBUT
break
;
case
RECORD_SHORT_DICTIONARY_ATTRIBUTE
:
if
((
hr
=
write_dict_string
(
writer
,
attr
->
localName
->
id
))
!=
S_OK
)
return
hr
;
if
((
hr
=
write_dict_string
(
writer
,
id
))
!=
S_OK
)
return
hr
;
break
;
case
RECORD_DICTIONARY_ATTRIBUTE
:
if
((
hr
=
write_string
(
writer
,
attr
->
prefix
->
bytes
,
attr
->
prefix
->
length
))
!=
S_OK
)
return
hr
;
if
((
hr
=
write_dict_string
(
writer
,
attr
->
localName
->
id
))
!=
S_OK
)
return
hr
;
if
((
hr
=
write_dict_string
(
writer
,
id
))
!=
S_OK
)
return
hr
;
break
;
default:
...
...
@@ -844,8 +867,8 @@ static enum record_type get_xmlns_record_type( const WS_XML_ATTRIBUTE *attr, BOO
static
HRESULT
write_namespace_attribute_bin
(
struct
writer
*
writer
,
const
WS_XML_ATTRIBUTE
*
attr
)
{
BOOL
use_dict
=
(
writer
->
dict
&&
attr
->
ns
->
dictionary
==
writer
->
dict
)
;
enum
record_type
type
=
get_xmlns_record_type
(
attr
,
use_dict
);
ULONG
id
;
enum
record_type
type
=
get_xmlns_record_type
(
attr
,
lookup_string_id
(
writer
,
attr
->
ns
,
&
id
)
);
HRESULT
hr
;
if
((
hr
=
write_grow_buffer
(
writer
,
1
))
!=
S_OK
)
return
hr
;
...
...
@@ -861,11 +884,11 @@ static HRESULT write_namespace_attribute_bin( struct writer *writer, const WS_XM
break
;
case
RECORD_SHORT_DICTIONARY_XMLNS_ATTRIBUTE
:
return
write_dict_string
(
writer
,
attr
->
ns
->
id
);
return
write_dict_string
(
writer
,
id
);
case
RECORD_DICTIONARY_XMLNS_ATTRIBUTE
:
if
((
hr
=
write_string
(
writer
,
attr
->
prefix
->
bytes
,
attr
->
prefix
->
length
))
!=
S_OK
)
return
hr
;
return
write_dict_string
(
writer
,
attr
->
ns
->
id
);
return
write_dict_string
(
writer
,
id
);
default:
ERR
(
"unhandled record type %02x
\n
"
,
type
);
...
...
@@ -1063,8 +1086,8 @@ static enum record_type get_elem_record_type( const WS_XML_ELEMENT_NODE *elem, B
static
HRESULT
write_startelement_bin
(
struct
writer
*
writer
)
{
const
WS_XML_ELEMENT_NODE
*
elem
=
&
writer
->
current
->
hdr
;
BOOL
use_dict
=
(
writer
->
dict
&&
elem
->
localName
->
dictionary
==
writer
->
dict
)
;
enum
record_type
type
=
get_elem_record_type
(
elem
,
use_dict
);
ULONG
id
;
enum
record_type
type
=
get_elem_record_type
(
elem
,
lookup_string_id
(
writer
,
elem
->
localName
,
&
id
)
);
HRESULT
hr
;
if
((
hr
=
write_grow_buffer
(
writer
,
1
))
!=
S_OK
)
return
hr
;
...
...
@@ -1077,7 +1100,7 @@ static HRESULT write_startelement_bin( struct writer *writer )
}
if
(
type
>=
RECORD_PREFIX_DICTIONARY_ELEMENT_A
&&
type
<=
RECORD_PREFIX_DICTIONARY_ELEMENT_Z
)
{
if
((
hr
=
write_dict_string
(
writer
,
elem
->
localName
->
id
))
!=
S_OK
)
return
hr
;
if
((
hr
=
write_dict_string
(
writer
,
id
))
!=
S_OK
)
return
hr
;
return
write_attributes
(
writer
,
elem
);
}
...
...
@@ -1093,12 +1116,12 @@ static HRESULT write_startelement_bin( struct writer *writer )
break
;
case
RECORD_SHORT_DICTIONARY_ELEMENT
:
if
((
hr
=
write_dict_string
(
writer
,
elem
->
localName
->
id
))
!=
S_OK
)
return
hr
;
if
((
hr
=
write_dict_string
(
writer
,
id
))
!=
S_OK
)
return
hr
;
break
;
case
RECORD_DICTIONARY_ELEMENT
:
if
((
hr
=
write_string
(
writer
,
elem
->
prefix
->
bytes
,
elem
->
prefix
->
length
))
!=
S_OK
)
return
hr
;
if
((
hr
=
write_dict_string
(
writer
,
elem
->
localName
->
id
))
!=
S_OK
)
return
hr
;
if
((
hr
=
write_dict_string
(
writer
,
id
))
!=
S_OK
)
return
hr
;
break
;
default:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment