gitea

Development moved to Codeberg

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
  101. 101
  102. 102
  103. 103
  104. 104
  105. 105
  106. 106
  107. 107
  108. 108
  109. 109
  110. 110
  111. 111
  112. 112
  113. 113
  114. 114
  115. 115
  116. 116
  117. 117
  118. 118
  119. 119
package rardecode

import "io"

type bitReader interface {
	readBits(n uint) (int, error) // read n bits of data
	unreadBits(n uint)            // revert the reading of the last n bits read
}

type limitedBitReader struct {
	br  bitReader
	n   int
	err error // error to return if br returns EOF before all n bits have been read
}

// limitBitReader returns a bitReader that reads from br and stops with io.EOF after n bits.
// If br returns an io.EOF before reading n bits, err is returned.
func limitBitReader(br bitReader, n int, err error) bitReader {
	return &limitedBitReader{br, n, err}
}

func (l *limitedBitReader) readBits(n uint) (int, error) {
	if int(n) > l.n {
		return 0, io.EOF
	}
	v, err := l.br.readBits(n)
	if err == nil {
		l.n -= int(n)
	} else if err == io.EOF {
		err = l.err
	}
	return v, err
}

func (l *limitedBitReader) unreadBits(n uint) {
	l.n += int(n)
	l.br.unreadBits(n)
}

// rarBitReader wraps an io.ByteReader to perform various bit and byte
// reading utility functions used in RAR file processing.
type rarBitReader struct {
	r io.ByteReader
	v int
	n uint
}

func (r *rarBitReader) reset(br io.ByteReader) {
	r.r = br
	r.n = 0
	r.v = 0
}

func (r *rarBitReader) readBits(n uint) (int, error) {
	for n > r.n {
		c, err := r.r.ReadByte()
		if err != nil {
			return 0, err
		}
		r.v = r.v<<8 | int(c)
		r.n += 8
	}
	r.n -= n
	return (r.v >> r.n) & ((1 << n) - 1), nil
}

func (r *rarBitReader) unreadBits(n uint) {
	r.n += n
}

// alignByte aligns the current bit reading input to the next byte boundary.
func (r *rarBitReader) alignByte() {
	r.n -= r.n % 8
}

// readUint32 reads a RAR V3 encoded uint32
func (r *rarBitReader) readUint32() (uint32, error) {
	n, err := r.readBits(2)
	if err != nil {
		return 0, err
	}
	if n != 1 {
		n, err = r.readBits(4 << uint(n))
		return uint32(n), err
	}
	n, err = r.readBits(4)
	if err != nil {
		return 0, err
	}
	if n == 0 {
		n, err = r.readBits(8)
		n |= -1 << 8
		return uint32(n), err
	}
	nlow, err := r.readBits(4)
	n = n<<4 | nlow
	return uint32(n), err
}

func (r *rarBitReader) ReadByte() (byte, error) {
	n, err := r.readBits(8)
	return byte(n), err
}

// readFull reads len(p) bytes into p. If fewer bytes are read an error is returned.
func (r *rarBitReader) readFull(p []byte) error {
	for i := range p {
		c, err := r.ReadByte()
		if err != nil {
			return err
		}
		p[i] = c
	}
	return nil
}

func newRarBitReader(r io.ByteReader) *rarBitReader {
	return &rarBitReader{r: r}
}