erlang自定义二进制协议
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

487 строки
18 KiB

5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
5 лет назад
  1. -module(protoGen).
  2. -export([
  3. convertFile/1
  4. , convert/1
  5. , convertDir/0
  6. , convertDir/1
  7. , convertDir/3
  8. ]).
  9. protoHrlHeader() ->
  10. "-opaque int8() :: -128..127.
  11. -opaque int16() :: -32768..32767.
  12. -opaque int32() :: -2147483648..2147483647.
  13. -opaque int64() :: -9223372036854775808..9223372036854775807.
  14. -opaque uint8() :: 0..255.
  15. -opaque uint16() :: 0..65536.
  16. -opaque uint32() :: 0..4294967295.
  17. -opaque uint64() :: 0..18446744073709551615.
  18. -opaque double() :: float().\n\n".
  19. protoErlHeader() ->
  20. "-module(protoMsg).\n\n
  21. -export([encode/1, decode/1, encodeRec/1, decodeRec/2]).
  22. -define(min8, -128).
  23. -define(max8, 127).
  24. -define(min16, -32768).
  25. -define(max16, 32767).
  26. -define(min32, -2147483648).
  27. -define(max32, 2147483647).
  28. -define(min64, -9223372036854775808).
  29. -define(max64, 9223372036854775807).
  30. -define(minF32, -3.4E+38).
  31. -define(maxF32, 3.4E+38).
  32. -define(minF64, -1.797E-308).
  33. -define(maxF64, 1.797E+308).
  34. -define(int8(V), <<V:8>>).
  35. -define(uint8(V), <<V:8>>).
  36. -define(int16(V), <<V:16/little>>).
  37. -define(uint16(V), <<V:16/little>>).
  38. -define(int32(V), <<V:32/little>>).
  39. -define(uint32(V), <<V:32/little>>).
  40. -define(int64(V), <<V:64/little>>).
  41. -define(uint64(V), <<V:64/little>>).
  42. -define(integer(V), (integer(V))).
  43. -define(number(V), (number(V))).
  44. -define(string(V), (string(V))).
  45. -define(float(V), <<V:32/little-float>>).
  46. -define(double(V), <<V:64/little-float>>).
  47. -define(bool(V), (case V of true -> <<1:8>>; _ -> <<0:8>> end)).
  48. -define(record(V), (case V of undefined -> [<<0:8>>]; V -> [<<1:8>>, encodeRec(V)] end)).
  49. -define(list_bool(List), [<<(length(List)):16/little>>, [?bool(V) || V <- List]]).
  50. -define(list_int8(List), [<<(length(List)):16/little>>, [?int8(V) || V <- List]]).
  51. -define(list_uint8(List), [<<(length(List)):16/little>>, [?uint8(V) || V <- List]]).
  52. -define(list_int16(List), [<<(length(List)):16/little>>, [?int16(V) || V <- List]]).
  53. -define(list_uint16(List), [<<(length(List)):16/little>>, [?uint16(V) || V <- List]]).
  54. -define(list_int32(List), [<<(length(List)):16/little>>, [?int32(V) || V <- List]]).
  55. -define(list_uint32(List), [<<(length(List)):16/little>>, [?uint32(V) || V <- List]]).
  56. -define(list_int64(List), [<<(length(List)):16/little>>, [?int64(V) || V <- List]]).
  57. -define(list_uint64(List), [<<(length(List)):16/little>>, [?uint64(V) || V <- List]]).
  58. -define(list_float(List), [<<(length(List)):16/little>>, [?float(V) || V <- List]]).
  59. -define(list_double(List), [<<(length(List)):16/little>>, [?double(V) || V <- List]]).
  60. -define(list_integer(List), [<<(length(List)):16/little>>, [integer(V) || V <- List]]).
  61. -define(list_number(List), [<<(length(List)):16/little>>, [number(V) || V <- List]]).
  62. -define(list_string(List), [<<(length(List)):16/little>>, [string(V) || V <- List]]).
  63. -define(list_record(List), [<<(length(List)):16/little>>, [encodeRec(V) || V <- List]]).
  64. integer(V) ->
  65. if
  66. V >= ?min8 andalso V =< ?max8 ->
  67. <<8:8, <<V:8>>/binary>>;
  68. V >= ?min16 andalso V =< ?max16 ->
  69. <<16:8, <<V:16/little>>/binary>>;
  70. V >= ?min32 andalso V =< ?max32 ->
  71. <<32:8, <<V:32/little>>/binary>>;
  72. V >= ?min64 andalso V =< ?max64 ->
  73. <<64:8, <<V:64/little>>/binary>>;
  74. true ->
  75. throw(exceeded_the_integer)
  76. end.
  77. numInteger(V) ->
  78. if
  79. V >= ?min8 andalso V =< ?max8 ->
  80. <<8:8, <<V:8>>/binary>>;
  81. V >= ?min16 andalso V =< ?max16 ->
  82. <<16:8, <<V:16/little>>/binary>>;
  83. V >= ?min32 andalso V =< ?max32 ->
  84. <<32:8, <<V:32/little>>/binary>>;
  85. V >= ?min64 andalso V =< ?max64 ->
  86. <<64:8, <<V:64/little>>/binary>>;
  87. true ->
  88. throw(exceeded_the_integer)
  89. end.
  90. numFloat(V) ->
  91. if
  92. V >= ?minF32 andalso V =< ?maxF32 ->
  93. <<33:8, <<V:32/little-float>>/binary>>;
  94. V >= ?minF64 andalso V =< ?maxF64 ->
  95. <<65:8, <<V:64/little-float>>/binary>>;
  96. true ->
  97. throw(exceeded_the_float)
  98. end.
  99. number(V) ->
  100. if
  101. erlang:is_integer(V) == true ->
  102. numInteger(V);
  103. erlang:is_float(V) == true ->
  104. numFloat(V);
  105. true ->
  106. throw(is_not_number)
  107. end.
  108. string(Str) when is_binary(Str) ->
  109. [<<(byte_size(Str)):16/little>>, Str];
  110. string(Str) ->
  111. Str2 = unicode:characters_to_binary(Str, utf8),
  112. [<<(byte_size(Str2)):16/little>>, Str2].
  113. encode(Record) ->
  114. MsgBin = encodeRec(Record),
  115. MsgId = getMsgId(element(1, Record)),
  116. [<<MsgId:16/little>>, MsgBin].
  117. decode(Bin) ->
  118. <<MsgId:16/little, MsgBin/binary>> = Bin,
  119. SchList = getMsgSchema(MsgId),
  120. {<<>>, ResultList} = decodeField(SchList, MsgBin, [getMsgType(MsgId)]),
  121. list_to_tuple(ResultList).
  122. decodeRec(RecordName, Bin) ->
  123. SchList = getMsgSchema(RecordName),
  124. {LeftBin, Result} = decodeField(SchList, Bin, [RecordName]),
  125. {LeftBin, list_to_tuple(Result)}.
  126. decodeField([], LeftBin, Result) ->
  127. {LeftBin, lists:reverse(Result)};
  128. decodeField([Type | SchList], MsgBin, Result) ->
  129. case Type of
  130. int32 ->
  131. <<Int:32/little-signed, LeftBin/binary>> = MsgBin,
  132. decodeField(SchList, LeftBin, [Int | Result]);
  133. uint32 ->
  134. <<Int:32/little-unsigned, LeftBin/binary>> = MsgBin,
  135. decodeField(SchList, LeftBin, [Int | Result]);
  136. string ->
  137. <<Len:16/little, StrBin:Len/binary, LeftBin/binary>> = MsgBin,
  138. decodeField(SchList, LeftBin, [StrBin | Result]);
  139. int16 ->
  140. <<Int:16/little-signed, LeftBin/binary>> = MsgBin,
  141. decodeField(SchList, LeftBin, [Int | Result]);
  142. uint16 ->
  143. <<Int:16/little-unsigned, LeftBin/binary>> = MsgBin,
  144. decodeField(SchList, LeftBin, [Int | Result]);
  145. int8 ->
  146. <<Int:8/little-signed, LeftBin/binary>> = MsgBin,
  147. decodeField(SchList, LeftBin, [Int | Result]);
  148. uint8 ->
  149. <<Int:8/little-unsigned, LeftBin/binary>> = MsgBin,
  150. decodeField(SchList, LeftBin, [Int | Result]);
  151. int64 ->
  152. <<Int:64/little-signed, LeftBin/binary>> = MsgBin,
  153. decodeField(SchList, LeftBin, [Int | Result]);
  154. uint64 ->
  155. <<Int:64/little-unsigned, LeftBin/binary>> = MsgBin,
  156. decodeField(SchList, LeftBin, [Int | Result]);
  157. integer ->
  158. <<IntBits:8, Int:IntBits/little-signed, LeftBin/binary>> = MsgBin,
  159. decodeField(SchList, LeftBin, [Int | Result]);
  160. number ->
  161. <<NumBits:8, NumBin/binary>> = MsgBin,
  162. case NumBits of
  163. 33 ->
  164. <<Float:32/little-float, LeftBin/binary>> = NumBin,
  165. decodeField(SchList, LeftBin, [Float | Result]);
  166. 65 ->
  167. <<Float:64/little-float, LeftBin/binary>> = NumBin,
  168. decodeField(SchList, LeftBin, [Float | Result]);
  169. _ ->
  170. <<Int:NumBits/little-signed, LeftBin/binary>> = NumBin,
  171. decodeField(SchList, LeftBin, [Int | Result])
  172. end;
  173. bool ->
  174. <<Bool:8/little-unsigned, LeftBin/binary>> = MsgBin,
  175. case Bool =:= 1 of
  176. true ->
  177. decodeField(SchList, LeftBin, [true | Result]);
  178. _ ->
  179. decodeField(SchList, LeftBin, [false | Result])
  180. end;
  181. float ->
  182. <<Float:32/little-float, LeftBin/binary>> = MsgBin,
  183. decodeField(SchList, LeftBin, [Float | Result]);
  184. double ->
  185. <<Float:64/little-float, LeftBin/binary>> = MsgBin,
  186. decodeField(SchList, LeftBin, [Float | Result]);
  187. {list, int32} ->
  188. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  189. {LeftBin, RetList} = deInt32List(Len, LeftListBin, []),
  190. decodeField(SchList, LeftBin, [RetList | Result]);
  191. {list, uint32} ->
  192. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  193. {LeftBin, RetList} = deUint32List(Len, LeftListBin, []),
  194. decodeField(SchList, LeftBin, [RetList | Result]);
  195. {list, int16} ->
  196. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  197. {LeftBin, RetList} = deInt16List(Len, LeftListBin, []),
  198. decodeField(SchList, LeftBin, [RetList | Result]);
  199. {list, uint16} ->
  200. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  201. {LeftBin, RetList} = deUint16List(Len, LeftListBin, []),
  202. decodeField(SchList, LeftBin, [RetList | Result]);
  203. {list, int8} ->
  204. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  205. {LeftBin, RetList} = deInt8List(Len, LeftListBin, []),
  206. decodeField(SchList, LeftBin, [RetList | Result]);
  207. {list, uint8} ->
  208. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  209. {LeftBin, RetList} = deUint8List(Len, LeftListBin, []),
  210. decodeField(SchList, LeftBin, [RetList | Result]);
  211. {list, string} ->
  212. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  213. {LeftBin, RetList} = deStringList(Len, LeftListBin, []),
  214. decodeField(SchList, LeftBin, [RetList | Result]);
  215. {list, int64} ->
  216. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  217. {LeftBin, RetList} = deInt64List(Len, LeftListBin, []),
  218. decodeField(SchList, LeftBin, [RetList | Result]);
  219. {list, uint64} ->
  220. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  221. {LeftBin, RetList} = deUint64List(Len, LeftListBin, []),
  222. decodeField(SchList, LeftBin, [RetList | Result]);
  223. {list, integer} ->
  224. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  225. {LeftBin, RetList} = deIntegerList(Len, LeftListBin, []),
  226. decodeField(SchList, LeftBin, [RetList | Result]);
  227. {list, number} ->
  228. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  229. {LeftBin, RetList} = deNumberList(Len, LeftListBin, []),
  230. decodeField(SchList, LeftBin, [RetList | Result]);
  231. {list, bool} ->
  232. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  233. {LeftBin, RetList} = deBoolList(Len, LeftListBin, []),
  234. decodeField(SchList, LeftBin, [RetList | Result]);
  235. {list, float} ->
  236. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  237. {LeftBin, RetList} = deFloatList(Len, LeftListBin, []),
  238. decodeField(SchList, LeftBin, [RetList | Result]);
  239. {list, double} ->
  240. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  241. {LeftBin, RetList} = deDoubleList(Len, LeftListBin, []),
  242. decodeField(SchList, LeftBin, [RetList | Result]);
  243. {list, RecordName} ->
  244. <<Len:16/little, LeftListBin/binary>> = MsgBin,
  245. {LeftBin, RetList} = deRecordList(Len, RecordName, LeftListBin, []),
  246. decodeField(SchList, LeftBin, [RetList | Result]);
  247. RecordName ->
  248. <<IsUndef:8, LeftBin/binary>> = MsgBin,
  249. case IsUndef of
  250. 0 ->
  251. decodeField(SchList, LeftBin, [undefined | Result]);
  252. _ ->
  253. SubSchList = getMsgSchema(RecordName),
  254. {SubLeftBin, SubResultList} = decodeField(SubSchList, LeftBin, [RecordName]),
  255. decodeField(SchList, SubLeftBin, [list_to_tuple(SubResultList) | Result])
  256. end
  257. end.
  258. deBoolList(0, MsgBin, RetList) ->
  259. {MsgBin, lists:reverse(RetList)};
  260. deBoolList(N, MsgBin, RetList) ->
  261. <<Bool:8, LeftBin/binary>> = MsgBin,
  262. case Bool =:= 1 of
  263. true ->
  264. deBoolList(N - 1, LeftBin, [true | RetList]);
  265. _ ->
  266. deBoolList(N - 1, LeftBin, [false | RetList])
  267. end.
  268. deInt8List(0, MsgBin, RetList) ->
  269. {MsgBin, RetList};
  270. deInt8List(N, MsgBin, RetList) ->
  271. <<Int:8/little-signed, LeftBin/binary>> = MsgBin,
  272. deInt8List(N - 1, LeftBin, [Int | RetList]).
  273. deUint8List(0, MsgBin, RetList) ->
  274. {MsgBin, lists:reverse(RetList)};
  275. deUint8List(N, MsgBin, RetList) ->
  276. <<Int:8/little-unsigned, LeftBin/binary>> = MsgBin,
  277. deUint8List(N - 1, LeftBin, [Int | RetList]).
  278. deInt16List(0, MsgBin, RetList) ->
  279. {MsgBin, lists:reverse(RetList)};
  280. deInt16List(N, MsgBin, RetList) ->
  281. <<Int:16/little-signed, LeftBin/binary>> = MsgBin,
  282. deInt16List(N - 1, LeftBin, [Int | RetList]).
  283. deUint16List(0, MsgBin, RetList) ->
  284. {MsgBin, lists:reverse(RetList)};
  285. deUint16List(N, MsgBin, RetList) ->
  286. <<Int:16/little-unsigned, LeftBin/binary>> = MsgBin,
  287. deUint16List(N - 1, LeftBin, [Int | RetList]).
  288. deInt32List(0, MsgBin, RetList) ->
  289. {MsgBin, lists:reverse(RetList)};
  290. deInt32List(N, MsgBin, RetList) ->
  291. <<Int:32/little-signed, LeftBin/binary>> = MsgBin,
  292. deInt32List(N - 1, LeftBin, [Int | RetList]).
  293. deUint32List(0, MsgBin, RetList) ->
  294. {MsgBin, lists:reverse(RetList)};
  295. deUint32List(N, MsgBin, RetList) ->
  296. <<Int:32/little-unsigned, LeftBin/binary>> = MsgBin,
  297. deUint32List(N - 1, LeftBin, [Int | RetList]).
  298. deInt64List(0, MsgBin, RetList) ->
  299. {MsgBin, lists:reverse(RetList)};
  300. deInt64List(N, MsgBin, RetList) ->
  301. <<Int:64/little-signed, LeftBin/binary>> = MsgBin,
  302. deInt64List(N - 1, LeftBin, [Int | RetList]).
  303. deUint64List(0, MsgBin, RetList) ->
  304. {MsgBin, lists:reverse(RetList)};
  305. deUint64List(N, MsgBin, RetList) ->
  306. <<Int:64/little-unsigned, LeftBin/binary>> = MsgBin,
  307. deUint64List(N - 1, LeftBin, [Int | RetList]).
  308. deIntegerList(0, MsgBin, RetList) ->
  309. {MsgBin, lists:reverse(RetList)};
  310. deIntegerList(N, MsgBin, RetList) ->
  311. <<IntBits:8, Int:IntBits/little-signed, LeftBin/binary>> = MsgBin,
  312. deIntegerList(N - 1, LeftBin, [Int | RetList]).
  313. deNumberList(0, MsgBin, RetList) ->
  314. {MsgBin, lists:reverse(RetList)};
  315. deNumberList(N, MsgBin, RetList) ->
  316. <<NumBits:8, NumBin/binary>> = MsgBin,
  317. case NumBits of
  318. 33 ->
  319. <<Float:32/little-float, LeftBin/binary>> = NumBin,
  320. deNumberList(N - 1, LeftBin, [Float | RetList]);
  321. 65 ->
  322. <<Float:64/little-float, LeftBin/binary>> = NumBin,
  323. deNumberList(N - 1, LeftBin, [Float | RetList]);
  324. _ ->
  325. <<Int:NumBits/little-signed, LeftBin/binary>> = NumBin,
  326. deNumberList(N - 1, LeftBin, [Int | RetList])
  327. end.
  328. deFloatList(0, MsgBin, RetList) ->
  329. {MsgBin, lists:reverse(RetList)};
  330. deFloatList(N, MsgBin, RetList) ->
  331. <<Float:32/little-float, LeftBin/binary>> = MsgBin,
  332. deFloatList(N - 1, LeftBin, [Float | RetList]).
  333. deDoubleList(0, MsgBin, RetList) ->
  334. {MsgBin, lists:reverse(RetList)};
  335. deDoubleList(N, MsgBin, RetList) ->
  336. <<Float:64/little-float, LeftBin/binary>> = MsgBin,
  337. deDoubleList(N - 1, LeftBin, [Float | RetList]).
  338. deStringList(0, MsgBin, RetList) ->
  339. {MsgBin, lists:reverse(RetList)};
  340. deStringList(N, MsgBin, RetList) ->
  341. <<Len:16/little, StrBin:Len/binary-unit:8, LeftBin/binary>> = MsgBin,
  342. deStringList(N - 1, LeftBin, [StrBin | RetList]).
  343. deRecordList(0, _RecordName, MsgBin, RetList) ->
  344. {MsgBin, lists:reverse(RetList)};
  345. deRecordList(N, RecordName, MsgBin, RetList) ->
  346. {LeftBin, Tuple} = decodeRec(RecordName, MsgBin),
  347. deRecordList(N - 1, RecordName, LeftBin, [Tuple | RetList]).\n\n".
  348. genSchema({FieldType, _FieldName}, AccList) ->
  349. SchemaStr = protoField:getSchemaInfo(FieldType),
  350. [SchemaStr | AccList].
  351. genMsgHrl(FieldInfo, {Index, Len, AccList}) ->
  352. TemStr =
  353. case Index of
  354. 1 ->
  355. "";
  356. _ ->
  357. ", "
  358. end,
  359. RecStr = TemStr ++ protoField:builtRecStr(FieldInfo) ++ (case Index == Len of true -> ""; _ -> "\t" end),
  360. {Index - 1, Len, [RecStr | AccList]}.
  361. genEncodeRec({MsgName, _MsgId, FieldList}) ->
  362. FieldLen = length(FieldList),
  363. FunHead =
  364. fun(_, {Index, StrAcc}) ->
  365. {Index - 1, ", V" ++ integer_to_list(Index) ++ StrAcc}
  366. end,
  367. {_, TemStr} = lists:foldr(FunHead, {FieldLen, "}) ->\n\t"}, FieldList),
  368. HeadStr = "encodeRec({" ++ MsgName ++ TemStr,
  369. FunBody =
  370. fun({FieldType, _FieldName}, {Index, PStrAcc}) ->
  371. TemV = "V" ++ integer_to_list(Index),
  372. PackStr = protoField:builtPackStr(FieldType) ++ TemV ++ ")",
  373. case Index == 1 of
  374. true ->
  375. {Index - 1, PackStr ++ PStrAcc};
  376. _ ->
  377. {Index - 1, ", " ++ PackStr ++ PStrAcc}
  378. end
  379. end,
  380. {_, LastStr} = lists:foldr(FunBody, {FieldLen, ""}, FieldList),
  381. case FieldLen > 0 of
  382. true ->
  383. HeadStr ++ "[" ++ LastStr ++ "];\n";
  384. _ ->
  385. HeadStr ++ "[];\n"
  386. end.
  387. convertFile(File) ->
  388. protoParse:parseFile(File).
  389. convert([ProtoDir, HrlDir, ErlDir]) ->
  390. convertDir(atom_to_list(ProtoDir), atom_to_list(HrlDir), atom_to_list(ErlDir)).
  391. convertDir() ->
  392. convertDir("./", "./", "./").
  393. convertDir(ProtoDir) ->
  394. convertDir(ProtoDir, "./", "./").
  395. convertDir(ProtoDir, HrlDir, ErlDir) ->
  396. FunRead =
  397. fun(File, Acc) ->
  398. case filename:extension(File) == ".msg" of
  399. true ->
  400. io:format("Convert proto msg file: ~s ~n", [File]),
  401. BaseName = filename:basename(File, ".msg"),
  402. [ModIndex | _ModName] = re:split(BaseName, "_"),
  403. Index = binary_to_integer(ModIndex),
  404. put(messageid, Index * 1000 + 1),
  405. SProto = protoParse:parseFile(File),
  406. [SProto | Acc];
  407. _ ->
  408. Acc
  409. end
  410. end,
  411. %% 下面文件帅选并不能准确的帅选出文件名为.msg结尾的文件 在FunRead函数中纠正处理一下
  412. SProtoListOfList = filelib:fold_files(ProtoDir, "\\.msg", true, FunRead, []),
  413. SProtoList = lists:append(SProtoListOfList),
  414. SortedSProtoList = lists:sort(fun({_Name1, MessageId1, _FieldList1}, {_Name2, MessageId2, _FieldList2}) ->
  415. MessageId1 > MessageId2 end, SProtoList),
  416. FunSpell =
  417. fun({MsgName, MsgId, FieldList} = MsgInfo, {MsgHrlAcc, MsgTypeAcc, MsgIdAcc, MsgEndStr, MsgSchemaAcc}) ->
  418. TypeStr = "getMsgType(" ++ integer_to_list(MsgId) ++ ")-> " ++ MsgName ++ ";\n",
  419. IdStr = "getMsgId(" ++ MsgName ++ ")-> " ++ integer_to_list(MsgId) ++ ";\n",
  420. EncodeStr = genEncodeRec(MsgInfo),
  421. Len = erlang:length(FieldList),
  422. SchemaList = lists:foldr(fun genSchema/2, [], FieldList),
  423. SchemaStr = "getMsgSchema(" ++ MsgName ++ ")->\n\t" ++ "getMsgSchema(" ++ integer_to_list(MsgId) ++ ");\n" ++
  424. "getMsgSchema(" ++ integer_to_list(MsgId) ++ ")->\n\t" ++ io_lib:format("~p", [SchemaList]) ++ ";\n",
  425. {_, Len, LastFieldStr} = lists:foldr(fun genMsgHrl/2, {Len, Len, ""}, FieldList),
  426. HrlStr = "-record(" ++ MsgName ++ " ,{\n\t" ++ LastFieldStr ++ "}).\n",
  427. {[HrlStr | MsgHrlAcc], [TypeStr | MsgTypeAcc], [IdStr | MsgIdAcc], [EncodeStr | MsgEndStr], [SchemaStr | MsgSchemaAcc]}
  428. end,
  429. {MsgHrlStr, MsgTypeStr, MsgIdStr, MsgEndStr, MsgSchemaStr} = lists:foldl(FunSpell, {[], ["getMsgType(_) -> undefined.\n\n"], ["getMsgId(_) -> 0.\n\n"], ["encodeRec(_) ->\n\t[].\n\n"], ["getMsgSchema(_) ->\n\t[].\n\n"]}, SortedSProtoList),
  430. ModStr = protoErlHeader(),
  431. OutputStr = ModStr ++ MsgTypeStr ++ MsgIdStr ++ MsgEndStr ++ MsgSchemaStr,
  432. HrlFilename = do_write_hrl(HrlDir, protoMsg, protoHrlHeader() ++ MsgHrlStr),
  433. ErlFilename = do_write_erl(ErlDir, protoMsg, OutputStr),
  434. io:format("protoConvert hrl dir : ~s ~n", [HrlDir]),
  435. io:format("protoConvert erl dir : ~s ~n", [ErlDir]),
  436. io:format("protoConvert to hrl file ~s succ.~n", [HrlFilename]),
  437. io:format("protoConvert to erl file ~s succ.~n", [ErlFilename]),
  438. ok.
  439. do_write_hrl(OutDir, Mod, Str) when is_list(OutDir) ->
  440. Filename = filename:join([OutDir, atom_to_list(Mod) ++ ".hrl"]),
  441. ok = file:write_file(Filename, Str),
  442. Filename.
  443. do_write_erl(OutDir, Mod, Str) when is_list(OutDir) ->
  444. Filename = filename:join([OutDir, atom_to_list(Mod) ++ ".erl"]),
  445. ok = file:write_file(Filename, Str),
  446. Filename.