|
|
- -module(protoMsg).
-
-
- -export([encode/1, decode/1, encodeRec/1, decodeRec/2]).
-
- -define(bool(V), (case V of true -> <<1:8>>; _ -> <<0:8>> end)).
- -define(int8(V), <<V:8>>).
- -define(uint8(V), <<V:8>>).
- -define(int16(V), <<V:16/big>>).
- -define(uint16(V), <<V:16/big>>).
- -define(int32(V), <<V:32/big>>).
- -define(uint32(V), <<V:32/big>>).
- -define(int64(V), <<V:64/big>>).
- -define(uint64(V), <<V:64/big>>).
- -define(float(V), <<V:32/big-float>>).
- -define(double(V), <<V:64/big-float>>).
- -define(string(V), (string(V))).
- -define(record(V), (case V of undefined -> [<<0:8>>]; V -> [<<1:8>>, encodeRec(V)] end)).
- -define(list_bool(List), [<<(length(List)):16/big>>, [?bool(V) || V <- List]]).
- -define(list_int8(List), [<<(length(List)):16/big>>, [?int8(V) || V <- List]]).
- -define(list_uint8(List), [<<(length(List)):16/big>>, [?uint8(V) || V <- List]]).
- -define(list_int16(List), [<<(length(List)):16/big>>, [?int16(V) || V <- List]]).
- -define(list_uint16(List), [<<(length(List)):16/big>>, [?uint16(V) || V <- List]]).
- -define(list_int32(List), [<<(length(List)):16/big>>, [?int32(V) || V <- List]]).
- -define(list_uint32(List), [<<(length(List)):16/big>>, [?uint32(V) || V <- List]]).
- -define(list_int64(List), [<<(length(List)):16/big>>, [?int64(V) || V <- List]]).
- -define(list_uint64(List), [<<(length(List)):16/big>>, [?uint64(V) || V <- List]]).
- -define(list_float(List), [<<(length(List)):16/big>>, [?float(V) || V <- List]]).
- -define(list_double(List), [<<(length(List)):16/big>>, [?double(V) || V <- List]]).
- -define(list_string(List), [<<(length(List)):16/big>>, [string(V) || V <- List]]).
- -define(list_record(List), [<<(length(List)):16/big>>, [encodeRec(V) || V <- List]]).
-
- string(Str) when is_binary(Str) ->
- [<<(byte_size(Str)):16/big>>, Str];
- string(Str) ->
- Str2 = unicode:characters_to_binary(Str, utf8),
- [<<(byte_size(Str2)):16/big>>, Str2].
-
- encode(Record) ->
- MsgBin = encodeRec(Record),
- MsgId = getMsgId(element(1, Record)),
- [<<MsgId:16/big>>, MsgBin].
-
- decode(Bin) ->
- <<MsgId:16/big, MsgBin/binary>> = Bin,
- SchList = getMsgSchema(MsgId),
- {<<>>, ResultList} = decodeField(SchList, MsgBin, [getMsgType(MsgId)]),
- list_to_tuple(ResultList).
-
- decodeRec(RecordName, Bin) ->
- SchList = getMsgSchema(RecordName),
- {LeftBin, Result} = decodeField(SchList, Bin, [RecordName]),
- {LeftBin, list_to_tuple(Result)}.
-
- decodeField([], LeftBin, Result) ->
- {LeftBin, lists:reverse(Result)};
- decodeField([Type | SchList], MsgBin, Result) ->
- case Type of
- int32 ->
- <<Int:32/big-signed, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Int | Result]);
- uint32 ->
- <<Int:32/big-unsigned, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Int | Result]);
- string ->
- <<Len:16/big, StrBin:Len/binary, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [StrBin | Result]);
- int16 ->
- <<Int:16/big-signed, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Int | Result]);
- uint16 ->
- <<Int:16/big-unsigned, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Int | Result]);
- int8 ->
- <<Int:8/big-signed, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Int | Result]);
- uint8 ->
- <<Int:8/big-unsigned, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Int | Result]);
- int64 ->
- <<Int:64/big-signed, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Int | Result]);
- uint64 ->
- <<Int:64/big-unsigned, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Int | Result]);
- bool ->
- <<Bool:8/big-unsigned, LeftBin/binary>> = MsgBin,
- case Bool =:= 1 of
- true ->
- decodeField(SchList, LeftBin, [true | Result]);
- _ ->
- decodeField(SchList, LeftBin, [false | Result])
- end;
- falat ->
- <<Float:32/big-float, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Float | Result]);
- double ->
- <<Float:64/big-float, LeftBin/binary>> = MsgBin,
- decodeField(SchList, LeftBin, [Float | Result]);
- {list, int32} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deInt32List(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, uint32} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deUint32List(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, int16} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deInt16List(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, uint16} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deUint16List(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, int8} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deInt8List(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, uint8} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deUint8List(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, string} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deStringList(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, int64} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deInt64List(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, uint64} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deUint64List(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, bool} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deBoolList(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, flat} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deFloatList(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, double} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deDoubleList(Len, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- {list, RecordName} ->
- <<Len:16/big, LeftListBin/binary>> = MsgBin,
- {LeftBin, RetList} = deRecordList(Len, RecordName, LeftListBin, []),
- decodeField(SchList, LeftBin, [RetList | Result]);
- RecordName ->
- <<IsUndef:8, LeftBin/binary>> = MsgBin,
- case IsUndef of
- 0 ->
- decodeField(SchList, LeftBin, [undefined | Result]);
- _ ->
- SubSchList = getMsgSchema(RecordName),
- {SubLeftBin, SubResultList} = decodeField(SubSchList, LeftBin, [RecordName]),
- decodeField(SchList, SubLeftBin, [list_to_tuple(SubResultList) | Result])
- end
- end.
-
- deBoolList(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deBoolList(N, <<Bool:8, LeftBin/binary>>, RetList) ->
- case Bool =:= 1 of
- true ->
- deBoolList(N - 1, LeftBin, [true | RetList]);
- _ ->
- deBoolList(N - 1, LeftBin, [false | RetList])
- end.
- deInt8List(0, MsgBin, RetList) ->
- {MsgBin, RetList};
- deInt8List(N, <<Int:8/big-signed, LeftBin/binary>>, RetList) ->
- deInt8List(N - 1, LeftBin, [Int | RetList]).
-
- deUint8List(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deUint8List(N, <<Int:8/big-unsigned, LeftBin/binary>>, RetList) ->
- deUint8List(N - 1, LeftBin, [Int | RetList]).
-
- deInt16List(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deInt16List(N, <<Int:16/big-signed, LeftBin/binary>>, RetList) ->
- deInt16List(N - 1, LeftBin, [Int | RetList]).
-
- deUint16List(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deUint16List(N, <<Int:16/big-unsigned, LeftBin/binary>>, RetList) ->
- deUint16List(N - 1, LeftBin, [Int | RetList]).
-
- deInt32List(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deInt32List(N, <<Int:32/big-signed, LeftBin/binary>>, RetList) ->
- deInt32List(N - 1, LeftBin, [Int | RetList]).
-
- deUint32List(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deUint32List(N, <<Int:32/big-unsigned, LeftBin/binary>>, RetList) ->
- deUint32List(N - 1, LeftBin, [Int | RetList]).
-
- deInt64List(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deInt64List(N, <<Int:64/big-signed, LeftBin/binary>>, RetList) ->
- deInt64List(N - 1, LeftBin, [Int | RetList]).
-
- deUint64List(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deUint64List(N, <<Int:64/big-unsigned, LeftBin/binary>>, RetList) ->
- deUint64List(N - 1, LeftBin, [Int | RetList]).
-
- deFloatList(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deFloatList(N, <<Float:32/big-float, LeftBin/binary>>, RetList) ->
- deFloatList(N - 1, LeftBin, [Float | RetList]).
-
- deDoubleList(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deDoubleList(N, <<Float:64/big-float, LeftBin/binary>>, RetList) ->
- deDoubleList(N - 1, LeftBin, [Float | RetList]).
-
- deStringList(0, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deStringList(N, <<Len:16/big, StrBin:Len/binary-unit:8, LeftBin/binary>>, RetList) ->
- deStringList(N - 1, LeftBin, [StrBin | RetList]).
-
- deRecordList(0, _RecordName, MsgBin, RetList) ->
- {MsgBin, lists:reverse(RetList)};
- deRecordList(N, RecordName, MsgBin, RetList) ->
- {LeftBin, Tuple} = decodeRec(RecordName, MsgBin),
- deRecordList(N - 1, RecordName, LeftBin, [Tuple | RetList]).
-
- getMsgType(1)->
- test;
- getMsgType(2)->
- phoneNumber;
- getMsgType(3)->
- person;
- getMsgType(4)->
- addressBook;
- getMsgType(_) ->
- undefined.
-
- getMsgId(test)->
- 1;
- getMsgId(phoneNumber)->
- 2;
- getMsgId(person)->
- 3;
- getMsgId(addressBook)->
- 4;
- getMsgId(_) ->
- 0.
-
- encodeRec({test, V1}) ->
- [?string(V1)];
- encodeRec({phoneNumber, V1, V2}) ->
- [?record(V1), ?int32(V2)];
- encodeRec({person, V1, V2, V3, V4}) ->
- [?string(V1), ?int32(V2), ?string(V3), ?list_record(V4)];
- encodeRec({addressBook, V1, V2}) ->
- [?list_record(V1), ?list_record(V2)];
- encodeRec(_) ->
- [].
-
- getMsgSchema(test)->
- getMsgSchema(1);
- getMsgSchema(1)->
- [string];
- getMsgSchema(phoneNumber)->
- getMsgSchema(2);
- getMsgSchema(2)->
- [test,int32];
- getMsgSchema(person)->
- getMsgSchema(3);
- getMsgSchema(3)->
- [string,int32,string,{list,phoneNumber}];
- getMsgSchema(addressBook)->
- getMsgSchema(4);
- getMsgSchema(4)->
- [{list,person},{list,person}];
- getMsgSchema(_) ->
- [].
-
|