reader_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package lzw
  5. import (
  6. "bytes"
  7. "io"
  8. "io/ioutil"
  9. "runtime"
  10. "strconv"
  11. "strings"
  12. "testing"
  13. )
  14. type lzwTest struct {
  15. desc string
  16. raw string
  17. compressed string
  18. err error
  19. }
  20. var lzwTests = []lzwTest{
  21. {
  22. "empty;LSB;8",
  23. "",
  24. "\x01\x01",
  25. nil,
  26. },
  27. {
  28. "empty;MSB;8",
  29. "",
  30. "\x80\x80",
  31. nil,
  32. },
  33. {
  34. "tobe;LSB;7",
  35. "TOBEORNOTTOBEORTOBEORNOT",
  36. "\x54\x4f\x42\x45\x4f\x52\x4e\x4f\x54\x82\x84\x86\x8b\x85\x87\x89\x81",
  37. nil,
  38. },
  39. {
  40. "tobe;LSB;8",
  41. "TOBEORNOTTOBEORTOBEORNOT",
  42. "\x54\x9e\x08\x29\xf2\x44\x8a\x93\x27\x54\x04\x12\x34\xb8\xb0\xe0\xc1\x84\x01\x01",
  43. nil,
  44. },
  45. {
  46. "tobe;MSB;7",
  47. "TOBEORNOTTOBEORTOBEORNOT",
  48. "\x54\x4f\x42\x45\x4f\x52\x4e\x4f\x54\x82\x84\x86\x8b\x85\x87\x89\x81",
  49. nil,
  50. },
  51. {
  52. "tobe;MSB;8",
  53. "TOBEORNOTTOBEORTOBEORNOT",
  54. "\x2a\x13\xc8\x44\x52\x79\x48\x9c\x4f\x2a\x40\xa0\x90\x68\x5c\x16\x0f\x09\x80\x80",
  55. nil,
  56. },
  57. {
  58. "tobe-truncated;LSB;8",
  59. "TOBEORNOTTOBEORTOBEORNOT",
  60. "\x54\x9e\x08\x29\xf2\x44\x8a\x93\x27\x54\x04",
  61. io.ErrUnexpectedEOF,
  62. },
  63. // This example comes from http://en.wikipedia.org/wiki/Graphics_Interchange_Format.
  64. {
  65. "gif;LSB;8",
  66. "\x28\xff\xff\xff\x28\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
  67. "\x00\x51\xfc\x1b\x28\x70\xa0\xc1\x83\x01\x01",
  68. nil,
  69. },
  70. // This example comes from http://compgroups.net/comp.lang.ruby/Decompressing-LZW-compression-from-PDF-file
  71. {
  72. "pdf;MSB;8",
  73. "-----A---B",
  74. "\x80\x0b\x60\x50\x22\x0c\x0c\x85\x01",
  75. nil,
  76. },
  77. }
  78. func TestReader(t *testing.T) {
  79. var b bytes.Buffer
  80. for _, tt := range lzwTests {
  81. d := strings.Split(tt.desc, ";")
  82. var order Order
  83. switch d[1] {
  84. case "LSB":
  85. order = LSB
  86. case "MSB":
  87. order = MSB
  88. default:
  89. t.Errorf("%s: bad order %q", tt.desc, d[1])
  90. }
  91. litWidth, _ := strconv.Atoi(d[2])
  92. rc := NewReader(strings.NewReader(tt.compressed), order, litWidth)
  93. defer rc.Close()
  94. b.Reset()
  95. n, err := io.Copy(&b, rc)
  96. if err != nil {
  97. if err != tt.err {
  98. t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
  99. }
  100. continue
  101. }
  102. s := b.String()
  103. if s != tt.raw {
  104. t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
  105. }
  106. }
  107. }
  108. func benchmarkDecoder(b *testing.B, n int) {
  109. b.StopTimer()
  110. b.SetBytes(int64(n))
  111. buf0, err := ioutil.ReadFile("../testdata/e.txt")
  112. if err != nil {
  113. b.Fatal(err)
  114. }
  115. if len(buf0) == 0 {
  116. b.Fatalf("test file has no data")
  117. }
  118. compressed := new(bytes.Buffer)
  119. w := NewWriter(compressed, LSB, 8)
  120. for i := 0; i < n; i += len(buf0) {
  121. if len(buf0) > n-i {
  122. buf0 = buf0[:n-i]
  123. }
  124. w.Write(buf0)
  125. }
  126. w.Close()
  127. buf1 := compressed.Bytes()
  128. buf0, compressed, w = nil, nil, nil
  129. runtime.GC()
  130. b.StartTimer()
  131. for i := 0; i < b.N; i++ {
  132. io.Copy(ioutil.Discard, NewReader(bytes.NewReader(buf1), LSB, 8))
  133. }
  134. }
  135. func BenchmarkDecoder1e4(b *testing.B) {
  136. benchmarkDecoder(b, 1e4)
  137. }
  138. func BenchmarkDecoder1e5(b *testing.B) {
  139. benchmarkDecoder(b, 1e5)
  140. }
  141. func BenchmarkDecoder1e6(b *testing.B) {
  142. benchmarkDecoder(b, 1e6)
  143. }