diff --git a/c_src/exml.cpp b/c_src/exml.cpp index c446d2d..1d9685b 100644 --- a/c_src/exml.cpp +++ b/c_src/exml.cpp @@ -583,9 +583,10 @@ static ERL_NIF_TERM parse_next(ErlNifEnv *env, int argc, } if (error_msg) { - return enif_make_tuple2( - env, atom_error, - enif_make_string(env, error_msg, ERL_NIF_LATIN1)); + ERL_NIF_TERM error_message = + to_subbinary(ctx, (const unsigned char *)error_msg, strlen(error_msg)); + + return enif_make_tuple2(env, atom_error, error_message); } return enif_make_tuple3( @@ -608,9 +609,12 @@ static ERL_NIF_TERM parse(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_tuple2(env, atom_ok, element); } - return enif_make_tuple2( - env, atom_error, - enif_make_string(env, result.error_message.c_str(), ERL_NIF_LATIN1)); + ERL_NIF_TERM error_message = + to_subbinary(ctx, + (const unsigned char *)result.error_message.c_str(), + result.error_message.size()); + + return enif_make_tuple2(env, atom_error, error_message); } static ERL_NIF_TERM escape_cdata(ErlNifEnv *env, int argc, diff --git a/include/exml.hrl b/include/exml.hrl index 34d8628..b3198fe 100644 --- a/include/exml.hrl +++ b/include/exml.hrl @@ -11,7 +11,7 @@ -record(xmlel, {name :: binary(), attrs = #{} :: exml:attrs(), - children = [] :: [exml:element() | exml:cdata()]}). + children = [] :: [exml:child()]}). %% Implementation of the exmlAssertEqual/2 macro is a modification of %% https://github.com/erszcz/rxml/commit/e8483408663f0bc2af7896e786c1cdea2e86e43d#diff-2cb5d18741df32f4ead70c21fdd221d1 diff --git a/src/exml.erl b/src/exml.erl index b6feb23..3699d4c 100644 --- a/src/exml.erl +++ b/src/exml.erl @@ -28,13 +28,12 @@ remove_attr/2, xml_sort/1]). --export_type([attr/0, - attrs/0, +-export_type([attrs/0, cdata/0, element/0, + child/0, item/0]). --type attr() :: {binary(), binary()}. -type attrs() :: #{binary() => binary()}. -type cdata() :: #xmlcdata{}. %% CDATA record. Printing escaping rules defaults to escaping character-wise. @@ -45,7 +44,8 @@ %%
  • `cdata': wraps the entire string into a `' section.
  • %% -type element() :: #xmlel{}. --type item() :: element() | attr() | cdata() | exml_stream:start() | exml_stream:stop(). +-type item() :: element() | cdata() | exml_stream:start() | exml_stream:stop(). +-type child() :: element() | cdata(). -type prettify() :: pretty | not_pretty. %% Printing indentation rule, see `to_iolist/2'. @@ -87,7 +87,6 @@ xml_size({Key, Value}) when is_binary(Key) -> %% https://github.com/erszcz/rxml/commit/e8483408663f0bc2af7896e786c1cdea2e86e43d -spec xml_sort([item()]) -> [item()]; (element()) -> element(); - (attr()) -> attr(); (cdata()) -> cdata(); (exml_stream:start()) -> exml_stream:start(); (exml_stream:stop()) -> exml_stream:stop(). @@ -101,8 +100,6 @@ xml_sort(#xmlstreamstart{} = StreamStart) -> StreamStart; xml_sort(#xmlstreamend{} = StreamEnd) -> StreamEnd; -xml_sort({Key, Value}) -> - {Key, Value}; xml_sort(Elements) when is_list(Elements) -> lists:sort([ xml_sort(E) || E <- Elements ]). diff --git a/src/exml_stream.erl b/src/exml_stream.erl index 27e87d1..c65997c 100644 --- a/src/exml_stream.erl +++ b/src/exml_stream.erl @@ -31,7 +31,7 @@ %% `#xmlstreamend{}' record. -type parser() :: #parser{}. %% `#parser{}' record. Keeps track of unparsed buffers. --type element() :: exml:element() | exml_stream:start() | exml_stream:stop(). +-type element() :: exml:element() | start() | stop(). %% One of `t:exml:element/0', `t:start/0', or `t:stop/0'. -type parser_opt() :: {infinite_stream, boolean()} | {max_element_size, non_neg_integer()}. @@ -69,7 +69,7 @@ new_parser(Opts)-> %% %% If successful, returns parsed elements and a new parser with updated buffers. -spec parse(parser(), binary()) -> - {ok, parser(), [exml_stream:element()]} | {error, Reason :: any()}. + {ok, parser(), [element()]} | {error, Reason :: binary()}. parse(Parser, Input) when is_binary(Input) -> #parser{event_parser = EventParser, buffer = OldBuf} = Parser, Buffer = OldBuf ++ [Input], diff --git a/test/exml_stream_tests.erl b/test/exml_stream_tests.erl index c2dedd3..795faac 100644 --- a/test/exml_stream_tests.erl +++ b/test/exml_stream_tests.erl @@ -188,45 +188,45 @@ stream_max_opening_tag_size_test() -> ?assertMatch({ok, _Parser1, [#xmlstreamstart{}, #xmlel{}]}, exml_stream:parse(Parser0, <<"">>)), {ok, Parser2} = exml_stream:new_parser([{max_element_size, 9}]), - ?assertEqual({error, "element too big"}, exml_stream:parse(Parser2, <<"">>)). + ?assertEqual({error, <<"element too big">>}, exml_stream:parse(Parser2, <<"">>)). stream_max_element_size_test() -> {ok, Parser0} = exml_stream:new_parser([{max_element_size, 10}]), {ok, Parser1, Elements0} = exml_stream:parse(Parser0, <<"">>), ?assertMatch([#xmlstreamstart{}, #xmlel{}], Elements0), - ?assertEqual({error, "element too big"}, exml_stream:parse(Parser1, <<"">>)). + ?assertEqual({error, <<"element too big">>}, exml_stream:parse(Parser1, <<"">>)). stream_max_text_element_size_test() -> {ok, Parser0} = exml_stream:new_parser([{max_element_size, 10}]), {ok, Parser1, Elements0} = exml_stream:parse(Parser0, <<"123123">>), ?assertMatch([#xmlstreamstart{}, #xmlel{}, #xmlel{}], Elements0), - ?assertEqual({error, "element too big"}, exml_stream:parse(Parser1, <<"1234">>)). + ?assertEqual({error, <<"element too big">>}, exml_stream:parse(Parser1, <<"1234">>)). stream_max_incomplete_element_size_test() -> {ok, Parser0} = exml_stream:new_parser([{max_element_size, 10}]), {ok, Parser1, Elements0} = exml_stream:parse(Parser0, <<"123123">>), ?assertMatch([#xmlstreamstart{}, #xmlel{}, #xmlel{}], Elements0), %% Element has 10 characters, but it's incomplete, so it would be too big - ?assertEqual({error, "element too big"}, exml_stream:parse(Parser1, <<"1234>)). + ?assertEqual({error, <<"element too big">>}, exml_stream:parse(Parser1, <<"1234>)). stream_max_chunked_element_size_test() -> {ok, Parser0} = exml_stream:new_parser([{max_element_size, 10}]), {ok, Parser1, Elements0} = exml_stream:parse(Parser0, <<"">>), ?assertMatch([#xmlstreamstart{}], Elements0), - ?assertEqual({error, "element too big"}, exml_stream:parse(Parser1, <<" ">>)). + ?assertEqual({error, <<"element too big">>}, exml_stream:parse(Parser1, <<" ">>)). stream_max_root_element_size_test() -> {ok, Parser0} = exml_stream:new_parser([{max_element_size, 10}, {infinite_stream, true}]), {ok, Parser1, Elements0} = exml_stream:parse(Parser0, <<"123123">>), ?assertMatch([#xmlel{}, #xmlel{}], Elements0), - ?assertEqual({error, "element too big"}, exml_stream:parse(Parser1, <<"">>)). + ?assertEqual({error, <<"element too big">>}, exml_stream:parse(Parser1, <<"">>)). stream_max_incomplete_root_element_size_test() -> {ok, Parser0} = exml_stream:new_parser([{max_element_size, 10}, {infinite_stream, true}]), {ok, Parser1, Elements0} = exml_stream:parse(Parser0, <<"123123">>), ?assertMatch([#xmlel{}, #xmlel{}], Elements0), %% Element has 10 characters, but it will have at least one more character - ?assertEqual({error, "element too big"}, exml_stream:parse(Parser1, <<"1234>)). + ?assertEqual({error, <<"element too big">>}, exml_stream:parse(Parser1, <<"1234>)). infinite_stream_partial_chunk_test() -> {ok, Parser0} = exml_stream:new_parser([{infinite_stream, true}]), diff --git a/test/exml_tests.erl b/test/exml_tests.erl index 81924fc..bb3e40b 100644 --- a/test/exml_tests.erl +++ b/test/exml_tests.erl @@ -52,11 +52,6 @@ sort_xmlel_identity_test() -> }, ?assertEqual(El, exml:xml_sort(El)). -sort_xmlel_attributes_test() -> - Attrs = [{<<"attr1">>, <<"foo">>}, {<<"attr2">>, <<"bar">>}], - ToOrder = [{<<"attr2">>, <<"bar">>}, {<<"attr1">>, <<"foo">>}], - ?assertEqual(Attrs, exml:xml_sort(ToOrder)). - remove_cdata_test() -> Attrs = #{<<"attr1">> => <<"foo">>, <<"attr2">> => <<"bar">>}, Child1 = #xmlel{name = <<"el1">>, attrs = Attrs},