tlv.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. package tlv
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "io"
  8. )
  9. // 定义数据类型
  10. const (
  11. TLVFLOAT64 = 1
  12. TLVFLOAT32 = 2
  13. TLVINT8 = 3
  14. TLVINT16 = 4
  15. TLVINT32 = 5
  16. TLVINT64 = 6
  17. TLVUINT8 = 7
  18. TLVUINT16 = 8
  19. TLVUINT32 = 9
  20. TLVUINT64 = 10
  21. TLVBYTES = 11
  22. TLVSTRING = 12
  23. TLVBOOL = 13
  24. )
  25. // TLV type length value
  26. type TLV struct {
  27. Tag uint16
  28. Value []byte
  29. }
  30. func uint16ToByte(value uint16) []byte {
  31. buf := bytes.NewBuffer([]byte{})
  32. binary.Write(buf, binary.BigEndian, value)
  33. return buf.Bytes()
  34. }
  35. func byteToUint16(buf []byte) uint16 {
  36. tmpBuf := bytes.NewBuffer(buf)
  37. var value uint16
  38. binary.Read(tmpBuf, binary.BigEndian, &value)
  39. return value
  40. }
  41. // ToBinary make tlv to []byte
  42. func (tlv *TLV) ToBinary() []byte {
  43. buf := new(bytes.Buffer)
  44. binary.Write(buf, binary.BigEndian, &tlv.Tag)
  45. binary.Write(buf, binary.BigEndian, &tlv.Value)
  46. return buf.Bytes()
  47. }
  48. // Length get tlv length
  49. func (tlv *TLV) Length() int {
  50. length := int(0)
  51. switch tlv.Tag {
  52. case TLVFLOAT64:
  53. length = 8
  54. case TLVINT64:
  55. length = 8
  56. case TLVUINT64:
  57. length = 8
  58. case TLVFLOAT32:
  59. length = 4
  60. case TLVINT32:
  61. length = 4
  62. case TLVUINT32:
  63. length = 4
  64. case TLVINT16:
  65. length = 2
  66. case TLVUINT16:
  67. length = 2
  68. case TLVINT8:
  69. length = 1
  70. case TLVUINT8:
  71. length = 1
  72. case TLVBYTES:
  73. length = int(byteToUint16(tlv.Value[0:2]))
  74. length += 2
  75. case TLVSTRING:
  76. length = int(byteToUint16(tlv.Value[0:2]))
  77. length += 2
  78. default:
  79. length = 0
  80. }
  81. length += 2
  82. return length
  83. }
  84. // FromBinary read from binary
  85. func (tlv *TLV) FromBinary(r io.Reader) error {
  86. binary.Read(r, binary.BigEndian, &tlv.Tag)
  87. length := uint16(0)
  88. switch tlv.Tag {
  89. case TLVFLOAT64:
  90. length = 8
  91. tlv.Value = make([]byte, length)
  92. binary.Read(r, binary.BigEndian, &tlv.Value)
  93. case TLVINT64:
  94. length = 8
  95. tlv.Value = make([]byte, length)
  96. binary.Read(r, binary.BigEndian, &tlv.Value)
  97. case TLVUINT64:
  98. length = 8
  99. tlv.Value = make([]byte, length)
  100. binary.Read(r, binary.BigEndian, &tlv.Value)
  101. case TLVFLOAT32:
  102. length = 4
  103. tlv.Value = make([]byte, length)
  104. binary.Read(r, binary.BigEndian, &tlv.Value)
  105. case TLVINT32:
  106. length = 4
  107. tlv.Value = make([]byte, length)
  108. binary.Read(r, binary.BigEndian, &tlv.Value)
  109. case TLVUINT32:
  110. length = 4
  111. tlv.Value = make([]byte, length)
  112. binary.Read(r, binary.BigEndian, &tlv.Value)
  113. case TLVINT16:
  114. length = 2
  115. tlv.Value = make([]byte, length)
  116. binary.Read(r, binary.BigEndian, &tlv.Value)
  117. case TLVUINT16:
  118. length = 2
  119. tlv.Value = make([]byte, length)
  120. binary.Read(r, binary.BigEndian, &tlv.Value)
  121. case TLVINT8:
  122. length = 1
  123. tlv.Value = make([]byte, length)
  124. binary.Read(r, binary.BigEndian, &tlv.Value)
  125. case TLVUINT8:
  126. length = 1
  127. tlv.Value = make([]byte, length)
  128. binary.Read(r, binary.BigEndian, &tlv.Value)
  129. case TLVBYTES:
  130. binary.Read(r, binary.BigEndian, &length)
  131. tlv.Value = make([]byte, length+2)
  132. copy(tlv.Value[0:2], uint16ToByte(length))
  133. binary.Read(r, binary.BigEndian, tlv.Value[2:])
  134. case TLVSTRING:
  135. binary.Read(r, binary.BigEndian, &length)
  136. tlv.Value = make([]byte, length+2)
  137. copy(tlv.Value[0:2], uint16ToByte(length))
  138. binary.Read(r, binary.BigEndian, tlv.Value[2:])
  139. default:
  140. return fmt.Errorf("unsuport value: %d", tlv.Tag)
  141. }
  142. return nil
  143. }
  144. // MakeTLV make a tlv pointer
  145. func MakeTLV(a interface{}) (*TLV, error) {
  146. var tag uint16
  147. var length uint16
  148. buf := new(bytes.Buffer)
  149. switch a := a.(type) {
  150. case float64:
  151. tag = TLVFLOAT64
  152. length = 8
  153. binary.Write(buf, binary.BigEndian, a)
  154. case float32:
  155. tag = TLVFLOAT32
  156. length = 4
  157. binary.Write(buf, binary.BigEndian, a)
  158. case int8:
  159. tag = TLVINT8
  160. length = 1
  161. binary.Write(buf, binary.BigEndian, a)
  162. case int16:
  163. tag = TLVINT16
  164. length = 2
  165. binary.Write(buf, binary.BigEndian, a)
  166. case int32:
  167. tag = TLVINT32
  168. length = 4
  169. binary.Write(buf, binary.BigEndian, a)
  170. case int64:
  171. tag = TLVINT64
  172. length = 8
  173. binary.Write(buf, binary.BigEndian, a)
  174. case uint8:
  175. tag = TLVUINT8
  176. length = 1
  177. binary.Write(buf, binary.BigEndian, a)
  178. case uint16:
  179. tag = TLVUINT16
  180. length = 2
  181. binary.Write(buf, binary.BigEndian, a)
  182. case uint32:
  183. tag = TLVUINT32
  184. length = 4
  185. binary.Write(buf, binary.BigEndian, a)
  186. case uint64:
  187. tag = TLVUINT64
  188. length = 8
  189. binary.Write(buf, binary.BigEndian, a)
  190. case []byte:
  191. tag = TLVBYTES
  192. length = uint16(len(a))
  193. binary.Write(buf, binary.BigEndian, length)
  194. binary.Write(buf, binary.BigEndian, a)
  195. case string:
  196. tag = TLVSTRING
  197. length = uint16(len(a))
  198. binary.Write(buf, binary.BigEndian, length)
  199. binary.Write(buf, binary.BigEndian, []byte(a))
  200. default:
  201. return nil, fmt.Errorf("unsuport value: %v", a)
  202. }
  203. tlv := TLV{
  204. Tag: tag,
  205. Value: buf.Bytes(),
  206. }
  207. if length == 0 {
  208. tlv.Value = []byte{}
  209. }
  210. return &tlv, nil
  211. }
  212. // ReadTLV read from tlv pointer
  213. func ReadTLV(tlv *TLV) (interface{}, error) {
  214. tag := tlv.Tag
  215. length := uint16(0)
  216. value := tlv.Value
  217. buffer := bytes.NewReader(value)
  218. switch tag {
  219. case TLVFLOAT64:
  220. retvar := float64(0.0)
  221. err := binary.Read(buffer, binary.BigEndian, &retvar)
  222. return retvar, err
  223. case TLVFLOAT32:
  224. retvar := float32(0.0)
  225. err := binary.Read(buffer, binary.BigEndian, &retvar)
  226. return retvar, err
  227. case TLVINT8:
  228. retvar := int8(0)
  229. err := binary.Read(buffer, binary.BigEndian, &retvar)
  230. return retvar, err
  231. case TLVINT16:
  232. retvar := int16(0)
  233. err := binary.Read(buffer, binary.BigEndian, &retvar)
  234. return retvar, err
  235. case TLVINT32:
  236. retvar := int32(0)
  237. err := binary.Read(buffer, binary.BigEndian, &retvar)
  238. return retvar, err
  239. case TLVINT64:
  240. retvar := int64(0)
  241. err := binary.Read(buffer, binary.BigEndian, &retvar)
  242. return retvar, err
  243. case TLVUINT8:
  244. retvar := uint8(0)
  245. err := binary.Read(buffer, binary.BigEndian, &retvar)
  246. return retvar, err
  247. case TLVUINT16:
  248. retvar := uint16(0)
  249. err := binary.Read(buffer, binary.BigEndian, &retvar)
  250. return retvar, err
  251. case TLVUINT32:
  252. retvar := uint32(0)
  253. err := binary.Read(buffer, binary.BigEndian, &retvar)
  254. return retvar, err
  255. case TLVUINT64:
  256. retvar := uint64(0)
  257. err := binary.Read(buffer, binary.BigEndian, &retvar)
  258. return retvar, err
  259. case TLVBYTES:
  260. err := binary.Read(buffer, binary.BigEndian, &length)
  261. if err != nil {
  262. return []byte{}, err
  263. }
  264. retvar := make([]byte, length)
  265. err = binary.Read(buffer, binary.BigEndian, &retvar)
  266. return retvar, err
  267. case TLVSTRING:
  268. err := binary.Read(buffer, binary.BigEndian, &length)
  269. if err != nil {
  270. return string([]byte{}), err
  271. }
  272. retvar := make([]byte, length)
  273. err = binary.Read(buffer, binary.BigEndian, &retvar)
  274. return string(retvar), err
  275. default:
  276. return nil, errors.New("Reading TLV error ,Unkown TLV type: " + string(tag))
  277. }
  278. }
  279. // MakeTLVs ``
  280. func MakeTLVs(a []interface{}) ([]TLV, error) {
  281. tlvs := []TLV{}
  282. for _, one := range a {
  283. tlv, err := MakeTLV(one)
  284. if err != nil {
  285. return nil, err
  286. }
  287. tlvs = append(tlvs, *tlv)
  288. }
  289. return tlvs, nil
  290. }
  291. // ReadTLVs ``
  292. func ReadTLVs(tlvs []TLV) ([]interface{}, error) {
  293. values := []interface{}{}
  294. for _, tlv := range tlvs {
  295. one, err := ReadTLV(&tlv)
  296. if err != nil {
  297. return values, err
  298. }
  299. values = append(values, one)
  300. }
  301. return values, nil
  302. }
  303. // CastTLV cast tlv
  304. func CastTLV(value interface{}, valueType int32) interface{} {
  305. switch valueType {
  306. case TLVFLOAT64:
  307. return float64(value.(float64))
  308. case TLVFLOAT32:
  309. return float32(value.(float64))
  310. case TLVINT8:
  311. return int8(value.(float64))
  312. case TLVINT16:
  313. return int16(value.(float64))
  314. case TLVINT32:
  315. return int32(value.(float64))
  316. case TLVINT64:
  317. return int64(value.(float64))
  318. case TLVUINT8:
  319. return uint8(value.(float64))
  320. case TLVUINT16:
  321. return uint16(value.(float64))
  322. case TLVUINT32:
  323. return uint32(value.(float64))
  324. case TLVUINT64:
  325. return uint64(value.(float64))
  326. case TLVBYTES:
  327. return []byte(value.(string))
  328. case TLVSTRING:
  329. return value.(string)
  330. default:
  331. return nil
  332. }
  333. }