From c466c7b91578ff3bca2bf52eb7c1542499db38a7 Mon Sep 17 00:00:00 2001 From: Olav Frengstad Date: Sat, 3 Oct 2015 05:49:41 +0200 Subject: [PATCH] Add support for encoding '+-infinity' Erlang can't process the float that is equivialant of Javascripts Infinity (Number.(POSITIVE,NEGATIVE)_INFINITY) which essentially is the max- and minimum floating point. Since there is no concept of a minimum value both are atoms. This means you can compare any number to '+infinity" and it will always be larger; however '-infinity' will also be larger than any number. --- src/bson_binary.erl | 9 +++++++-- test/bson_tests.erl | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/bson_binary.erl b/src/bson_binary.erl index 49e3719..16c7971 100644 --- a/src/bson_binary.erl +++ b/src/bson_binary.erl @@ -71,6 +71,8 @@ put_field(N, {javascript, {}, Code}) -> < <>; put_field(N, {mongostamp, Inc, Time}) -> <>; put_field(N, UnixTime = {_, _, _}) -> <>; +put_field(N, '+infinity') -> <>; +put_field(N, '-infinity') -> <>; put_field(N, V) when is_float(V) -> <>; put_field(N, V) when is_binary(V) -> <>; put_field(N, V) when is_tuple(V) -> <>; @@ -84,8 +86,11 @@ put_field(N, V) -> erlang:error(bad_bson, [N, V]). %% @private get_field(<<1:8, _/binary>>, _, Bin1, _) -> - <> = Bin1, - {N, Bin2}; + case Bin1 of + <<0, 0, 0, 0, 0, 0, 240, 127, Bin2/binary>> -> {'+infinity', Bin2}; + <<0, 0, 0, 0, 0, 0, 240, 255, Bin2/binary>> -> {'-infinity', Bin2}; + <> -> {N, Bin2} + end; get_field(<<2:8, _/binary>>, _, Bin1, _) -> get_string(Bin1); get_field(<<3:8, _/binary>>, _, Bin1, map) -> diff --git a/test/bson_tests.erl b/test/bson_tests.erl index 5fbc64b..893e425 100644 --- a/test/bson_tests.erl +++ b/test/bson_tests.erl @@ -145,4 +145,19 @@ maps_flattering_test() -> <<"personal.country.domen">> => <<"su">>, <<"email">> => <<"test@test.su">> }, - ?assertEqual(FlattenMap, Result). \ No newline at end of file + ?assertEqual(FlattenMap, Result). + +infinity_test() -> + Encoded = <<16#2b, 16#00, 16#00, 16#00, 16#01, 16#2b, 16#69, 16#6e, 16#66, + 16#69, 16#6e, 16#69, 16#74, 16#79, 16#00, 16#00, 16#00, 16#00, + 16#00, 16#00, 16#00, 16#f0, 16#7f, 16#01, 16#2d, 16#69, 16#6e, + 16#66, 16#69, 16#6e, 16#69, 16#74, 16#79, 16#00, 16#00, 16#00, + 16#00, 16#00, 16#00, 16#00, 16#f0, 16#ff, 16#00>>, + + ?assertEqual( + {{<<"+infinity">>, '+infinity', <<"-infinity">>, '-infinity'}, <<>>}, + bson_binary:get_document(Encoded)), + + Doc = #{<<"+infinity">> => '+infinity', <<"-infinity">> => '-infinity'}, + Encoded2 = bson_binary:put_document(Doc), + ?assertEqual(Encoded, Encoded2).