|
|
- -module(protoGen).
-
- -export([
- convertFile/1
- , convert/1
- , convertDir/0
- , convertDir/1
- , convertDir/3
- ]).
-
- protoHrlHeader() ->
- "-opaque int8() :: -128..127.
- -opaque int16() :: -32768..32767.
- -opaque int32() :: -2147483648..2147483647.
- -opaque int64() :: -9223372036854775808..9223372036854775807.
- -opaque uint8() :: 0..255.
- -opaque uint16() :: 0..65536.
- -opaque uint32() :: 0..4294967295.
- -opaque uint64() :: 0..18446744073709551615.
- -opaque double() :: float().\n\n".
-
- protoErlHeader() ->
- "-module(protoMsg).\n\n
- -compile([nowarn_unused_vars]).
-
- -export([encode/1, decode/1, encodeRec/1, decodeBin/2]).
-
- -define(min8, -128).
- -define(max8, 127).
- -define(min16, -32768).
- -define(max16, 32767).
- -define(min32, -2147483648).
- -define(max32, 2147483647).
- -define(min64, -9223372036854775808).
- -define(max64, 9223372036854775807).
-
- -define(minF32, -3.4E+38).
- -define(maxF32, 3.4E+38).
- -define(minF64, -1.797E-308).
- -define(maxF64, 1.797E+308).
-
- -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(integer(V), (integer(V))).
- -define(number(V), (number(V))).
- -define(string(V), (string(V))).
- -define(float(V), <<V:32/big-float>>).
- -define(double(V), <<V:64/big-float>>).
- -define(bool(V), (case V of true -> <<1:8>>; _ -> <<0:8>> end)).
- -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_integer(List), [<<(length(List)):16/big>>, [integer(V) || V <- List]]).
- -define(list_number(List), [<<(length(List)):16/big>>, [number(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]]).
-
- -define(BinaryShareSize, 65).
- -define(BinaryCopyRatio, 1.2).
-
- integer(V) ->
- if
- V >= ?min8 andalso V =< ?max8 ->
- <<8:8, <<V:8>>/binary>>;
- V >= ?min16 andalso V =< ?max16 ->
- <<16:8, <<V:16/big>>/binary>>;
- V >= ?min32 andalso V =< ?max32 ->
- <<32:8, <<V:32/big>>/binary>>;
- V >= ?min64 andalso V =< ?max64 ->
- <<64:8, <<V:64/big>>/binary>>;
- true ->
- throw(exceeded_the_integer)
- end.
-
- number(V) ->
- if
- erlang:is_integer(V) ->
- if
- V >= ?min8 andalso V =< ?max8 ->
- <<8:8, <<V:8>>/binary>>;
- V >= ?min16 andalso V =< ?max16 ->
- <<16:8, <<V:16/big>>/binary>>;
- V >= ?min32 andalso V =< ?max32 ->
- <<32:8, <<V:32/big>>/binary>>;
- V >= ?min64 andalso V =< ?max64 ->
- <<64:8, <<V:64/big>>/binary>>;
- true ->
- throw(exceeded_the_integer)
- end;
- erlang:is_float(V) ->
- if
- V >= ?minF32 andalso V =< ?maxF32 ->
- <<33:8, <<V:32/big-float>>/binary>>;
- V >= ?minF64 andalso V =< ?maxF64 ->
- <<65:8, <<V:64/big-float>>/binary>>;
- true ->
- throw(exceeded_the_float)
- end;
- true ->
- throw(is_not_number)
- end.
-
- 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].
-
- decode(Bin) ->
- <<MsgId:16/big, MsgBin/binary>> = Bin,
- decodeBin(MsgId, MsgBin).
-
- deIntegerList(0, MsgBin, RetList) ->
- {lists:reverse(RetList), MsgBin};
- deIntegerList(N, MsgBin, RetList) ->
- <<IntBits:8, Int:IntBits/big-signed, LeftBin/binary>> = MsgBin,
- deIntegerList(N - 1, LeftBin, [Int | RetList]).
-
- deNumberList(0, MsgBin, RetList) ->
- {lists:reverse(RetList), MsgBin};
- deNumberList(N, MsgBin, RetList) ->
- <<NumBits:8, NumBin/binary>> = MsgBin,
- case NumBits of
- 33 ->
- <<Float:32/big-float, LeftBin/binary>> = NumBin,
- deNumberList(N - 1, LeftBin, [Float | RetList]);
- 65 ->
- <<Float:64/big-float, LeftBin/binary>> = NumBin,
- deNumberList(N - 1, LeftBin, [Float | RetList]);
- _ ->
- <<Int:NumBits/big-signed, LeftBin/binary>> = NumBin,
- deNumberList(N - 1, LeftBin, [Int | RetList])
- end.
-
- deStringList(0, MsgBin, _RefSize, RetList) ->
- {lists:reverse(RetList), MsgBin};
- deStringList(N, MsgBin, RefSize, RetList) ->
- <<Len:16/big, StrBin:Len/binary-unit:8, LeftBin/binary>> = MsgBin,
- case Len < ?BinaryShareSize of
- true ->
- deStringList(N - 1, LeftBin, RefSize, [StrBin | RetList]);
- _ ->
- case RefSize / Len > ?BinaryCopyRatio of
- true ->
- StrBinCopy = binary:copy(StrBin),
- deStringList(N - 1, LeftBin, RefSize, [StrBinCopy | RetList]);
- _ ->
- deStringList(N - 1, LeftBin, RefSize, [StrBin | RetList])
- end
- end.
-
- deRecordList(0, _MsgId, MsgBin, RetList) ->
- {lists:reverse(RetList), MsgBin};
- deRecordList(N, MsgId, MsgBin, RetList) ->
- {Tuple, LeftBin} = decodeRec(MsgId, MsgBin),
- deRecordList(N - 1, MsgId, LeftBin, [Tuple | RetList]).\n\n".
-
- genMsgHrl(FieldInfo, {Index, Len, AccList}) ->
- TemStr =
- case Index of
- 1 ->
- "";
- _ ->
- ", "
- end,
- RecStr = TemStr ++ protoField:builtRecStr(FieldInfo) ++ (case Index == Len of true -> ""; _ -> "\t" end),
- {Index - 1, Len, [RecStr | AccList]}.
-
- genErrCodeHrl({ErrName, ErrCodeId, ComDesc}, AccList) ->
- Str = "-define(" ++ ErrName ++ ", " ++ integer_to_list(ErrCodeId) ++ ").\t\t%% " ++ ComDesc ++ "\n",
- [Str | AccList].
-
- genEncodeRec({MsgName, MsgId, FieldList}, IsForBin) ->
- FieldLen = length(FieldList),
- FunHead =
- fun(_, {Index, StrAcc}) ->
- {Index - 1, ", V" ++ integer_to_list(Index) ++ StrAcc}
- end,
- {_, TemStr} = lists:foldr(FunHead, {FieldLen, "}) ->\n\t"}, FieldList),
- HeadStr =
- case IsForBin of
- true ->
- "encode({" ++ MsgName ++ TemStr;
- _ ->
- "encodeRec({" ++ MsgName ++ TemStr
- end,
-
- FunBody =
- fun({FieldType, _FieldName}, {Index, PStrAcc}) ->
- TemV = "V" ++ integer_to_list(Index),
- PackStr = protoField:builtPackStr(FieldType) ++ TemV ++ ")",
- case Index == 1 of
- true ->
- {Index - 1, PackStr ++ PStrAcc};
- _ ->
- {Index - 1, ", " ++ PackStr ++ PStrAcc}
-
- end
- end,
- {_, BodyStr} = lists:foldr(FunBody, {FieldLen, ""}, FieldList),
- case IsForBin of
- true ->
- case FieldLen > 0 of
- true ->
- HeadStr ++ "[<<" ++ integer_to_list(MsgId) ++ ":16/big-unsigned>>, " ++ BodyStr ++ "];\n";
- _ ->
- HeadStr ++ "[<<" ++ integer_to_list(MsgId) ++ ":16/big-unsigned>>];\n"
- end;
- _ ->
- case FieldLen > 0 of
- true ->
- HeadStr ++ "[" ++ BodyStr ++ "];\n";
- _ ->
- HeadStr ++ "[];\n"
- end
- end.
-
- resetPd() ->
- erlang:put(pd_v, 0),
- erlang:put(pd_len, 0),
- erlang:put(pd_bool, 0),
- erlang:put(pd_leftBin, 0),
- erlang:put(pd_intBits, 0),
- erlang:put(pd_numBits, 0),
- erlang:put(pd_listBin, 0),
- erlang:put(pd_isUndef, 0),
- erlang:put(pd_isCalcRefSize, 0).
-
- getIndexStr(Type) ->
- Index = erlang:get(Type),
- erlang:integer_to_list(Index).
-
- useIndexStr(Type) ->
- Index = erlang:get(Type) + 1,
- erlang:put(Type, Index),
- erlang:integer_to_list(Index).
-
- isCalcRefSize() ->
- erlang:get(pd_isCalcRefSize) > 0.
-
- initSubRec() ->
- erlang:put(pd_subRec, []).
-
- getSubRec() ->
- erlang:get(pd_subRec).
-
- addSubRec({MsgName, _MsgId, _FieldList} = Info, IsForBin) when IsForBin ->
- OldList = erlang:get(pd_subRec),
- case lists:keyfind(MsgName, 1, OldList) of
- false ->
- erlang:put(pd_subRec, [Info | OldList]);
- _ ->
- ignore
- end;
- addSubRec(_Info, _IsForBin) ->
- ignore.
-
- genDecodeBin({MsgName, MsgId, FieldList}, SortedSProtoList, IsForBin) ->
- FieldLen = length(FieldList),
- case IsForBin of
- true ->
- HeadStr = "decodeBin(" ++ integer_to_list(MsgId) ++ ", LeftBin" ++ getIndexStr(pd_leftBin) ++ ") ->\n";
- _ ->
- HeadStr = "decodeRec(" ++ integer_to_list(MsgId) ++ ", LeftBin" ++ getIndexStr(pd_leftBin) ++ ") ->\n"
- end,
-
- FunBody =
- fun({FieldType, _FieldName}, {IsSimple, StrAcc}) ->
- case FieldType of
- "bool" ->
- TemStr =
- case IsSimple of
- true ->
- GetLeftBinStr1 = getIndexStr(pd_leftBin),
- UseLeftBinStr1 = useIndexStr(pd_leftBin),
- "LeftBin" ++ UseLeftBinStr1 ++ "/binary>> = LeftBin" ++ GetLeftBinStr1 ++ ",\n";
- _ ->
- ""
- end,
- UseBoolStr = useIndexStr(pd_bool),
- GetLeftBinStr2 = getIndexStr(pd_leftBin),
- UseLeftBinStr2 = useIndexStr(pd_leftBin),
- BoolStr = "\t<<Bool" ++ UseBoolStr ++ ":8/big-unsigned, LeftBin" ++ UseLeftBinStr2 ++ "/binary>> = LeftBin" ++ GetLeftBinStr2 ++ ",\n",
- UseVStr = useIndexStr(pd_v),
- VStr = "\tV" ++ UseVStr ++ " = Bool" ++ UseBoolStr ++ " =:= 1,\n",
- {false, StrAcc ++ TemStr ++ BoolStr ++ VStr};
- "int8" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":8/big-signed, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":8/big-signed, "
- end,
- {true, StrAcc ++ TemStr};
- "uint8" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":8/big-unsigned, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":8/big-unsigned, "
- end,
- {true, StrAcc ++ TemStr};
- "int16" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":16/big-signed, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":16/big-signed, "
- end,
- {true, StrAcc ++ TemStr};
- "uint16" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":16/big-unsigned, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":16/big-unsigned, "
- end,
- {true, StrAcc ++ TemStr};
- "int32" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":32/big-signed, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":32/big-signed, "
- end,
- {true, StrAcc ++ TemStr};
- "uint32" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":32/big-unsigned, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":32/big-unsigned, "
- end,
- {true, StrAcc ++ TemStr};
- "int64" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":64/big-signed, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":64/big-signed, "
- end,
- {true, StrAcc ++ TemStr};
- "uint64" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":64/big-unsigned, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":64/big-unsigned, "
- end,
- {true, StrAcc ++ TemStr};
- "float" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":32/big-float, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":32/big-float, "
- end,
- {true, StrAcc ++ TemStr};
- "double" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- "V" ++ UseVStr ++ ":64/big-float, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- "\t<<V" ++ UseVStr ++ ":64/big-float, "
- end,
- {true, StrAcc ++ TemStr};
- "string" ->
- TemStr =
- case IsSimple of
- true ->
- GetLeftBinStr1 = getIndexStr(pd_leftBin),
- UseLeftBinStr1 = useIndexStr(pd_leftBin),
- "LeftBin" ++ UseLeftBinStr1 ++ "/binary>> = LeftBin" ++ GetLeftBinStr1 ++ ",\n";
- _ ->
- ""
- end,
- UseLenStr = useIndexStr(pd_len),
- GetLeftBinStr2 = getIndexStr(pd_leftBin),
- UseLeftBinStr2 = useIndexStr(pd_leftBin),
- UseVStr = useIndexStr(pd_v),
- RefSizeStr =
- case isCalcRefSize() of
- false ->
- useIndexStr(pd_isCalcRefSize),
- "\tRefSize = binary:referenced_byte_size(LeftBin0),\n";
- _ ->
- ""
- end,
- StrStr = "\t<<Len" ++ UseLenStr ++ ":16/big-unsigned, TemStrV" ++ UseVStr ++ ":Len" ++ UseLenStr ++ "/binary, LeftBin" ++ UseLeftBinStr2 ++ "/binary>> = LeftBin" ++ GetLeftBinStr2 ++ ",\n",
- VStr = "\tcase Len" ++ UseLenStr ++ " < ?BinaryShareSize of\n\t\t" ++
- "true ->\n\t\t\tV" ++ UseVStr ++ " = TemStrV" ++ UseVStr ++ ";\n\t\t" ++
- "_ ->\n\t\t\tcase RefSize / Len" ++ UseLenStr ++ " > ?BinaryCopyRatio of\n\t\t\t\t" ++
- "true ->\n\t\t\t\t\tV" ++ UseVStr ++ " = binary:copy(TemStrV" ++ UseVStr ++ ");\n\t\t\t\t" ++
- "_ ->\n\t\t\t\t\tV" ++ UseVStr ++ " = TemStrV" ++ UseVStr ++ "\n\t\t\tend\n\tend,\n",
- {false, StrAcc ++ TemStr ++ RefSizeStr ++ StrStr ++ VStr};
- "integer" ->
- TemStr =
- case IsSimple of
- true ->
- UseVStr = useIndexStr(pd_v),
- UseIntBitsStr = useIndexStr(pd_intBits),
- "IntBits" ++ UseIntBitsStr ++ ":8, " ++ "V" ++ UseVStr ++ ":IntBits" ++ UseIntBitsStr ++ "/big-signed, ";
- _ ->
- UseVStr = useIndexStr(pd_v),
- UseIntBitsStr = useIndexStr(pd_intBits),
- "\t<<IntBits" ++ UseIntBitsStr ++ ":8, " ++ "V" ++ UseVStr ++ ":IntBits" ++ UseIntBitsStr ++ "/big-signed, "
- end,
- {true, StrAcc ++ TemStr};
- "number" ->
- TemStr =
- case IsSimple of
- true ->
- GetLeftBinStr1 = getIndexStr(pd_leftBin),
- UseLeftBinStr1 = useIndexStr(pd_leftBin),
- "LeftBin" ++ UseLeftBinStr1 ++ "/binary>> = LeftBin" ++ GetLeftBinStr1 ++ ",\n";
- _ ->
- ""
- end,
- UseNumBitsStr = useIndexStr(pd_numBits),
- GetLeftBinStr2 = getIndexStr(pd_leftBin),
- UseLeftBinStr2 = useIndexStr(pd_leftBin),
- NumStr = "\t<<NumBits" ++ UseNumBitsStr ++ ":8, LeftBin" ++ UseLeftBinStr2 ++ "/binary>> = LeftBin" ++ GetLeftBinStr2 ++ ",\n",
- UseVStr = useIndexStr(pd_v),
- UseLeftBinStr3 = useIndexStr(pd_leftBin),
- VStr =
- "\tcase NumBits" ++ UseNumBitsStr ++ " of\n\t\t33-> \n\t\t\t<<V" ++ UseVStr ++ ":32/big-float, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ UseLeftBinStr2 ++
- ";\n\t\t65 ->\n\t\t\t<<V" ++ UseVStr ++ ":64/big-float, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ UseLeftBinStr2 ++
- ";\n\t\t_ ->\n\t\t\t<<V" ++ UseVStr ++ ":NumBits" ++ UseNumBitsStr ++ "/big-signed, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ UseLeftBinStr2 ++ "\n\tend,\n",
- {false, StrAcc ++ TemStr ++ NumStr ++ VStr};
- "list[" ++ LeftStr ->
- [SubTypeStr | _] = re:split(LeftStr, "\\]", [{return, list}]),
- TemStr =
- case IsSimple of
- true ->
- GetLeftBinStr1 = getIndexStr(pd_leftBin),
- UseLeftBinStr1 = useIndexStr(pd_leftBin),
- "LeftBin" ++ UseLeftBinStr1 ++ "/binary>> = LeftBin" ++ GetLeftBinStr1 ++ ",\n";
- _ ->
- ""
- end,
-
- UseLenStr = useIndexStr(pd_len),
- GetLeftBinStr2 = getIndexStr(pd_leftBin),
- UseLeftBinStr2 = useIndexStr(pd_leftBin),
- UseVStr = useIndexStr(pd_v),
- UseListBinStr = useIndexStr(pd_listBin),
- GetLeftBinStr3 = getIndexStr(pd_leftBin),
- UseLeftBinStr3 = useIndexStr(pd_leftBin),
- LenStr = "\t<<Len" ++ UseLenStr ++ ":16/big-unsigned, LeftBin" ++ UseLeftBinStr2 ++ "/binary>> = LeftBin" ++ GetLeftBinStr2 ++ ",\n",
- DeListStr =
- case SubTypeStr of
- "bool" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:8, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV =:= 1 || <<TemV:8/big-unsigned>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "int8" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:8, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:8/big-signed>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "uint8" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:8, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:8/big-unsigned>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "int16" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:16, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:16/big-signed>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "uint16" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:16, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:16/big-unsigned>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "int32" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:32, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:32/big-signed>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "uint32" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:32, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:32/big-unsigned>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "int64" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:64, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:64/big-signed>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "uint64" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:64, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:64/big-unsigned>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "integer" ->
- "\t{V" ++ UseVStr ++ ", LeftBin" ++ UseLeftBinStr3 ++ "} = deIntegerList(Len" ++ UseLenStr ++ ", LeftBin" ++ GetLeftBinStr3 ++ ", []),\n";
- "number" ->
- "\t{V" ++ UseVStr ++ ", LeftBin" ++ UseLeftBinStr3 ++ "} = deNumberList(Len" ++ UseLenStr ++ ", LeftBin" ++ GetLeftBinStr3 ++ ", []),\n";
- "float" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:32, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:32/big-float>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "double" ->
- ListBinStr = "\t<<ListBin" ++ UseListBinStr ++ ":Len" ++ UseLenStr ++ "/big-binary-unit:64, LeftBin" ++ UseLeftBinStr3 ++ "/binary>> = LeftBin" ++ GetLeftBinStr3 ++ ",\n",
- VStr = "\tV" ++ UseVStr ++ " = [TemV || <<TemV:64/big-float>> <= ListBin" ++ UseListBinStr ++ "],\n",
- ListBinStr ++ VStr;
- "string" ->
- case isCalcRefSize() of
- true ->
- "\t{V" ++ UseVStr ++ ", LeftBin" ++ UseLeftBinStr3 ++ "} = deStringList(Len" ++ UseLenStr ++ ", LeftBin" ++ GetLeftBinStr3 ++ ", RefSize, []),\n";
- _ ->
- useIndexStr(pd_isCalcRefSize),
- RefSizeStr = "\tRefSize = binary:referenced_byte_size(LeftBin0),\n",
- VStr = "\t{V" ++ UseVStr ++ ", LeftBin" ++ UseLeftBinStr3 ++ "} = deStringList(Len" ++ UseLenStr ++ ", LeftBin" ++ GetLeftBinStr3 ++ ", RefSize, []),\n",
- RefSizeStr ++ VStr
- end;
- ListRecord ->
- case lists:keyfind(ListRecord, 1, SortedSProtoList) of
- {ListRecord, ListMsgId, _} = RecordInfo ->
- addSubRec(RecordInfo, IsForBin),
- "\t{V" ++ UseVStr ++ ", LeftBin" ++ UseLeftBinStr3 ++ "} = deRecordList(Len" ++ UseLenStr ++ ", " ++ integer_to_list(ListMsgId) ++ ", LeftBin" ++ GetLeftBinStr3 ++ ", []),\n";
- _ ->
- io:format("this an Record undefined :~p~n", [ListRecord]),
- throw(record_undefined)
- end
- end,
- {false, StrAcc ++ TemStr ++ LenStr ++ DeListStr};
- OtherRecord ->
- TemStr =
- case IsSimple of
- true ->
- GetLeftBinStr1 = getIndexStr(pd_leftBin),
- UseLeftBinStr1 = useIndexStr(pd_leftBin),
- "LeftBin" ++ UseLeftBinStr1 ++ "/binary>> = LeftBin" ++ GetLeftBinStr1 ++ ",\n";
- _ ->
- ""
- end,
- UseIsUndefStr = useIndexStr(pd_isUndef),
- GetLeftBinStr2 = getIndexStr(pd_leftBin),
- UseLeftBinStr2 = useIndexStr(pd_leftBin),
- IsStr = "\t<<IsUndef" ++ UseIsUndefStr ++ ":8/big-unsigned, LeftBin" ++ UseLeftBinStr2 ++ "/binary>> = LeftBin" ++ GetLeftBinStr2 ++ ",\n",
- UseVStr = useIndexStr(pd_v),
- UseLeftBinStr3 = useIndexStr(pd_leftBin),
- case lists:keyfind(OtherRecord, 1, SortedSProtoList) of
- {OtherRecord, OtherMsgId, _} = RecordInfo ->
- addSubRec(RecordInfo, IsForBin),
- VStr = "\tcase IsUndef" ++ UseIsUndefStr ++ " of\n\t\t0 ->\n\t\t\tV" ++ UseVStr ++ " = undefined,\n\t\t\tLeftBin" ++ UseLeftBinStr3 ++ " = LeftBin" ++ UseLeftBinStr2 ++
- " ;\n\t\t_ ->\n\t\t\t{V" ++ UseVStr ++ ", LeftBin" ++ UseLeftBinStr3 ++ "} = " ++ "decodeRec(" ++ integer_to_list(OtherMsgId) ++ ", LeftBin" ++ UseLeftBinStr2 ++ ")\n\tend,\n",
- {false, StrAcc ++ TemStr ++ IsStr ++ VStr};
- _ ->
- io:format("this an Record undefined :~p~n", [OtherRecord]),
- throw(record_undefined)
- end
- end
- end,
-
- {LIsSimple, BodyStr} = lists:foldl(FunBody, {false, ""}, FieldList),
- LBodyStr =
- case LIsSimple of
- true ->
- LGetLeftBinStr = getIndexStr(pd_leftBin),
- LUseLeftBinStr = useIndexStr(pd_leftBin),
- BodyStr ++ "LeftBin" ++ LUseLeftBinStr ++ "/binary>> = LeftBin" ++ LGetLeftBinStr ++ ",\n";
- _ ->
- BodyStr
- end,
-
- RetStr =
- case IsForBin of
- true ->
- case FieldLen > 0 of
- true ->
- FunRec =
- fun(N, Acc) ->
- ", V" ++ integer_to_list(N) ++ Acc
-
- end,
- RecStr = lists:foldr(FunRec, "", lists:seq(1, FieldLen)),
- "\t{" ++ MsgName ++ RecStr ++ "};\n";
- _ ->
- "\t{" + MsgName ++ "};\n"
- end;
- _ ->
- case FieldLen > 0 of
- true ->
- FunRec =
- fun(N, Acc) ->
- ", V" ++ integer_to_list(N) ++ Acc
-
- end,
- RecStr = lists:foldr(FunRec, "", lists:seq(1, FieldLen)),
- "\tMsgRec = {" ++ MsgName ++ RecStr ++ "},\n"
- "\t{MsgRec, LeftBin" ++ getIndexStr(pd_leftBin) ++ "};\n";
- _ ->
- "\t{{" + MsgName ++ "}, " ++ "<<>>};\n"
- end
- end,
- HeadStr ++ LBodyStr ++ RetStr.
-
- convertFile(File) ->
- protoParse:parseFile(File).
-
- convert([ProtoDir, HrlDir, ErlDir]) ->
- convertDir(atom_to_list(ProtoDir), atom_to_list(HrlDir), atom_to_list(ErlDir)).
-
- convertDir() ->
- convertDir("./", "./", "./").
- convertDir(ProtoDir) ->
- convertDir(ProtoDir, "./", "./").
- convertDir(ProtoDir, HrlDir, ErlDir) ->
- erlang:put(pd_errlist, []),
- FunRead =
- fun(File, ProAcc) ->
- case filename:extension(File) == ".mpdf" of
- true ->
- io:format("Convert proto msg file: ~s ~n", [File]),
- BaseName = filename:basename(File, ".mpdf"),
- [ModIndex | _ModName] = re:split(BaseName, "_"),
- Index = binary_to_integer(ModIndex),
- erlang:put(pd_messageid, Index * 1000 + 1),
- erlang:put(pd_errcodeid, Index * 1000 + 1),
- SProto = protoParse:parseFile(File),
- ErrCode = erlang:get(pd_errlist),
- erlang:erase(),
- erlang:put(pd_errlist, ErrCode),
- [SProto | ProAcc];
- _ ->
- ProAcc
- end
- end,
- %% 下面文件帅选并不能准确的帅选出文件名为.mpdf结尾的文件 在FunRead函数中纠正处理一下
- SProtoListOfList = filelib:fold_files(ProtoDir, "\\.mpdf$", true, FunRead, []),
- SProtoList = lists:append(SProtoListOfList),
- ErrCodeList = erlang:get(pd_errlist),
- initSubRec(),
-
- SortedSProtoList = lists:sort(fun({_Name1, MessageId1, _FieldList1}, {_Name2, MessageId2, _FieldList2}) ->
- MessageId1 > MessageId2 end, SProtoList),
-
- FunSpell =
- fun({MsgName, _MsgId, FieldList} = MsgInfo, {MsgHrlAcc, _MsgIdAcc, MsgEncodeAcc, MsgDecodeAcc}) ->
- %% gen hrl str
- Len = erlang:length(FieldList),
- {_, Len, LastFieldStr} = lists:foldr(fun genMsgHrl/2, {Len, Len, ""}, FieldList),
- HrlStr = "-record(" ++ MsgName ++ ", {\n\t" ++ LastFieldStr ++ "}).\n",
- %% gen getMsgId getMsgType str
- %% TypeStr = "getMsgType(" ++ integer_to_list(MsgId) ++ ")-> " ++ MsgName ++ ";\n",
- %% IdStr = "getMsgId(" ++ MsgName ++ ")-> " ++ integer_to_list(MsgId) ++ ";\n",
-
- %% gen encodeRec Str
- EncodeStr = genEncodeRec(MsgInfo, true),
-
- %% gen decodeBin str
- resetPd(),
- DecodeStr = genDecodeBin(MsgInfo, SortedSProtoList, true),
-
- {[HrlStr | MsgHrlAcc], ["Unuse"], [EncodeStr | MsgEncodeAcc], [DecodeStr | MsgDecodeAcc]}
- end,
- {MsgHrlStr, _MsgIdStr, MsgEncodeStr, MsgDecodeStr} = lists:foldl(FunSpell, {[], ["getMsgId(_) -> 0.\n\n"], ["encode(_) ->\n\t[].\n\n"], ["decodeBin(_, _) ->\n\t{{}, <<>>}.\n\n"]}, SortedSProtoList),
-
- SortedErrList = lists:sort(fun({_ErrName1, ErrCodeId1, _Desc1}, {_ErrName2, ErrCodeId2, _Desc2}) ->
- ErrCodeId1 > ErrCodeId2 end, ErrCodeList),
- ErrCodeStr = lists:foldl(fun genErrCodeHrl/2, [], SortedErrList) ++ "\n\n",
-
- %% gen decodeRec str
- SubRecList = getSubRec(),
- SortedSubRecList = lists:sort(fun({_Name1, MessageId1, _FieldList1}, {_Name2, MessageId2, _FieldList2}) ->
- MessageId1 > MessageId2 end, SubRecList),
-
- FunSubRec =
- fun(MsgInfo, {SubEncodeAcc, SubDecodeAcc}) ->
- EncodeStr = genEncodeRec(MsgInfo, false),
- resetPd(),
- DecodeStr = genDecodeBin(MsgInfo, SortedSProtoList, false),
- {[EncodeStr | SubEncodeAcc], [DecodeStr | SubDecodeAcc]}
- end,
- {MsgEncodeRecStr, MsgDecodeRecStr} = lists:foldl(FunSubRec, {["encodeRec(_) ->\n\t[].\n\n"], ["decodeRec(_, _) ->\n\t{{}, <<>>}.\n\n"]}, SortedSubRecList),
-
- ErlHeaderStr = protoErlHeader(),
- OutputStr = ErlHeaderStr ++ MsgEncodeRecStr ++ MsgEncodeStr ++ MsgDecodeRecStr ++ MsgDecodeStr,
- HrlFilename = do_write_hrl(HrlDir, protoMsg, protoHrlHeader() ++ ErrCodeStr ++ MsgHrlStr),
- ErlFilename = do_write_erl(ErlDir, protoMsg, OutputStr),
-
- io:format("protoConvert hrl dir : ~s ~n", [HrlDir]),
- io:format("protoConvert erl dir : ~s ~n", [ErlDir]),
- io:format("protoConvert to hrl file ~s succ.~n", [HrlFilename]),
- io:format("protoConvert to erl file ~s succ.~n", [ErlFilename]),
- ok.
-
- do_write_hrl(OutDir, Mod, Str) when is_list(OutDir) ->
- Filename = filename:join([OutDir, atom_to_list(Mod) ++ ".hrl"]),
- ok = file:write_file(Filename, Str),
- Filename.
-
- do_write_erl(OutDir, Mod, Str) when is_list(OutDir) ->
- Filename = filename:join([OutDir, atom_to_list(Mod) ++ ".erl"]),
- ok = file:write_file(Filename, Str),
- Filename.
-
|