1

私はerlangに不慣れで、erlang-mysql-driverを勉強しています。関数「get_lcb」でバイナリを解析するときに、なぜここでエンディアンが少ないのかを理解するのを手伝ってくれる人はいますか?

以下はmysql_conn.erlのコードです

%%--------------------------------------------------------------------
%% Function: get_query_response(LogFun, RecvPid)
%%           LogFun  = undefined | function() with arity 3
%%           RecvPid = pid(), mysql_recv process
%%           Version = integer(), Representing MySQL version used
%% Descrip.: Wait for frames until we have a complete query response.
%% Returns :   {data, #mysql_result}
%%             {updated, #mysql_result}
%%             {error, #mysql_result}
%%           FieldInfo    = list() of term()
%%           Rows         = list() of [string()]
%%           AffectedRows = int()
%%           Reason       = term()
%%--------------------------------------------------------------------
get_query_response(LogFun, RecvPid, Version) ->
    case do_recv(LogFun, RecvPid, undefined) of
    {ok, Packet, _} ->
        {Fieldcount, Rest} = get_lcb(Packet),
        case Fieldcount of
        0 ->
            %% No Tabular data
            <<AffectedRows:8, Rest2/binary>> = Rest,
            io:format("Rest2=~p~n", [Rest2]),
            {InsertId, _} = get_lcb(Rest2),
            io:format("InsertId=~p~n", [InsertId]),
            {updated, #mysql_result{affectedrows=AffectedRows, insertid=InsertId}};
        255 ->
            <<_Code:16/little, Message/binary>>  = Rest,
            {error, #mysql_result{error=Message}};
        _ ->
            %% Tabular data received
            case get_fields(LogFun, RecvPid, [], Version) of
            {ok, Fields} ->
                case get_rows(Fields, LogFun, RecvPid, []) of
                {ok, Rows} ->
                    {data, #mysql_result{fieldinfo=Fields,
                             rows=Rows}};
                {error, Reason} ->
                    {error, #mysql_result{error=Reason}}
                end;
            {error, Reason} ->
                {error, #mysql_result{error=Reason}}
            end
        end;
    {error, Reason} ->
        {error, #mysql_result{error=Reason}}
    end.


get_lcb(<<251:8, Rest/binary>>) ->
    {null, Rest};
get_lcb(<<252:8, Value:16/little, Rest/binary>>) ->
    io:format("Value=~p~n",[Value]),
    io:format("Rest=~p~n",[Rest]),
    {Value, Rest};
get_lcb(<<253:8, Value:24/little, Rest/binary>>) ->
    {Value, Rest};
get_lcb(<<254:8, Value:32/little, Rest/binary>>) ->
    {Value, Rest};
get_lcb(<<Value:8, Rest/binary>>) when Value < 251 ->
    {Value, Rest};
get_lcb(<<255:8, Rest/binary>>) ->
    {255, Rest}.


%%--------------------------------------------------------------------
%% Function: do_recv(LogFun, RecvPid, SeqNum)
%%           LogFun  = undefined | function() with arity 3
%%           RecvPid = pid(), mysql_recv process
%%           SeqNum  = undefined | integer()
%% Descrip.: Wait for a frame decoded and sent to us by RecvPid.
%%           Either wait for a specific frame if SeqNum is an integer,
%%           or just any frame if SeqNum is undefined.
%% Returns : {ok, Packet, Num} |
%%           {error, Reason}
%%           Reason = term()
%%
%% Note    : Only to be used externally by the 'mysql_auth' module.
%%--------------------------------------------------------------------
do_recv(LogFun, RecvPid, SeqNum)  when is_function(LogFun);
                       LogFun == undefined,
                       SeqNum == undefined ->
    receive
        {mysql_recv, RecvPid, data, Packet, Num} ->
        {ok, Packet, Num};
    {mysql_recv, RecvPid, closed, _E} ->
        {error, "mysql_recv: socket was closed"}
    end;
do_recv(LogFun, RecvPid, SeqNum) when is_function(LogFun);
                      LogFun == undefined,
                      is_integer(SeqNum) ->
    ResponseNum = SeqNum + 1,
    receive
        {mysql_recv, RecvPid, data, Packet, ResponseNum} ->
        {ok, Packet, ResponseNum};
    {mysql_recv, RecvPid, closed, _E} ->
        {error, "mysql_recv: socket was closed"}
    end.
4

1 に答える 1

0

次の行を意味していると思います:Value:16/littleValue:24/little、など...?これは、MySQL サーバーが応答パケットのこれらの部分を常にリトル エンディアン値で満たすためです。しかし、デフォルトでは、Erlang マシンは CPU 固有のエンディアンで動作します。

于 2012-09-04T09:10:41.090 に答える