tlv.go 7.6 KB

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