From 011535f0de1a14d6f5f411035bff9eeafec1c612 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 11 Sep 2012 15:45:59 +0200 Subject: binary refactoring --- src/xmlrpc_encode.erl | 184 +++++++++++++++++++++++--------------------------- 1 file changed, 83 insertions(+), 101 deletions(-) (limited to 'src/xmlrpc_encode.erl') diff --git a/src/xmlrpc_encode.erl b/src/xmlrpc_encode.erl index be2d3b526..a903360dc 100644 --- a/src/xmlrpc_encode.erl +++ b/src/xmlrpc_encode.erl @@ -3,10 +3,10 @@ %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions -%% are met: +%% are met: %% %% 1. Redistributions of source code must retain the above copyright -%% notice, this list of conditions and the following disclaimer. +%% 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 @@ -25,121 +25,103 @@ %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -module(xmlrpc_encode). + -author('jocke@gleipnir.com'). + -export([payload/1]). %% Exported: payload/1 -payload({call, Name, Params}) when atom(Name), list(Params) -> - case encode_params(Params) of - {error, Reason} -> {error, Reason}; - EncodedParams -> - EncodedPayload = - ["", - atom_to_list(Name), "", EncodedParams, - ""], - {ok, EncodedPayload} - end; -payload({response, {fault, Code, String}}) when integer(Code) -> - case xmlrpc_util:is_string(String) of - yes -> - EncodedPayload = - ["" - "faultCode", - integer_to_list(Code), "" - "faultString", escape_string(String), - "", - ""], - {ok, EncodedPayload}; - no -> {error, {bad_string, String}} - end; -payload({response, []} = Payload) -> - {ok, [""]}; -payload({response, [Param]} = Payload) -> - case encode_params([Param]) of - {error, Reason} -> {error, Reason}; - EncodedParam -> - {ok, ["", EncodedParam, - ""]} - end; -payload(Payload) -> {error, {bad_payload, Payload}}. +-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(Params) -> encode_params(Params, <<>>). -encode_params([], []) -> []; -encode_params([], Acc) -> ["", Acc, ""]; -encode_params([Param|Rest], Acc) -> - case encode(Param) of - {error, Reason} -> {error, Reason}; - EncodedParam -> - NewAcc = Acc++["", EncodedParam, ""], - encode_params(Rest, NewAcc) - end. +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}) -> - case encode_members(Struct) of - {error, Reason} -> {error, Reason}; - Members -> ["", Members, ""] - end; -encode({array, Array}) when list(Array) -> - case encode_values(Array)of - {error, Reason} -> {error, Reason}; - Values -> ["", Values, ""] - end; -encode(Integer) when integer(Integer) -> - ["", integer_to_list(Integer), ""]; -encode(true) -> "1"; % duh! -encode(false) -> "0"; % duh! -encode(Double) when float(Double) -> - ["", io_lib:format("~p", [Double]), ""]; + 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}) -> - case xmlrpc_util:is_iso8601_date(Date) of - yes -> ["", Date, ""]; - no -> {error, {bad_date, Date}} - end; + <<"", Date/binary, "">>; encode({base64, Base64}) -> - case xmlrpc_util:is_base64(Base64) of - yes -> ["", Base64, ""]; - no -> {error, {bad_base64, Base64}} - end; + <<"", Base64/binary, "">>; encode(Value) -> - case xmlrpc_util:is_string(Value) of - yes -> escape_string(Value); - no -> {error, {bad_value, Value}} - end. + escape_string(Value). -escape_string([]) -> []; -escape_string([$<|Rest]) -> ["<", escape_string(Rest)]; -escape_string([$>|Rest]) -> [">", escape_string(Rest)]; -escape_string([$&|Rest]) -> ["&", escape_string(Rest)]; -escape_string([C|Rest]) -> [C|escape_string(Rest)]. +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(Struct) -> encode_members(Struct, <<>>). encode_members([], Acc) -> Acc; -encode_members([{Name, Value}|Rest], Acc) when atom(Name) -> - case encode(Value) of - {error, Reason} -> {error, Reason}; - EncodedValue -> - NewAcc = - Acc++["", atom_to_list(Name), "", - EncodedValue, ""], - encode_members(Rest, NewAcc) - end; -encode_members([{Name, Value}|Rest], Acc) -> {error, {invalid_name, Name}}; -encode_members(UnknownMember, Acc) -> - {error, {unknown_member, UnknownMember}}. +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(Array) -> encode_values(Array, <<>>). encode_values([], Acc) -> Acc; -encode_values([Value|Rest], Acc) -> - case encode(Value) of - {error, Reason} -> {error, Reason}; - EncodedValue -> - NewAcc = Acc++["", EncodedValue, ""], - encode_values(Rest, NewAcc) - end; -encode_values([{Name, Value}|Rest], Acc) -> {error, {invalid_name, Name}}; -encode_values(UnknownMember, Acc) -> - {error, {unknown_member, UnknownMember}}. +encode_values([Value | Rest], Acc) -> + NewAcc = <", + (encode(Value))/binary, + "">>, + encode_values(Rest, NewAcc). -- cgit v1.2.3