Advertisement
Guest User

Untitled

a guest
Jul 21st, 2019
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.96 KB | None | 0 0
  1. package bits
  2.  
  3. import (
  4. "fmt"
  5. "strings"
  6. )
  7.  
  8. const (
  9. blen = 8
  10. Invalid = -1
  11. )
  12.  
  13. type Bits struct {
  14. buf []byte
  15. }
  16.  
  17. func New(buf []byte) (*Bits, error) {
  18. if len(buf) == 0 {
  19. return nil, fmt.Errorf("can not create a Bits from an empty buffer")
  20. }
  21. return &Bits{buf}, nil
  22. }
  23.  
  24. func (b Bits) Len() int {
  25. return len(b.buf) * blen
  26. }
  27.  
  28. func (b Bits) String() string {
  29. parts := make([]string, len(b.buf))
  30. for i, v := range b.buf {
  31. parts[i] = fmt.Sprintf("%0*b", blen, v)
  32. }
  33. return strings.Join(parts, "")
  34. }
  35.  
  36. func (b *Bits) RotateLeft(c int) error {
  37. if c <= 0 {
  38. return fmt.Errorf("can not rotate with c <= 0")
  39. }
  40. return nil
  41. }
  42.  
  43. func (b *Bits) RotateRight(c int) error {
  44. if c <= 0 {
  45. return fmt.Errorf("can not rotate with c <= 0")
  46. }
  47. return nil
  48. }
  49.  
  50. func (b Bits) GetBit(pos int) (int64, error) {
  51. if pos < 0 || pos > b.Len() {
  52. return Invalid, fmt.Errorf("invalid position %d", pos)
  53. } else {
  54. ix, off := pos/blen, pos%blen
  55. val := int64(b.buf[ix]) & (128 >> uint(off))
  56. return val >> uint(blen-off-1), nil
  57. }
  58. }
  59.  
  60. func (b Bits) GetBits(pos, length int, swap bool) (int64, error) {
  61. if pos < 0 || pos-length > b.Len() {
  62. return Invalid, fmt.Errorf("invalid position %d", pos)
  63. }
  64. switch length {
  65. case 0:
  66. return Invalid, fmt.Errorf("length must be greater than 0")
  67. case 1:
  68. return b.GetBit(pos)
  69. default:
  70. var sum int64
  71.  
  72. s := pos / blen
  73. e := s + ((length + (length % blen)) / blen)
  74. d := length - blen
  75. buf := b.buf[s:e]
  76.  
  77. if swap {
  78. mid, mod := len(buf)/2, len(buf)%2
  79. if mod%2 != 0 {
  80. return Invalid, fmt.Errorf("can not swap")
  81. }
  82. tmp := make([]byte, len(buf), len(buf))
  83. for _, b := range buf {
  84. tmp[mid] = b
  85. mid++
  86. if mid >= len(buf) {
  87. mid = 0
  88. }
  89. }
  90. buf = tmp
  91. }
  92.  
  93. for i, v := range buf {
  94. m := int64((1 << uint(d)) - 1)
  95. d = length - d
  96.  
  97. sum += (int64(v) & m) << uint(8*(len(buf)-i-1))
  98. }
  99. return sum, nil
  100. }
  101. }
  102.  
  103. //Uint returns a big endian integer from Bits.
  104. func (b Bits) Uint(pos, length int) int64 {
  105. if v, err := b.GetBits(pos, length, false); err != nil {
  106. return Invalid
  107. } else {
  108. return v
  109. }
  110. }
  111.  
  112. //UintLe returns an unsigned little endian integer from Bits.
  113. func (b Bits) UintLe(pos, length int) int64 {
  114. if v, err := b.GetBits(pos, length, true); err != nil {
  115. return Invalid
  116. } else {
  117. return v
  118. }
  119. }
  120.  
  121. //Int returns a big endian Integer from Bits.
  122. func (b Bits) Int(pos, length int) int64 {
  123. if v, err := b.GetBits(pos, length, false); err != nil {
  124. return Invalid
  125. } else {
  126. if b.IsSet(pos) {
  127. v = (1<<uint(length) - 1) + ^v
  128. }
  129. return v
  130. }
  131. }
  132.  
  133. //IntLe returns a little endian integer from Bits.
  134. func (b Bits) IntLe(pos, length int) int64 {
  135. if v, err := b.GetBits(pos, length, true); err != nil {
  136. return Invalid
  137. } else {
  138. if b.IsSet(pos) {
  139. v = (1<<uint(length) - 1) + ^v
  140. }
  141. return v
  142. }
  143. }
  144.  
  145. func (b Bits) IsSet(pos int) bool {
  146. if v, err := b.GetBit(pos); err != nil {
  147. return false
  148. } else {
  149. return v == 1
  150. }
  151. }
  152.  
  153. func (b Bits) AreSets(pos ...int) bool {
  154. for _, p := range pos {
  155. if !b.IsSet(p) {
  156. return false
  157. }
  158. }
  159. return true
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement