%% Copyright (C) 2003 Joakim Grebenö . %% All rights reserved. %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions %% are met: %% %% 1. Redistributions of source code must retain the above copyright %% notice, this list of conditions and the following disclaimer. %% 2. Redistributions in binary form must reproduce the above %% copyright notice, this list of conditions and the following %% disclaimer in the documentation and/or other materials provided %% with the distribution. %% %% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS %% OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED %% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY %% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE %% GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS %% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, %% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING %% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -module(xmlrpc_encode). -author('jocke@gleipnir.com'). -export([payload/1]). %% Exported: payload/1 -type xmlrpc() :: number() | boolean() | binary() | {base64, binary()} | {date, binary()} | {array, [xmlrpc()]} | {struct, [{atom(), xmlrpc()}]}. -spec payload({call, atom(), [xmlrpc()]} | {response, {fault, integer(), binary()} | [xmlrpc()]}) -> binary(). payload({call, Name, Params}) -> <<"", (jlib:atom_to_binary(Name))/binary, "", (encode_params(Params))/binary, "">>; payload({response, {fault, Code, String}}) -> <<"faultCode", (jlib:integer_to_binary(Code))/binary, "faultStr" "ing", (escape_string(String))/binary, "">>; payload({response, []}) -> <<"">>; payload({response, [Param]}) -> <<"", (encode_params([Param]))/binary, "">>. encode_params(Params) -> encode_params(Params, <<>>). encode_params([], <<>>) -> <<>>; encode_params([], Acc) -> <<"", Acc/binary, "">>; encode_params([Param | Rest], Acc) -> EncodedParam = encode(Param), NewAcc = <", EncodedParam/binary, "">>, encode_params(Rest, NewAcc). encode({struct, Struct}) -> Members = encode_members(Struct), <<"", Members/binary, "">>; encode({array, Array}) -> Values = encode_values(Array), <<"", Values/binary, "">>; encode(Integer) when is_integer(Integer) -> <<"", (jlib:integer_to_binary(Integer))/binary, "">>; encode(true) -> <<"1">>; % duh! encode(false) -> <<"0">>; % duh! encode(Double) when is_float(Double) -> list_to_binary( [<<"">>, io_lib:format("~p", [Double]), <<"">>]); encode({date, Date}) -> <<"", Date/binary, "">>; encode({base64, Base64}) -> <<"", Base64/binary, "">>; encode(Value) -> escape_string(Value). escape_string(<<>>) -> <<>>; escape_string(<<$<, Rest/binary>>) -> <<"<", (escape_string(Rest))/binary>>; escape_string(<<$>, Rest/binary>>) -> <<">", (escape_string(Rest))/binary>>; escape_string(<<$&, Rest/binary>>) -> <<"&", (escape_string(Rest))/binary>>; escape_string(<>) -> <>. encode_members(Struct) -> encode_members(Struct, <<>>). encode_members([], Acc) -> Acc; encode_members([{Name, Value} | Rest], Acc) -> NewAcc = <", (jlib:atom_to_binary(Name))/binary, "", (encode(Value))/binary, "">>, encode_members(Rest, NewAcc). encode_values(Array) -> encode_values(Array, <<>>). encode_values([], Acc) -> Acc; encode_values([Value | Rest], Acc) -> NewAcc = <", (encode(Value))/binary, "">>, encode_values(Rest, NewAcc).