/* * 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 }.