decode_test.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package lz4
  2. import (
  3. "bytes"
  4. "encoding/base64"
  5. "strings"
  6. "testing"
  7. )
  8. func unbase64(in string) []byte {
  9. p, err := base64.StdEncoding.DecodeString(in)
  10. if err != nil {
  11. panic(err)
  12. }
  13. return p
  14. }
  15. func TestBlockDecode(t *testing.T) {
  16. appendLen := func(p []byte, size int) []byte {
  17. for size > 0xFF {
  18. p = append(p, 0xFF)
  19. size -= 0xFF
  20. }
  21. p = append(p, byte(size))
  22. return p
  23. }
  24. emitSeq := func(lit string, offset uint16, matchLen int) []byte {
  25. var b byte
  26. litLen := len(lit)
  27. if litLen < 15 {
  28. b = byte(litLen << 4)
  29. litLen = -1
  30. } else {
  31. b = 0xF0
  32. litLen -= 15
  33. }
  34. if matchLen < 4 || offset == 0 {
  35. out := []byte{b}
  36. if litLen >= 0 {
  37. out = appendLen(out, litLen)
  38. }
  39. return append(out, lit...)
  40. }
  41. matchLen -= 4
  42. if matchLen < 15 {
  43. b |= byte(matchLen)
  44. matchLen = -1
  45. } else {
  46. b |= 0x0F
  47. matchLen -= 15
  48. }
  49. out := []byte{b}
  50. if litLen >= 0 {
  51. out = appendLen(out, litLen)
  52. }
  53. if len(lit) > 0 {
  54. out = append(out, lit...)
  55. }
  56. out = append(out, byte(offset), byte(offset>>8))
  57. if matchLen >= 0 {
  58. out = appendLen(out, matchLen)
  59. }
  60. return out
  61. }
  62. concat := func(in ...[]byte) []byte {
  63. var p []byte
  64. for _, b := range in {
  65. p = append(p, b...)
  66. }
  67. return p
  68. }
  69. tests := []struct {
  70. name string
  71. src []byte
  72. exp []byte
  73. }{
  74. {
  75. "literal_only_short",
  76. emitSeq("hello", 0, 0),
  77. []byte("hello"),
  78. },
  79. {
  80. "literal_only_long",
  81. emitSeq(strings.Repeat("A", 15+255+255+1), 0, 0),
  82. bytes.Repeat([]byte("A"), 15+255+255+1),
  83. },
  84. {
  85. "literal_only_long_1",
  86. emitSeq(strings.Repeat("A", 15), 0, 0),
  87. bytes.Repeat([]byte("A"), 15),
  88. },
  89. {
  90. "repeat_match_len",
  91. emitSeq("a", 1, 4),
  92. []byte("aaaaa"),
  93. },
  94. {
  95. "repeat_match_len_2_seq",
  96. concat(emitSeq("a", 1, 4), emitSeq("B", 1, 4)),
  97. []byte("aaaaaBBBBB"),
  98. },
  99. {
  100. "long_match",
  101. emitSeq("A", 1, 16),
  102. bytes.Repeat([]byte("A"), 17),
  103. },
  104. {
  105. "repeat_match_log_len_2_seq",
  106. concat(emitSeq("a", 1, 15), emitSeq("B", 1, 15), emitSeq("end", 0, 0)),
  107. []byte(strings.Repeat("a", 16) + strings.Repeat("B", 16) + "end"),
  108. },
  109. }
  110. for _, test := range tests {
  111. t.Run(test.name, func(t *testing.T) {
  112. buf := make([]byte, len(test.exp))
  113. n := decodeBlock(buf, test.src)
  114. if n <= 0 {
  115. t.Log(-n)
  116. }
  117. if !bytes.Equal(buf, test.exp) {
  118. t.Fatalf("expected %q got %q", test.exp, buf)
  119. }
  120. })
  121. }
  122. }