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.

271 lines
7.1 KiB

пре 1 година
  1. BA_ENDIAN_BIG = "ENDIAN_BIG" -- 大端
  2. BA_ENDIAN_LITTLE = "ENDIAN_LITTLE" -- 小端
  3. function ByteArray(endian)
  4. ----------------------------------------------------------------------
  5. -- private member variable
  6. ----------------------------------------------------------------------
  7. local mRadix = {[8]="%03o", [10]="%03u", [16]="%02X"} -- 进制
  8. local mEndian = endian or "" -- 大小端标识
  9. local mBuf = {} -- 二进制字节流
  10. local mPos = 1 -- 读写位置
  11. ----------------------------------------------------------------------
  12. -- private method
  13. ----------------------------------------------------------------------
  14. -- 验证读写位置
  15. local function checkAvailable()
  16. assert(#mBuf >= mPos, string.format("End of file was encountered. pos: %d, length: %d.", mPos, #mBuf))
  17. end
  18. -- 获取字符码
  19. local function getLetterCode(fmt)
  20. fmt = fmt or ""
  21. if BA_ENDIAN_LITTLE == mEndian then
  22. return "<"..fmt
  23. elseif BA_ENDIAN_BIG == mEndian then
  24. return ">"..fmt
  25. else
  26. return "="..fmt
  27. end
  28. end
  29. -- 读单个字节
  30. local function readRawByte()
  31. checkAvailable()
  32. local rawByte = mBuf[mPos]
  33. mPos = mPos + 1
  34. return rawByte
  35. end
  36. -- 写单个字节
  37. local function writeRawByte(rawByte)
  38. if mPos > #mBuf + 1 then
  39. for i=#mBuf + 1, mPos - 1 do
  40. mBuf[i] = string.char(0)
  41. end
  42. end
  43. mBuf[mPos] = rawByte
  44. mPos = mPos + 1
  45. end
  46. -- 读字节流
  47. local function readBuf(length)
  48. checkAvailable()
  49. local buf = table.concat(mBuf, "", mPos, mPos + length - 1)
  50. mPos = mPos + length
  51. return buf
  52. end
  53. -- 写字节流
  54. local function writeBuf(buf)
  55. for i=1, #buf do
  56. writeRawByte(buf:sub(i, i))
  57. end
  58. end
  59. -- 读字符串
  60. local function read_string_bytes(length)
  61. if 0 == length then
  62. return ""
  63. end
  64. local tmp, value = string.unpack(readBuf(length), getLetterCode("A"..length))
  65. return value
  66. end
  67. -- 写字符串
  68. local function write_string_bytes(value)
  69. local buf = string.pack(getLetterCode("A"), value)
  70. writeBuf(buf)
  71. end
  72. ----------------------------------------------------------------------
  73. -- public method
  74. ----------------------------------------------------------------------
  75. local ba = {}
  76. -- 设置大小端
  77. ba.setEndian = function(endian)
  78. mEndian = endian or ""
  79. end
  80. -- 设置字节流
  81. ba.setBytes = function(buf)
  82. if #mBuf > 0 then
  83. return
  84. end
  85. writeBuf(buf)
  86. mPos = 1 -- 这里必须重置读写位置为1,方能保证接下去的读操作正确
  87. end
  88. -- 获取字节流
  89. ba.getBytes = function()
  90. local bytes = {}
  91. for i=1, #mBuf do
  92. bytes[#bytes+1] = string.byte(mBuf[i])
  93. end
  94. local packRes = string.pack(getLetterCode("b"..#bytes), unpack(bytes))
  95. return packRes
  96. end
  97. -- 获取字节流长度
  98. ba.getLength = function()
  99. return #mBuf
  100. end
  101. -- 字节流转为字符串,radix-8,10,16
  102. ba.toString = function(radix, separator)
  103. radix = radix or 16
  104. radix = mRadix[radix] or "%02X"
  105. separator = separator or " "
  106. local bytes = {}
  107. for i=1, #mBuf do
  108. bytes[i] = string.format(radix..separator, string.byte(mBuf[i]))
  109. end
  110. return table.concat(bytes)
  111. end
  112. ----------------------------------------------------------------------
  113. -- 读16位整型
  114. ba.read_int16 = function()
  115. local tmp, value = string.unpack(readBuf(2), getLetterCode("h"))
  116. return value
  117. end
  118. -- 写16位整型
  119. ba.write_int16 = function(value)
  120. local buf = string.pack(getLetterCode("h"), value)
  121. writeBuf(buf)
  122. end
  123. -- 读16位无符号整型
  124. ba.read_uint16 = function()
  125. local tmp, value = string.unpack(readBuf(2), getLetterCode("H"))
  126. return value
  127. end
  128. -- 写16位无符号整型
  129. ba.write_uint16 = function(value)
  130. local sstr = getLetterCode("H")
  131. local buf = string.pack(sstr, value)
  132. writeBuf(buf)
  133. end
  134. -- 读32位整型
  135. ba.read_int32 = function()
  136. local tmp, value = string.unpack(readBuf(4), getLetterCode("i"))
  137. return value
  138. end
  139. -- 写32位整型
  140. ba.write_int32 = function(value)
  141. local buf = string.pack(getLetterCode("i"), value)
  142. writeBuf(buf)
  143. end
  144. -- 读32位无符号整型
  145. ba.read_uint32 = function()
  146. local tmp, value = string.unpack(readBuf(4), getLetterCode("I"))
  147. return value
  148. end
  149. -- 写32位无符号整型
  150. ba.write_uint32 = function(value)
  151. local buf = string.pack(getLetterCode("I"), value)
  152. writeBuf(buf)
  153. end
  154. -- 读长整型
  155. ba.read_long = function()
  156. local tmp, value = string.unpack(readBuf(4), getLetterCode("l"))
  157. return value
  158. end
  159. -- 写长整型
  160. ba.write_long = function(value)
  161. local buf = string.pack(getLetterCode("l"), value)
  162. writeBuf(buf)
  163. end
  164. -- 读无符号长整型
  165. ba.read_ulong = function()
  166. local tmp, value = string.unpack(readBuf(4), getLetterCode("L"))
  167. return value
  168. end
  169. -- 写无符号长整型
  170. ba.write_ulong = function(value)
  171. local buf = string.pack(getLetterCode("L"), value)
  172. writeBuf(buf)
  173. end
  174. -- 读64位整型
  175. ba.read_int64 = function()
  176. -- local tmp, value = string.unpack(readBuf(8), getLetterCode("m"))
  177. -- return value
  178. return read_string_bytes(8)
  179. end
  180. -- 写64位整型
  181. ba.write_int64 = function(value)
  182. -- local buf = string.pack(getLetterCode("m"), value)
  183. -- writeBuf(buf)
  184. local buf = string.pack(getLetterCode("A"), value)
  185. writeBuf(buf)
  186. end
  187. -- 读64位无符号整型
  188. ba.read_uint64 = function()
  189. -- local tmp, value = string.unpack(readBuf(8), getLetterCode("M"))
  190. -- return value
  191. return read_string_bytes(8)
  192. end
  193. -- 写64位无符号整型
  194. ba.write_uint64 = function(value)
  195. -- local buf = string.pack(getLetterCode("M"), value)
  196. -- writeBuf(buf)
  197. local buf = string.pack(getLetterCode("A"), value)
  198. writeBuf(buf)
  199. end
  200. -- 读单精度浮点型
  201. ba.read_float = function()
  202. local tmp, value = string.unpack(readBuf(4), getLetterCode("f"))
  203. return value
  204. end
  205. -- 写单精度浮点型
  206. ba.write_float = function(value)
  207. local buf = string.pack(getLetterCode("f"), value)
  208. writeBuf(buf)
  209. end
  210. -- 读双精度浮点型
  211. ba.read_double = function()
  212. local tmp, value = string.unpack(readBuf(8), getLetterCode("d"))
  213. return value
  214. end
  215. -- 写双精度浮点型
  216. ba.write_double = function(value)
  217. local buf = string.pack(getLetterCode("d"), value)
  218. writeBuf(buf)
  219. end
  220. -- 读布尔型
  221. ba.read_bool = function()
  222. return 1 == read_char()
  223. end
  224. -- 写布尔型
  225. ba.write_bool = function(value)
  226. if value then
  227. ba.write_char(1)
  228. else
  229. ba.write_char(0)
  230. end
  231. end
  232. -- 读字符型
  233. ba.read_int8 = function()
  234. local tmp, value = string.unpack(readRawByte(), "c")
  235. return value
  236. end
  237. -- 写字符型
  238. ba.write_int8 = function(value)
  239. writeRawByte(string.pack("c", value))
  240. end
  241. -- 读单字节
  242. ba.read_uint8 = function()
  243. -- 方法1
  244. -- return string.byte(readRawByte())
  245. -- 方法2
  246. local tmp, value = string.unpack(readRawByte(), "b")
  247. return value
  248. end
  249. -- 写单字节
  250. ba.write_uint8 = function(value)
  251. -- 方法1
  252. -- writeRawByte(string.char(value))
  253. -- 方法2
  254. writeRawByte(string.pack("b", value))
  255. end
  256. -- 读字符串
  257. ba.read_string = function()
  258. local length = ba.read_uint16()
  259. return read_string_bytes(length)
  260. end
  261. -- 写字符串
  262. ba.write_string = function(value)
  263. local buf = string.pack(getLetterCode("A"), value)
  264. ba.write_uint16(#buf)
  265. writeBuf(buf)
  266. end
  267. ----------------------------------------------------------------------
  268. return ba
  269. end