/*
* Created by PyramIDE.
* User: Totoro
* Date: 06/07/2013
* Time: 01:13
*
*/
read xlib/web/xml_rpc_types.anubis
read tools/streams.anubis
read tools/basis.anubis
read system/string.anubis
read system/convert.anubis
type XML_RPC_Token:
none,
token(String token).
define Maybe(XML_RPC_value) read_value(Stream stream).
define XML_RPC_Token
_next_xml_token
(
Stream stream,
List(Word8) so_far,
Bool in_token
)=
if read_byte(stream) is
{
failure then none, //can't read on stream !!
success(b) then
//println("["+implode([b])+"]");
if in_token then
if b = '>' then //just found the end of bracket, so we return the token in LOWER case
with tok = to_lower(implode(reverse(so_far))),
//println("found tag "+tok);
token(tok)
else
_next_xml_token(stream, [b . so_far], in_token)
else
if b = '<' then //just found the begin of token
_next_xml_token(stream, [], true)
else
_next_xml_token(stream, so_far, in_token)
}
.
define XML_RPC_Token
next_xml_token
(
Stream stream
)= _next_xml_token(stream, [], false).
define Maybe(String)
_xml_tag_content
(
Stream stream,
String tag, //tag to match
List(Word8) so_far,
List(Word8) content,
Bool in_first_token,
Bool in_content,
Bool in_last_token
)=
if read_byte(stream) is
{
failure then failure, //can't read on stream !!
success(b) then
if in_first_token then
if b = '>' then //just found the end of bracket, so we return the token in LOWER case
if to_lower(implode(reverse(so_far))) = tag then
_xml_tag_content(stream, tag, [], [], false, true, false)
else
failure
else
_xml_tag_content(stream, tag, [b . so_far], content, in_first_token, in_content, in_last_token)
else if in_content then
if b = '<' then //just found the begin bracket,
if read_byte(stream) is
{
failure then failure, //can't read on stream !!
success(_b) then
if _b = '/' then //can't find / => syntax error
_xml_tag_content(stream, tag, [], content, false, false, true)
else
failure
}
else
_xml_tag_content(stream, tag, [], [b . content], false, true, false)
else if in_last_token then
if b = '>' then //just found the end of bracket, so we return the token in LOWER case
if to_lower(implode(reverse(so_far))) = tag then
with _content = implode(reverse(content)),
println("Tag ["+tag+"] content found ["+_content+"]");
success(_content)
else
failure
else
_xml_tag_content(stream, tag, [b . so_far], content, false, false, true)
else
if b = '<' then //just found the begin of token
_xml_tag_content(stream, tag, [], [], true, false, false)
else
_xml_tag_content(stream, tag, [], [], false, false, false)
}
.
define Maybe(String)
xml_pair_tag_content
(
Stream stream,
String tag
)= _xml_tag_content( stream, tag, [], [], false, false, false).
define Maybe(String)
xml_tag_content
(
Stream stream,
String tag
)= _xml_tag_content( stream, tag, [], [], false, true, false).
/***** ARRAY functions ******/
define Maybe(List(XML_RPC_value))
read_values
(
Stream stream,
List(XML_RPC_value) so_far
)=
if read_value(stream) is
{
failure then failure,
success(value) then
if next_xml_token(stream) is
{
none then failure,
token(token) then
if token = "value" then //there is another value we read it
read_values(stream, [value . so_far])
else
unput_string("<"+token+">", stream);
success(reverse([value . so_far]))
}
}.
define Maybe(List(XML_RPC_value))
read_data
(
Stream stream
)=
if next_xml_token(stream) is
{
none then failure,
token(token) then
if token = "data" then
if next_xml_token(stream) is
{
none then failure,
token(token) then
if token = "value" then
if read_values(stream, []) is
{
failure then failure
success(values) then
if next_xml_token(stream) is
{
none then failure,
token(token) then
if token = "/data" then
success(values)
else
failure
}
}
// mean empty array
else if token = "/data" then
success([])
else
failure
}
else
failure
}.
define Maybe(XML_RPC_value)
read_array
(
Stream stream
)=
if read_data(stream) is
{
failure then failure
success(values) then
if next_xml_token(stream) is
{
none then failure,
token(token) then
if token = "/array" then
success(array(array(values)))
else
failure
}
}.
/***** STRUCT functions ******/
define Maybe(List(XML_RPC_struct_member))
read_members
(
Stream stream,
List(XML_RPC_struct_member) so_far
)=
if xml_pair_tag_content(stream, "name") is
{
failure then failure,
success(member_name) then
if next_xml_token(stream) is
{
none then failure,
token(tok) then
if tok = "value" then
if read_value(stream) is
{
failure then failure,
success(value) then
if next_xml_token(stream) is
{
none then failure,
token(tok) then
if tok = "/member" then
if next_xml_token(stream) is
{
none then failure,
token(tok) then
if tok = "member" then //there is another member in structure, we read it
read_members(stream, [member(member_name, value) . so_far])
else if tok = "/struct" then //End of structrue found
//println("End struct");
success(reverse([member(member_name, value) . so_far])) //return all members in right order
else
failure //unexpected token
}
else
failure
}
}
else
failure
}
} .
define Maybe(XML_RPC_value)
read_struct
(
Stream stream
)=
if next_xml_token(stream) is
{
none then failure,
token(token) then
//there is member hence read it
if token = "member" then
if read_members(stream, []) is
{
failure then failure
success(members_list) then success(struct(members(members_list)))
}
//the immediate following token is . Hence this is an empty struct
else if token = "/struct" then
success(struct(members([])))
else
failure
}.
define Maybe(XML_RPC_value)
read_value
(
Stream stream
)=
if next_xml_token(stream) is
{
none then failure,
token(token) then
with value = if token = "string" then
if xml_tag_content(stream, "string") is
{
failure then failure,
success(v) then success(string(v))
}
else if token = "int" then
if xml_tag_content(stream, "int") is
{
failure then failure,
success(v) then
if decimal_scan(v) is
{
failure then failure,
success(int_v) then success(int(truncate_to_Word32(int_v)))
}
}
else if token = "i4" then
if xml_tag_content(stream, "i4") is
{
failure then failure,
success(v) then
if decimal_scan(v) is
{
failure then failure,
success(int_v) then success(int(truncate_to_Word32(int_v)))
}
}
else if token = "boolean" then
if xml_tag_content(stream, "boolean") is
{
failure then failure,
success(v) then success(bool(to_Bool(v)))
}
else if token = "double" then
if xml_tag_content(stream, "string") is
{
failure then failure,
success(v) then success(double(0.0))
}
else if token = "datetime" then
if xml_tag_content(stream, "string") is
{
failure then failure,
success(v) then success(datetime(v))
}
else if token = "base64" then
if xml_tag_content(stream, "base64") is
{
failure then failure,
success(b64) then success(base64(b64))
}
else if token = "struct" then read_struct(stream)
else if token = "array" then read_array(stream)
else if token = "nil/" then success(nil)
else
println("Unknown token ["+token+"]");
failure,
if next_xml_token(stream) is
{
none then failure
token(token) then
if token = "/value" then
value
else
failure
}
}.
define Maybe(XML_RPC_parameter)
in_value
(
Stream stream,
List(XML_RPC_value) so_far
)=
if next_xml_token(stream) is
{
none then failure,
token(tok) then
if tok = "value" then
if read_value(stream) is
{
failure then failure,
success(value) then in_value(stream, [ value. so_far])
}
else if tok = "/param" then
success(parameter(reverse(so_far)))
else
failure
}.
define Maybe(XML_RPC_value)
in_fault
(
Stream stream,
)=
if next_xml_token(stream) is
{
none then failure,
token(tok) then
if tok = "value" then
if read_value(stream) is
{
failure then failure,
success(value) then
if next_xml_token(stream) is
{
none then failure,
token(tok) then
if tok = "/fault" then
success(value)
else
failure
}
}
else
failure
}.
define Maybe(XML_RPC_parameters)
in_param
(
Stream stream,
List(XML_RPC_parameter) so_far
)=
if next_xml_token(stream) is
{
none then failure,
token(tok) then
if tok = "param" then
if in_value(stream, []) is
{
failure then failure,
success(param) then in_param(stream, [ param . so_far])
}
else if tok = "/params" then
success(parameters(reverse(so_far)))
else
failure
}
.
define Maybe(XML_RPC_response)
in_params
(
Stream stream
)=
if next_xml_token(stream) is
{
none then failure,
token(tok) then
if tok = "params" then
if in_param(stream, []) is
{
failure then failure,
success(resp) then success(ok(resp))
}
else if tok = "fault" then
if in_fault(stream) is
{
failure then failure,
success(resp) then success(fault(resp))
}
else
failure
}
.
public define Maybe(XML_RPC_response)
xml_rpc_get_response
(
String response
)=
with stream = make_stream(response),
if next_xml_token(stream) is
{
none then failure
token(tok) then
if tok = "?xml version='1.0'?" then
if next_xml_token(stream) is
{
none then failure
token(_tok) then
if _tok = "methodresponse" then
in_params(stream)
else
failure
}
else
failure
}.