binaryutil.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2018 Google LLC. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package binaryutil contains convenience wrappers around encoding/binary.
  15. package binaryutil
  16. import (
  17. "bytes"
  18. "encoding/binary"
  19. "unsafe"
  20. )
  21. // ByteOrder is like binary.ByteOrder, but allocates memory and returns byte
  22. // slices, for convenience.
  23. type ByteOrder interface {
  24. PutUint16(v uint16) []byte
  25. PutUint32(v uint32) []byte
  26. PutUint64(v uint64) []byte
  27. Uint16(b []byte) uint16
  28. Uint32(b []byte) uint32
  29. Uint64(b []byte) uint64
  30. }
  31. // NativeEndian is either little endian or big endian, depending on the native
  32. // endian-ness, and allocates memory and returns byte slices, for convenience.
  33. var NativeEndian ByteOrder = &nativeEndian{}
  34. type nativeEndian struct{}
  35. func (nativeEndian) PutUint16(v uint16) []byte {
  36. buf := make([]byte, 2)
  37. *(*uint16)(unsafe.Pointer(&buf[0])) = v
  38. return buf
  39. }
  40. func (nativeEndian) PutUint32(v uint32) []byte {
  41. buf := make([]byte, 4)
  42. *(*uint32)(unsafe.Pointer(&buf[0])) = v
  43. return buf
  44. }
  45. func (nativeEndian) PutUint64(v uint64) []byte {
  46. buf := make([]byte, 8)
  47. *(*uint64)(unsafe.Pointer(&buf[0])) = v
  48. return buf
  49. }
  50. func (nativeEndian) Uint16(b []byte) uint16 {
  51. return *(*uint16)(unsafe.Pointer(&b[0]))
  52. }
  53. func (nativeEndian) Uint32(b []byte) uint32 {
  54. return *(*uint32)(unsafe.Pointer(&b[0]))
  55. }
  56. func (nativeEndian) Uint64(b []byte) uint64 {
  57. return *(*uint64)(unsafe.Pointer(&b[0]))
  58. }
  59. // BigEndian is like binary.BigEndian, but allocates memory and returns byte
  60. // slices, for convenience.
  61. var BigEndian ByteOrder = &bigEndian{}
  62. type bigEndian struct{}
  63. func (bigEndian) PutUint16(v uint16) []byte {
  64. buf := make([]byte, 2)
  65. binary.BigEndian.PutUint16(buf, v)
  66. return buf
  67. }
  68. func (bigEndian) PutUint32(v uint32) []byte {
  69. buf := make([]byte, 4)
  70. binary.BigEndian.PutUint32(buf, v)
  71. return buf
  72. }
  73. func (bigEndian) PutUint64(v uint64) []byte {
  74. buf := make([]byte, 8)
  75. binary.BigEndian.PutUint64(buf, v)
  76. return buf
  77. }
  78. func (bigEndian) Uint16(b []byte) uint16 {
  79. return binary.BigEndian.Uint16(b)
  80. }
  81. func (bigEndian) Uint32(b []byte) uint32 {
  82. return binary.BigEndian.Uint32(b)
  83. }
  84. func (bigEndian) Uint64(b []byte) uint64 {
  85. return binary.BigEndian.Uint64(b)
  86. }
  87. // For dealing with types not supported by the encoding/binary interface
  88. func PutInt32(v int32) []byte {
  89. buf := make([]byte, 4)
  90. *(*int32)(unsafe.Pointer(&buf[0])) = v
  91. return buf
  92. }
  93. func Int32(b []byte) int32 {
  94. return *(*int32)(unsafe.Pointer(&b[0]))
  95. }
  96. func PutString(s string) []byte {
  97. return []byte(s)
  98. }
  99. func String(b []byte) string {
  100. return string(bytes.TrimRight(b, "\x00"))
  101. }