anchor.diff:          {ok, Rest} ->
               recv(Socket, <<Bin/binary, Rest/binary>>, 8);
           _ ->
  -            {recv_error, {invalid_data_length, GotSize}}
  +            {error, {invalid_data_length, GotSize}}
       end;
   recv(Socket, << "*",
                   Type:?BLEN_TYPE_LEN/binary,
                   BodyLen:?BLEN_BODY_LEN/integer, "\r\n", Rest/binary >>, Size) ->
       GotSize = byte_size(Rest),
  -    WantSize = BodyLen + 2 - GotSize,
  +    NeedSize = BodyLen + 2,
  +    WantSize = NeedSize - GotSize,
       case WantSize of
  -        0 ->
  -            recv_0(Type, <<Rest/binary>>);
  -        RecvByte when RecvByte < 0 ->
  -            {recv_error, {invalid_data_length, RecvByte}};
  +        RecvByte when RecvByte =< 0 ->
  +            <<TargetBin:NeedSize/binary, NextBin/binary>> = Rest, 
  +            recv_0(Type, TargetBin, NextBin);
           RecvByte ->
               case gen_tcp:recv(Socket, RecvByte, ?RECV_TIMEOUT) of
                   {ok, Rest2} ->
  -                    recv_0(Type, <<Rest/binary, Rest2/binary>>);
  +                    recv_0(Type, <<Rest/binary, Rest2/binary>>, <<>>);
                   _ ->
  -                    {recv_error, {invalid_data_length, Size}}
  +                    {error, {invalid_data_length, Size}}
               end
       end.
   
  -recv_0(?BIN_ORG_TYPE_BIN, << Len:?BLEN_PARAM_TERM/integer, "\r\n", Rest/binary >>) ->
  +recv_0(?BIN_ORG_TYPE_BIN, << Len:?BLEN_PARAM_TERM/integer, "\r\n", Rest/binary >>, NextBin) ->
       << RetBin:Len/binary, "\r\n\r\n" >> = Rest,
  -    RetBin;
  -recv_0(?BIN_ORG_TYPE_TERM, << Len:?BLEN_PARAM_TERM/integer, "\r\n", Rest/binary >>) ->
  +    {value, RetBin, NextBin};
  +recv_0(?BIN_ORG_TYPE_TERM, << Len:?BLEN_PARAM_TERM/integer, "\r\n", Rest/binary >>, NextBin) ->
       << Term:Len/binary, "\r\n\r\n" >> = Rest,
  -    binary_to_term(Term);
  -recv_0(?BIN_ORG_TYPE_TUPLE, << Len:?BLEN_PARAM_TERM/integer, "\r\n", Rest/binary >>) ->
  -    recv_1(Len, Rest, []);
  -recv_0(InvalidType, _Rest) ->
  -    {recv_error, {invalid_root_type, InvalidType}}.
  -
  -recv_1(_, <<"\r\n">>, Acc) ->
  -    list_to_tuple(Acc);
  -recv_1(Len, << "B\r\n", Rest1/binary >>, Acc) ->
  -    recv_2(Len, ?BIN_ORG_TYPE_BIN, Rest1, Acc);
  -recv_1(Len, << "M\r\n", Rest1/binary >>, Acc) ->
  -    recv_2(Len, ?BIN_ORG_TYPE_TERM, Rest1, Acc);
  -recv_1(Len, << "T\r\n", Rest1/binary >>, Acc) ->
  -    recv_2(Len, ?BIN_ORG_TYPE_TUPLE, Rest1, Acc);
  -recv_1(_,_InvalidBlock,_) ->
  -    {recv_error, {invalid_tuple_type, _InvalidBlock}}.
  -
  -recv_2(Len, Type, Rest1, Acc) ->
  +    {value, binary_to_term(Term), NextBin};
  +recv_0(?BIN_ORG_TYPE_TUPLE, << Len:?BLEN_PARAM_TERM/integer, "\r\n", Rest/binary >>, NextBin) ->
  +    recv_1(Len, Rest, [], NextBin);
  +recv_0(InvalidType, _Rest, _NextBin) ->
  +    {error, {invalid_root_type, InvalidType}}.
  +
  +recv_1(_, <<"\r\n">>, Acc, NextBin) ->
  +    {value, list_to_tuple(Acc), NextBin};
  +recv_1(Len, << "B\r\n", Rest1/binary >>, Acc, NextBin) ->
  +    recv_2(Len, ?BIN_ORG_TYPE_BIN, Rest1, Acc, NextBin);
  +recv_1(Len, << "M\r\n", Rest1/binary >>, Acc, NextBin) ->
  +    recv_2(Len, ?BIN_ORG_TYPE_TERM, Rest1, Acc, NextBin);
  +recv_1(Len, << "T\r\n", Rest1/binary >>, Acc, NextBin) ->
  +    recv_2(Len, ?BIN_ORG_TYPE_TUPLE, Rest1, Acc, NextBin);
  +recv_1(_,_InvalidBlock,_,_NextBin) ->
  +    {error, {invalid_tuple_type, _InvalidBlock}}.
  +
  +recv_2(Len, Type, Rest1, Acc, NextBin) ->
       case (byte_size(Rest1) > Len) of
           true ->
               << Item:Len/binary, "\r\n", Rest2/binary >> = Rest1,
  
positive.code:                        _ ->
                             [binary_to_term(Item)|Acc]
                     end,
              recv_1(Len2, Rest4, Acc1);
          false ->
              {recv_error, {invalid_data_length, Len, Type, Rest1}}
      end.
  
  
  
negative.code: %%    >>
  %%
  -spec(recv(pid(), binary()) ->
        {value, any(), binary()} | {error, any()}).
  recv(Socket, Bin) ->
      Size = byte_size(Bin),
      recv(Socket, Bin, Size).
  