erlang自定义二进制协议
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

772 line
36 KiB

4 年之前
4 年之前
4 年之前
  1. -module(gCsGen).
  2. -include("genDef.hrl").
  3. -export([
  4. genCs/4
  5. ]).
  6. protoHeader() ->
  7. <<"using System;
  8. using System.Collections;
  9. using System.Collections.Generic;
  10. using System.IO;
  11. namespace ProtoMsg
  12. {
  13. public static class Protocol
  14. {
  15. public enum BasicTypeEnum
  16. {
  17. Boolean = 0x01,
  18. Int8 = 0x02,
  19. UInt8 = 0x03,
  20. UInt16 = 0x04,
  21. Int16 = 0x05,
  22. Int32 = 0x06,
  23. UInt32 = 0x07,
  24. Int64 = 0x08,
  25. UInt64 = 0x09,
  26. Float = 0x10,
  27. Double = 0x11,
  28. String = 0x12,
  29. }
  30. public static BasicTypeEnum JudgeType<T>(T value)
  31. {
  32. return value switch
  33. {
  34. bool => BasicTypeEnum.Boolean,
  35. byte => BasicTypeEnum.Int8,
  36. sbyte => BasicTypeEnum.UInt8,
  37. ushort => BasicTypeEnum.UInt16,
  38. short => BasicTypeEnum.Int16,
  39. int => BasicTypeEnum.Int32,
  40. uint => BasicTypeEnum.UInt32,
  41. long => BasicTypeEnum.Int64,
  42. ulong => BasicTypeEnum.UInt64,
  43. float => BasicTypeEnum.Float,
  44. double => BasicTypeEnum.Double,
  45. string => BasicTypeEnum.String,
  46. _ => throw new InvalidOperationException($\"unexpect type: {value.GetType().FullName}\")
  47. };
  48. }
  49. public static void WriteValue<T>(this BinaryWriter binaryWriter, T value)
  50. {
  51. switch (value)
  52. {
  53. case bool boolValue:
  54. binaryWriter.Write(boolValue);
  55. break;
  56. case byte byteValue:
  57. binaryWriter.Write(byteValue);
  58. break;
  59. case sbyte sbyteValue:
  60. binaryWriter.Write(sbyteValue);
  61. break;
  62. case ushort ushortValue:
  63. binaryWriter.Write(ushortValue);
  64. break;
  65. case short shortValue:
  66. binaryWriter.Write(shortValue);
  67. break;
  68. case int intValue:
  69. binaryWriter.Write(intValue);
  70. break;
  71. case uint uintValue:
  72. binaryWriter.Write(uintValue);
  73. break;
  74. case long longValue:
  75. binaryWriter.Write(longValue);
  76. break;
  77. case ulong ulongValue:
  78. binaryWriter.Write(ulongValue);
  79. break;
  80. case float floatValue:
  81. binaryWriter.Write(floatValue);
  82. break;
  83. case double doubleValue:
  84. binaryWriter.Write(doubleValue);
  85. break;
  86. case string stringValue:
  87. binaryWriter.Write(stringValue);
  88. break;
  89. default:
  90. throw new InvalidOperationException($\"unexpect type: {value.GetType().FullName}\");
  91. }
  92. }
  93. public static void WriteList<T>(this BinaryWriter binaryWriter, IList<T> list)
  94. {
  95. var length = (ushort) (list?.Count ?? 0);
  96. binaryWriter.Write(length);
  97. if (list == null) return;
  98. for (var idx = 0; idx < length; idx++)
  99. {
  100. var value = list[idx];
  101. if (idx == 0)
  102. {
  103. var basicType = JudgeType(value);
  104. binaryWriter.Write((byte) basicType);
  105. }
  106. binaryWriter.WriteValue(value);
  107. }
  108. }
  109. public static void ReadList(this BinaryReader binaryReader, out IList list)
  110. {
  111. var length = binaryReader.ReadUInt16();
  112. if (length <= 0)
  113. {
  114. list = default;
  115. return;
  116. }
  117. list = default;
  118. var basicTypeEnum = (BasicTypeEnum) binaryReader.ReadByte();
  119. for (int idx = 0; idx < length; idx++)
  120. {
  121. switch (basicTypeEnum)
  122. {
  123. case BasicTypeEnum.Boolean:
  124. list ??= new List<bool>(length);
  125. var boolValue = binaryReader.ReadBoolean();
  126. list.Add(boolValue);
  127. break;
  128. case BasicTypeEnum.Int8:
  129. list ??= new List<sbyte>(length);
  130. var sbyteValue = binaryReader.ReadSByte();
  131. list.Add(sbyteValue);
  132. break;
  133. case BasicTypeEnum.UInt8:
  134. list ??= new List<byte>(length);
  135. var byteValue = binaryReader.ReadByte();
  136. list.Add(byteValue);
  137. break;
  138. case BasicTypeEnum.UInt16:
  139. list ??= new List<ushort>(length);
  140. var ushortValue = binaryReader.ReadUInt16();
  141. list.Add(ushortValue);
  142. break;
  143. case BasicTypeEnum.Int16:
  144. list ??= new List<short>(length);
  145. var shortValue = binaryReader.ReadInt16();
  146. list.Add(shortValue);
  147. break;
  148. case BasicTypeEnum.Int32:
  149. list ??= new List<int>(length);
  150. var intValue = binaryReader.ReadInt32();
  151. list.Add(intValue);
  152. break;
  153. case BasicTypeEnum.UInt32:
  154. list ??= new List<uint>(length);
  155. var uintValue = binaryReader.ReadUInt32();
  156. list.Add(uintValue);
  157. break;
  158. case BasicTypeEnum.Int64:
  159. list ??= new List<long>(length);
  160. var longValue = binaryReader.ReadInt64();
  161. list.Add(longValue);
  162. break;
  163. case BasicTypeEnum.UInt64:
  164. list ??= new List<ulong>(length);
  165. var ulongValue = binaryReader.ReadUInt64();
  166. list.Add(ulongValue);
  167. break;
  168. case BasicTypeEnum.Float:
  169. list ??= new List<float>(length);
  170. var singleValue = binaryReader.ReadSingle();
  171. list.Add(singleValue);
  172. break;
  173. case BasicTypeEnum.Double:
  174. list ??= new List<double>(length);
  175. var doubleValue = binaryReader.ReadDouble();
  176. list.Add(doubleValue);
  177. break;
  178. case BasicTypeEnum.String:
  179. list ??= new List<string>(length);
  180. var stringValue = binaryReader.ReadString();
  181. list.Add(stringValue);
  182. break;
  183. default:
  184. throw new ArgumentOutOfRangeException();
  185. }
  186. }
  187. }
  188. }">>.
  189. protoEnd() ->
  190. <<"}">>.
  191. genMsgHrl([], _Index, _Len, HrlBinStr) ->
  192. HrlBinStr;
  193. genMsgHrl([FieldInfo | FieldList], Index, Len, HrlBinStr) ->
  194. TemStr =
  195. case Index of
  196. Len ->
  197. <<"">>;
  198. _ ->
  199. <<", ">>
  200. end,
  201. RecStr = <<TemStr/binary, (gErlField:builtRecStr(FieldInfo))/binary, (case Index == 1 of true -> <<"">>; _ -> <<"\t">> end)/binary>>,
  202. genMsgHrl(FieldList, Index - 1, Len, <<HrlBinStr/binary, RecStr/binary>>).
  203. spellHead([], _Index, HeadBinStr) ->
  204. HeadBinStr;
  205. spellHead([_FieldInfo | FieldList], Index, HeadBinStr) ->
  206. spellHead(FieldList, Index + 1, <<HeadBinStr/binary, ", V", (integer_to_binary(Index))/binary>>).
  207. spellBody([], _Index, BodyBinStr) ->
  208. BodyBinStr;
  209. spellBody([{FieldType, _FieldName}], Index, BodyBinStr) ->
  210. TemV = <<"V", (integer_to_binary(Index))/binary>>,
  211. <<BodyBinStr/binary, (gErlField:builtPackStr(FieldType))/binary, TemV/binary, ")">>;
  212. spellBody([{FieldType, _FieldName} | FieldList], Index, BodyBinStr) ->
  213. TemV = <<"V", (integer_to_binary(Index))/binary>>,
  214. NewBodyBinStr = <<BodyBinStr/binary, (gErlField:builtPackStr(FieldType))/binary, TemV/binary, "), ">>,
  215. spellBody(FieldList, Index + 1, NewBodyBinStr).
  216. spellErrCodeHrl([], ErrBinStr) ->
  217. ErrBinStr;
  218. spellErrCodeHrl([{ErrName, ErrCodeId, ComDesc} | SortedErrList], ErrBinStr) ->
  219. ErrStr = <<"-define(", ErrName/binary, ", ", (integer_to_binary(ErrCodeId))/binary, ").\t\t%% ", ComDesc/binary, "\n">>,
  220. spellErrCodeHrl(SortedErrList, <<ErrBinStr/binary, ErrStr/binary>>).
  221. genEncodeRec({MsgName, MsgId, FieldList}, IsForBin) ->
  222. FieldLen = length(FieldList),
  223. TemStr = spellHead(FieldList, 1, <<"">>),
  224. HeadStr =
  225. case IsForBin of
  226. true ->
  227. <<"encodeIol(", MsgName/binary, ", {_", TemStr/binary, "}) ->\n\t">>;
  228. _ ->
  229. <<"subEncode(", MsgName/binary, ", {_", TemStr/binary, "}) ->\n\t">>
  230. end,
  231. BodyStr = spellBody(FieldList, 1, <<"">>),
  232. case IsForBin of
  233. true ->
  234. case FieldLen > 0 of
  235. true ->
  236. <<HeadStr/binary, "[<<", (integer_to_binary(MsgId))/binary, ":16/big-unsigned>>, ", BodyStr/binary, "];\n">>;
  237. _ ->
  238. <<HeadStr/binary, "[<<", (integer_to_binary(MsgId))/binary, ":16/big-unsigned>>];\n">>
  239. end;
  240. _ ->
  241. case FieldLen > 0 of
  242. true ->
  243. <<HeadStr/binary, "[", BodyStr/binary, "];\n">>;
  244. _ ->
  245. <<HeadStr/binary, "[];\n">>
  246. end
  247. end.
  248. resetPd() ->
  249. erlang:put(pd_v, 0),
  250. erlang:put(pd_len, 0),
  251. erlang:put(pd_bool, 0),
  252. erlang:put(pd_leftBin, 0),
  253. erlang:put(pd_intBits, 0),
  254. erlang:put(pd_numBits, 0),
  255. erlang:put(pd_listBin, 0),
  256. erlang:put(pd_isUndef, 0),
  257. erlang:put(pd_isCalcRefSize, 0).
  258. getIndexStr(Type) ->
  259. Index = erlang:get(Type),
  260. integer_to_binary(Index).
  261. useIndexStr(Type) ->
  262. Index = erlang:get(Type) + 1,
  263. erlang:put(Type, Index),
  264. integer_to_binary(Index).
  265. isCalcRefSize() ->
  266. erlang:get(pd_isCalcRefSize) > 0.
  267. initSubRec() ->
  268. erlang:put(pd_subRec, []).
  269. getSubRec() ->
  270. erlang:get(pd_subRec).
  271. initSubSubRec() ->
  272. erlang:put(pd_subSubRec, []).
  273. getSubSubRec() ->
  274. erlang:get(pd_subSubRec).
  275. addSubRec({MsgName, _MsgId, _FieldList} = Info, IsForBin) when IsForBin ->
  276. OldList = erlang:get(pd_subRec),
  277. case lists:keyfind(MsgName, 1, OldList) of
  278. false ->
  279. erlang:put(pd_subRec, [Info | OldList]);
  280. _ ->
  281. ignore
  282. end;
  283. addSubRec({MsgName, _MsgId, _FieldList} = Info, _IsForBin) ->
  284. OldAllList = erlang:get(pd_subRec),
  285. case lists:keyfind(MsgName, 1, OldAllList) of
  286. false ->
  287. erlang:put(pd_subRec, [Info | OldAllList]),
  288. OldSubList = erlang:get(pd_subSubRec),
  289. case lists:keyfind(MsgName, 1, OldSubList) of
  290. false ->
  291. erlang:put(pd_subSubRec, [Info | OldSubList]);
  292. _ ->
  293. ignore
  294. end;
  295. _ ->
  296. ignore
  297. end.
  298. genDecodeBin({MsgName, MsgId, FieldList}, SortedSProtoList, IsForBin) ->
  299. FieldLen = length(FieldList),
  300. case IsForBin of
  301. true ->
  302. HeadStr = <<"decodeBin(", (integer_to_binary(MsgId))/binary, ", LeftBin", (getIndexStr(pd_leftBin))/binary, ") ->\n">>;
  303. _ ->
  304. HeadStr = <<"decodeRec(", (integer_to_binary(MsgId))/binary, ", LeftBin", (getIndexStr(pd_leftBin))/binary, ") ->\n">>
  305. end,
  306. FunBody =
  307. fun({FieldType, _FieldName}, {IsSimple, StrAcc}) ->
  308. case FieldType of
  309. <<"bool">> ->
  310. TemStr =
  311. case IsSimple of
  312. true ->
  313. GetLeftBinStr1 = getIndexStr(pd_leftBin),
  314. UseLeftBinStr1 = useIndexStr(pd_leftBin),
  315. <<"LeftBin", UseLeftBinStr1/binary, "/binary>> = LeftBin", GetLeftBinStr1/binary, ",\n">>;
  316. _ ->
  317. <<"">>
  318. end,
  319. UseBoolStr = useIndexStr(pd_bool),
  320. GetLeftBinStr2 = getIndexStr(pd_leftBin),
  321. UseLeftBinStr2 = useIndexStr(pd_leftBin),
  322. BoolStr = <<"\t<<Bool", UseBoolStr/binary, ":8/big-unsigned, LeftBin", UseLeftBinStr2/binary, "/binary>> = LeftBin", GetLeftBinStr2/binary, ",\n">>,
  323. UseVStr = useIndexStr(pd_v),
  324. VStr = <<"\tV", UseVStr/binary, " = Bool", UseBoolStr/binary, " =:= 1,\n">>,
  325. {false, <<StrAcc/binary, TemStr/binary, BoolStr/binary, VStr/binary>>};
  326. <<"int8">> ->
  327. TemStr =
  328. case IsSimple of
  329. true ->
  330. UseVStr = useIndexStr(pd_v),
  331. <<"V", UseVStr/binary, ":8/big-signed, ">>;
  332. _ ->
  333. UseVStr = useIndexStr(pd_v),
  334. <<"\t<<V", UseVStr/binary, ":8/big-signed, ">>
  335. end,
  336. {true, <<StrAcc/binary, TemStr/binary>>};
  337. <<"uint8">> ->
  338. TemStr =
  339. case IsSimple of
  340. true ->
  341. UseVStr = useIndexStr(pd_v),
  342. <<"V", UseVStr/binary, ":8/big-unsigned, ">>;
  343. _ ->
  344. UseVStr = useIndexStr(pd_v),
  345. <<"\t<<V", UseVStr/binary, ":8/big-unsigned, ">>
  346. end,
  347. {true, <<StrAcc/binary, TemStr/binary>>};
  348. <<"int16">> ->
  349. TemStr =
  350. case IsSimple of
  351. true ->
  352. UseVStr = useIndexStr(pd_v),
  353. <<"V", UseVStr/binary, ":16/big-signed, ">>;
  354. _ ->
  355. UseVStr = useIndexStr(pd_v),
  356. <<"\t<<V", UseVStr/binary, ":16/big-signed, ">>
  357. end,
  358. {true, <<StrAcc/binary, TemStr/binary>>};
  359. <<"uint16">> ->
  360. TemStr =
  361. case IsSimple of
  362. true ->
  363. UseVStr = useIndexStr(pd_v),
  364. <<"V", UseVStr/binary, ":16/big-unsigned, ">>;
  365. _ ->
  366. UseVStr = useIndexStr(pd_v),
  367. <<"\t<<V", UseVStr/binary, ":16/big-unsigned, ">>
  368. end,
  369. {true, <<StrAcc/binary, TemStr/binary>>};
  370. <<"int32">> ->
  371. TemStr =
  372. case IsSimple of
  373. true ->
  374. UseVStr = useIndexStr(pd_v),
  375. <<"V", UseVStr/binary, ":32/big-signed, ">>;
  376. _ ->
  377. UseVStr = useIndexStr(pd_v),
  378. <<"\t<<V", UseVStr/binary, ":32/big-signed, ">>
  379. end,
  380. {true, <<StrAcc/binary, TemStr/binary>>};
  381. <<"uint32">> ->
  382. TemStr =
  383. case IsSimple of
  384. true ->
  385. UseVStr = useIndexStr(pd_v),
  386. <<"V", UseVStr/binary, ":32/big-unsigned, ">>;
  387. _ ->
  388. UseVStr = useIndexStr(pd_v),
  389. <<"\t<<V", UseVStr/binary, ":32/big-unsigned, ">>
  390. end,
  391. {true, <<StrAcc/binary, TemStr/binary>>};
  392. <<"int64">> ->
  393. TemStr =
  394. case IsSimple of
  395. true ->
  396. UseVStr = useIndexStr(pd_v),
  397. <<"V", UseVStr/binary, ":64/big-signed, ">>;
  398. _ ->
  399. UseVStr = useIndexStr(pd_v),
  400. <<"\t<<V", UseVStr/binary, ":64/big-signed, ">>
  401. end,
  402. {true, <<StrAcc/binary, TemStr/binary>>};
  403. <<"uint64">> ->
  404. TemStr =
  405. case IsSimple of
  406. true ->
  407. UseVStr = useIndexStr(pd_v),
  408. <<"V", UseVStr/binary, ":64/big-unsigned, ">>;
  409. _ ->
  410. UseVStr = useIndexStr(pd_v),
  411. <<"\t<<V", UseVStr/binary, ":64/big-unsigned, ">>
  412. end,
  413. {true, <<StrAcc/binary, TemStr/binary>>};
  414. <<"float">> ->
  415. TemStr =
  416. case IsSimple of
  417. true ->
  418. UseVStr = useIndexStr(pd_v),
  419. <<"V", UseVStr/binary, ":32/big-float, ">>;
  420. _ ->
  421. UseVStr = useIndexStr(pd_v),
  422. <<"\t<<V", UseVStr/binary, ":32/big-float, ">>
  423. end,
  424. {true, <<StrAcc/binary, TemStr/binary>>};
  425. <<"double">> ->
  426. TemStr =
  427. case IsSimple of
  428. true ->
  429. UseVStr = useIndexStr(pd_v),
  430. <<"V", UseVStr/binary, ":64/big-float, ">>;
  431. _ ->
  432. UseVStr = useIndexStr(pd_v),
  433. <<"\t<<V", UseVStr/binary, ":64/big-float, ">>
  434. end,
  435. {true, <<StrAcc/binary, TemStr/binary>>};
  436. <<"string">> ->
  437. TemStr =
  438. case IsSimple of
  439. true ->
  440. GetLeftBinStr1 = getIndexStr(pd_leftBin),
  441. UseLeftBinStr1 = useIndexStr(pd_leftBin),
  442. <<"LeftBin", UseLeftBinStr1/binary, "/binary>> = LeftBin", GetLeftBinStr1/binary, ",\n">>;
  443. _ ->
  444. <<"">>
  445. end,
  446. UseLenStr = useIndexStr(pd_len),
  447. GetLeftBinStr2 = getIndexStr(pd_leftBin),
  448. UseLeftBinStr2 = useIndexStr(pd_leftBin),
  449. UseVStr = useIndexStr(pd_v),
  450. RefSizeStr =
  451. case isCalcRefSize() of
  452. false ->
  453. useIndexStr(pd_isCalcRefSize),
  454. <<"\tRefSize = binary:referenced_byte_size(LeftBin0),\n">>;
  455. _ ->
  456. <<"">>
  457. end,
  458. StrStr = <<"\t<<Len", UseLenStr/binary, ":16/big-unsigned, TemStrV", UseVStr/binary, ":Len", UseLenStr/binary, "/binary, LeftBin", UseLeftBinStr2/binary, "/binary>> = LeftBin", GetLeftBinStr2/binary, ",\n">>,
  459. VStr = <<"\tcase Len", UseLenStr/binary, " < ?BinaryShareSize of\n\t\t",
  460. "true ->\n\t\t\tV", UseVStr/binary, " = TemStrV", UseVStr/binary, ";\n\t\t",
  461. "_ ->\n\t\t\tcase RefSize / Len", UseLenStr/binary, " > ?BinaryCopyRatio of\n\t\t\t\t",
  462. "true ->\n\t\t\t\t\tV", UseVStr/binary, " = binary:copy(TemStrV", UseVStr/binary, ");\n\t\t\t\t",
  463. "_ ->\n\t\t\t\t\tV", UseVStr/binary, " = TemStrV", UseVStr/binary, "\n\t\t\tend\n\tend,\n">>,
  464. {false, <<StrAcc/binary, TemStr/binary, RefSizeStr/binary, StrStr/binary, VStr/binary>>};
  465. <<"integer">> ->
  466. TemStr =
  467. case IsSimple of
  468. true ->
  469. UseVStr = useIndexStr(pd_v),
  470. UseIntBitsStr = useIndexStr(pd_intBits),
  471. <<"IntBits", UseIntBitsStr/binary, ":8, V", UseVStr/binary, ":IntBits", UseIntBitsStr/binary, "/big-signed, ">>;
  472. _ ->
  473. UseVStr = useIndexStr(pd_v),
  474. UseIntBitsStr = useIndexStr(pd_intBits),
  475. <<"\t<<IntBits", UseIntBitsStr/binary, ":8, V", UseVStr/binary, ":IntBits", UseIntBitsStr/binary, "/big-signed, ">>
  476. end,
  477. {true, <<StrAcc/binary, TemStr/binary>>};
  478. <<"number">> ->
  479. TemStr =
  480. case IsSimple of
  481. true ->
  482. GetLeftBinStr1 = getIndexStr(pd_leftBin),
  483. UseLeftBinStr1 = useIndexStr(pd_leftBin),
  484. <<"LeftBin", UseLeftBinStr1/binary, "/binary>> = LeftBin", GetLeftBinStr1/binary, ",\n">>;
  485. _ ->
  486. <<"">>
  487. end,
  488. UseNumBitsStr = useIndexStr(pd_numBits),
  489. GetLeftBinStr2 = getIndexStr(pd_leftBin),
  490. UseLeftBinStr2 = useIndexStr(pd_leftBin),
  491. NumStr = <<"\t<<NumBits", UseNumBitsStr/binary, ":8, LeftBin", UseLeftBinStr2/binary, "/binary>> = LeftBin", GetLeftBinStr2/binary, ",\n">>,
  492. UseVStr = useIndexStr(pd_v),
  493. UseLeftBinStr3 = useIndexStr(pd_leftBin),
  494. VStr =
  495. <<"\tcase NumBits", UseNumBitsStr/binary, " of\n\t\t33-> \n\t\t\t<<V", UseVStr/binary, ":32/big-float, LeftBin", UseLeftBinStr3/binary,
  496. "/binary>> = LeftBin", UseLeftBinStr2/binary, ";\n\t\t65 ->\n\t\t\t<<V", UseVStr/binary, ":64/big-float, LeftBin", UseLeftBinStr3/binary,
  497. "/binary>> = LeftBin", UseLeftBinStr2/binary, ";\n\t\t_ ->\n\t\t\t<<V", UseVStr/binary, ":NumBits", UseNumBitsStr/binary, "/big-signed, LeftBin", UseLeftBinStr3/binary,
  498. "/binary>> = LeftBin", UseLeftBinStr2/binary, "\n\tend,\n">>,
  499. {false, <<StrAcc/binary, TemStr/binary, NumStr/binary, VStr/binary>>};
  500. <<"list[", LeftStr/binary>> ->
  501. [SubTypeStr | _] = re:split(LeftStr, <<"\\]">>, [{return, binary}]),
  502. TemStr =
  503. case IsSimple of
  504. true ->
  505. GetLeftBinStr1 = getIndexStr(pd_leftBin),
  506. UseLeftBinStr1 = useIndexStr(pd_leftBin),
  507. <<"LeftBin", UseLeftBinStr1/binary, "/binary>> = LeftBin", GetLeftBinStr1/binary, ",\n">>;
  508. _ ->
  509. <<"">>
  510. end,
  511. UseLenStr = useIndexStr(pd_len),
  512. GetLeftBinStr2 = getIndexStr(pd_leftBin),
  513. UseLeftBinStr2 = useIndexStr(pd_leftBin),
  514. UseVStr = useIndexStr(pd_v),
  515. UseListBinStr = useIndexStr(pd_listBin),
  516. GetLeftBinStr3 = getIndexStr(pd_leftBin),
  517. UseLeftBinStr3 = useIndexStr(pd_leftBin),
  518. LenStr = <<"\t<<Len", UseLenStr/binary, ":16/big-unsigned, LeftBin", UseLeftBinStr2/binary, "/binary>> = LeftBin", GetLeftBinStr2/binary, ",\n">>,
  519. DeListStr =
  520. case SubTypeStr of
  521. <<"bool">> ->
  522. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:8, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  523. VStr = <<"\tV", UseVStr/binary, " = [TemV =:= 1 || <<TemV:8/big-unsigned>> <= ListBin", UseListBinStr/binary, "],\n">>,
  524. <<ListBinStr/binary, VStr/binary>>;
  525. <<"int8">> ->
  526. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:8, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  527. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:8/big-signed>> <= ListBin", UseListBinStr/binary, "],\n">>,
  528. <<ListBinStr/binary, VStr/binary>>;
  529. <<"uint8">> ->
  530. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:8, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  531. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:8/big-unsigned>> <= ListBin", UseListBinStr/binary, "],\n">>,
  532. <<ListBinStr/binary, VStr/binary>>;
  533. <<"int16">> ->
  534. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:16, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  535. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:16/big-signed>> <= ListBin", UseListBinStr/binary, "],\n">>,
  536. <<ListBinStr/binary, VStr/binary>>;
  537. <<"uint16">> ->
  538. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:16, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  539. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:16/big-unsigned>> <= ListBin", UseListBinStr/binary, "],\n">>,
  540. <<ListBinStr/binary, VStr/binary>>;
  541. <<"int32">> ->
  542. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:32, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  543. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:32/big-signed>> <= ListBin", UseListBinStr/binary, "],\n">>,
  544. <<ListBinStr/binary, VStr/binary>>;
  545. <<"uint32">> ->
  546. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:32, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  547. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:32/big-unsigned>> <= ListBin", UseListBinStr/binary, "],\n">>,
  548. <<ListBinStr/binary, VStr/binary>>;
  549. <<"int64">> ->
  550. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:64, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  551. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:64/big-signed>> <= ListBin", UseListBinStr/binary, "],\n">>,
  552. <<ListBinStr/binary, VStr/binary>>;
  553. <<"uint64">> ->
  554. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:64, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  555. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:64/big-unsigned>> <= ListBin", UseListBinStr/binary, "],\n">>,
  556. <<ListBinStr/binary, VStr/binary>>;
  557. <<"integer">> ->
  558. <<"\t{V", UseVStr/binary, ", LeftBin", UseLeftBinStr3/binary, "} = deIntegerList(Len", UseLenStr/binary, ", LeftBin", GetLeftBinStr3/binary, ", []),\n">>;
  559. <<"number">> ->
  560. <<"\t{V", UseVStr/binary, ", LeftBin", UseLeftBinStr3/binary, "} = deNumberList(Len", UseLenStr/binary, ", LeftBin", GetLeftBinStr3/binary, ", []),\n">>;
  561. <<"float">> ->
  562. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:32, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  563. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:32/big-float>> <= ListBin", UseListBinStr/binary, "],\n">>,
  564. <<ListBinStr/binary, VStr/binary>>;
  565. <<"double">> ->
  566. ListBinStr = <<"\t<<ListBin", UseListBinStr/binary, ":Len", UseLenStr/binary, "/big-binary-unit:64, LeftBin", UseLeftBinStr3/binary, "/binary>> = LeftBin", GetLeftBinStr3/binary, ",\n">>,
  567. VStr = <<"\tV", UseVStr/binary, " = [TemV || <<TemV:64/big-float>> <= ListBin", UseListBinStr/binary, "],\n">>,
  568. <<ListBinStr/binary, VStr/binary>>;
  569. <<"string">> ->
  570. case isCalcRefSize() of
  571. true ->
  572. <<"\t{V", UseVStr/binary, ", LeftBin", UseLeftBinStr3/binary, "} = deStringList(Len", UseLenStr/binary, ", LeftBin", GetLeftBinStr3/binary, ", RefSize, []),\n">>;
  573. _ ->
  574. useIndexStr(pd_isCalcRefSize),
  575. RefSizeStr = <<"\tRefSize = binary:referenced_byte_size(LeftBin0),\n">>,
  576. VStr = <<"\t{V", UseVStr/binary, ", LeftBin", UseLeftBinStr3/binary, "} = deStringList(Len", UseLenStr/binary, ", LeftBin", GetLeftBinStr3/binary, ", RefSize, []),\n">>,
  577. <<RefSizeStr/binary, VStr/binary>>
  578. end;
  579. ListRecord ->
  580. case lists:keyfind(ListRecord, 1, SortedSProtoList) of
  581. {ListRecord, ListMsgId, _} = RecordInfo ->
  582. addSubRec(RecordInfo, IsForBin),
  583. <<"\t{V", UseVStr/binary, ", LeftBin", UseLeftBinStr3/binary, "} = deRecordList(Len", UseLenStr/binary, ", ", (integer_to_binary(ListMsgId))/binary, ", LeftBin", GetLeftBinStr3/binary, ", []),\n">>;
  584. _ ->
  585. io:format("this an Record undefined :~p~n", [ListRecord]),
  586. throw(record_undefined)
  587. end
  588. end,
  589. {false, <<StrAcc/binary, TemStr/binary, LenStr/binary, DeListStr/binary>>};
  590. OtherRecord ->
  591. TemStr =
  592. case IsSimple of
  593. true ->
  594. GetLeftBinStr1 = getIndexStr(pd_leftBin),
  595. UseLeftBinStr1 = useIndexStr(pd_leftBin),
  596. <<"LeftBin", UseLeftBinStr1/binary, "/binary>> = LeftBin", GetLeftBinStr1/binary, ",\n">>;
  597. _ ->
  598. <<"">>
  599. end,
  600. UseIsUndefStr = useIndexStr(pd_isUndef),
  601. GetLeftBinStr2 = getIndexStr(pd_leftBin),
  602. UseLeftBinStr2 = useIndexStr(pd_leftBin),
  603. IsStr = <<"\t<<IsUndef", UseIsUndefStr/binary, ":8/big-unsigned, LeftBin", UseLeftBinStr2/binary, "/binary>> = LeftBin", GetLeftBinStr2/binary, ",\n">>,
  604. UseVStr = useIndexStr(pd_v),
  605. UseLeftBinStr3 = useIndexStr(pd_leftBin),
  606. case lists:keyfind(OtherRecord, 1, SortedSProtoList) of
  607. {OtherRecord, OtherMsgId, _} = RecordInfo ->
  608. addSubRec(RecordInfo, IsForBin),
  609. VStr = <<"\tcase IsUndef", UseIsUndefStr/binary, " of\n\t\t0 ->\n\t\t\tV", UseVStr/binary, " = undefined,\n\t\t\tLeftBin", UseLeftBinStr3/binary, " = LeftBin", UseLeftBinStr2/binary,
  610. " ;\n\t\t_ ->\n\t\t\t{V", UseVStr/binary, ", LeftBin", UseLeftBinStr3/binary, "} = ", "decodeRec(", (integer_to_binary(OtherMsgId))/binary, ", LeftBin", UseLeftBinStr2/binary, ")\n\tend,\n">>,
  611. {false, <<StrAcc/binary, TemStr/binary, IsStr/binary, VStr/binary>>};
  612. _ ->
  613. io:format("this an Record undefined :~p~n", [OtherRecord]),
  614. throw(record_undefined)
  615. end
  616. end
  617. end,
  618. {LIsSimple, BodyStr} = lists:foldl(FunBody, {false, <<"">>}, FieldList),
  619. LBodyStr =
  620. case LIsSimple of
  621. true ->
  622. LGetLeftBinStr = getIndexStr(pd_leftBin),
  623. LUseLeftBinStr = useIndexStr(pd_leftBin),
  624. <<BodyStr/binary, "LeftBin", LUseLeftBinStr/binary, "/binary>> = LeftBin", LGetLeftBinStr/binary, ",\n">>;
  625. _ ->
  626. BodyStr
  627. end,
  628. RetStr =
  629. case IsForBin of
  630. true ->
  631. MsgIndex = MsgId div ?MsgIdSegSize,
  632. Handler = erlang:get(pd_handler),
  633. {MsgIndex, ModName} = lists:keyfind(MsgIndex, 1, Handler),
  634. HandleName = <<ModName/binary, "Her">>,
  635. case FieldLen > 0 of
  636. true ->
  637. FunRec =
  638. fun(N, Acc) ->
  639. <<Acc/binary, ", V", (integer_to_binary(N))/binary>>
  640. end,
  641. RecStr = lists:foldl(FunRec, <<"">>, lists:seq(1, FieldLen)),
  642. <<"\t{", HandleName/binary, ", ", MsgName/binary, ", {", MsgName/binary, RecStr/binary, "}};\n">>;
  643. _ ->
  644. <<"\t{", HandleName/binary, ", ", MsgName/binary, ", {", MsgName/binary, "}};\n">>
  645. end;
  646. _ ->
  647. case FieldLen > 0 of
  648. true ->
  649. FunRec =
  650. fun(N, Acc) ->
  651. <<Acc/binary, ", V", (integer_to_binary(N))/binary>>
  652. end,
  653. RecStr = lists:foldl(FunRec, <<"">>, lists:seq(1, FieldLen)),
  654. <<"\tMsgRec = {", MsgName/binary, RecStr/binary, "},\n\t{MsgRec, LeftBin", (getIndexStr(pd_leftBin))/binary, "};\n">>;
  655. _ ->
  656. <<"\t{{", MsgName/binary, "}, ", "<<>>};\n">>
  657. end
  658. end,
  659. <<HeadStr/binary, LBodyStr/binary, RetStr/binary>>.
  660. genCs(SortedSProtoList, SortedErrList, HrlDir, ErlDir) ->
  661. initSubRec(),
  662. FunSpell =
  663. fun({MsgName, MsgId, FieldList} = MsgInfo, {MsgHrlAcc, MsgEncodeAcc, MsgDecodeAcc, MsgIdAcc, MsgNameAcc}) ->
  664. %% gen hrl str
  665. Len = erlang:length(FieldList),
  666. LastFieldStr = genMsgHrl(FieldList, Len, Len, <<"">>),
  667. HrlStr = <<"-record(", MsgName/binary, ", {\n\t", LastFieldStr/binary, "}).\n">>,
  668. %% gen getMsgId getMsgType str
  669. IdStr = <<"getMsgId(", MsgName/binary, ")-> ", (integer_to_binary(MsgId))/binary, ";\n">>,
  670. NameStr = <<"getMsgName(", (integer_to_binary(MsgId))/binary, ")-> ", MsgName/binary, ";\n">>,
  671. %% gen encodeRec Str
  672. EncodeStr = genEncodeRec(MsgInfo, true),
  673. %% gen decodeBin str
  674. resetPd(),
  675. DecodeStr = genDecodeBin(MsgInfo, SortedSProtoList, true),
  676. {<<MsgHrlAcc/binary, HrlStr/binary>>, <<MsgEncodeAcc/binary, EncodeStr/binary>>, <<MsgDecodeAcc/binary, DecodeStr/binary>>, <<MsgIdAcc/binary, IdStr/binary>>, <<MsgNameAcc/binary, NameStr/binary>>}
  677. end,
  678. {MsgHrlStr, TMsgEncodeStr, TMsgDecodeStr, _TMsgIdStr, _TMsgNameStr} = lists:foldl(FunSpell, {<<>>, <<>>, <<>>, <<>>, <<>>}, SortedSProtoList),
  679. MsgEncodeStr = <<TMsgEncodeStr/binary, "encodeIol(_, _) ->\n\t[].\n\n">>,
  680. MsgDecodeStr = <<TMsgDecodeStr/binary, "decodeBin(_, _) ->\n\t{undefinedHer, undefined, {}}.\n\n">>,
  681. _MsgIdStr = <<_TMsgIdStr/binary, "getMsgId(_) -> 0.\n\n">>,
  682. _MsgNameStr = <<_TMsgNameStr/binary, "getMsgName(_) -> undefiend.\n\n">>,
  683. ErrCodeStr = spellErrCodeHrl(SortedErrList, <<>>),
  684. %% gen decodeRec str
  685. SubRecList = getSubRec(),
  686. initSubSubRec(),
  687. SortedSubRecList = lists:sort(fun({_Name1, MessageId1, _FieldList1}, {_Name2, MessageId2, _FieldList2}) -> MessageId1 < MessageId2 end, SubRecList),
  688. {MsgEncodeRecStr, MsgDecodeRecStr} = dealSubRec(SortedSubRecList, SortedSProtoList, <<"">>, <<"">>),
  689. ErlHeaderStr = protoErlHeader(),
  690. HrlHeaderStr = protoHrlHeader(),
  691. OutputErlStr = <<ErlHeaderStr/binary, MsgEncodeRecStr/binary, MsgEncodeStr/binary, MsgDecodeRecStr/binary, MsgDecodeStr/binary>>,
  692. OutputHrlStr = <<HrlHeaderStr/binary, ErrCodeStr/binary, "\n\n", MsgHrlStr/binary>>,
  693. HrlFilename = do_write_hrl(HrlDir, protoMsg, OutputHrlStr),
  694. ErlFilename = do_write_erl(ErlDir, protoMsg, OutputErlStr),
  695. io:format("protoConvert hrl dir : ~s ~n", [HrlDir]),
  696. io:format("protoConvert erl dir : ~s ~n", [ErlDir]),
  697. io:format("protoConvert to hrl file ~s succ.~n", [HrlFilename]),
  698. io:format("protoConvert to erl file ~s succ.~n", [ErlFilename]),
  699. ok.
  700. dealSubRec([], SortedSProtoList, SubEncodeAcc, SubDecodeAcc) ->
  701. case getSubSubRec() of
  702. [] ->
  703. {<<SubEncodeAcc/binary, "subEncode(_, _) ->\n\t[].\n\n">>, <<SubDecodeAcc/binary, "decodeRec(_, _) ->\n\t{{}, <<>>}.\n\n">>};
  704. NewAddList ->
  705. initSubSubRec(),
  706. SortedSubRecList = lists:sort(fun({_Name1, MessageId1, _FieldList1}, {_Name2, MessageId2, _FieldList2}) -> MessageId1 < MessageId2 end, NewAddList),
  707. dealSubRec(SortedSubRecList, SortedSProtoList, SubEncodeAcc, SubDecodeAcc)
  708. end;
  709. dealSubRec([MsgInfo | SubRecList], SortedSProtoList, SubEncodeAcc, SubDecodeAcc) ->
  710. EncodeStr = genEncodeRec(MsgInfo, false),
  711. resetPd(),
  712. DecodeStr = genDecodeBin(MsgInfo, SortedSProtoList, false),
  713. dealSubRec(SubRecList, SortedSProtoList, <<SubEncodeAcc/binary, EncodeStr/binary>>, <<SubDecodeAcc/binary, DecodeStr/binary>>).
  714. do_write_hrl(OutDir, Mod, BinStr) ->
  715. Filename = filename:join([OutDir, atom_to_list(Mod) ++ ".hrl"]),
  716. ok = file:write_file(Filename, BinStr),
  717. Filename.
  718. do_write_erl(OutDir, Mod, BinStr) ->
  719. Filename = filename:join([OutDir, atom_to_list(Mod) ++ ".erl"]),
  720. case file:write_file(Filename, BinStr) of
  721. ok ->
  722. ok;
  723. _Ret ->
  724. io:format("write to erl file error:~p ~n", [_Ret])
  725. end,
  726. Filename.