1 // Copyright 2016 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 5 package flate 6 7 import ( 8 "bytes" 9 "strings" 10 "testing" 11 ) 12 13 func TestDictDecoder(t *testing.T) { 14 const ( 15 abc = "ABC\n" 16 fox = "The quick brown fox jumped over the lazy dog!\n" 17 poem = "The Road Not Taken\nRobert Frost\n" + 18 "\n" + 19 "Two roads diverged in a yellow wood,\n" + 20 "And sorry I could not travel both\n" + 21 "And be one traveler, long I stood\n" + 22 "And looked down one as far as I could\n" + 23 "To where it bent in the undergrowth;\n" + 24 "\n" + 25 "Then took the other, as just as fair,\n" + 26 "And having perhaps the better claim,\n" + 27 "Because it was grassy and wanted wear;\n" + 28 "Though as for that the passing there\n" + 29 "Had worn them really about the same,\n" + 30 "\n" + 31 "And both that morning equally lay\n" + 32 "In leaves no step had trodden black.\n" + 33 "Oh, I kept the first for another day!\n" + 34 "Yet knowing how way leads on to way,\n" + 35 "I doubted if I should ever come back.\n" + 36 "\n" + 37 "I shall be telling this with a sigh\n" + 38 "Somewhere ages and ages hence:\n" + 39 "Two roads diverged in a wood, and I-\n" + 40 "I took the one less traveled by,\n" + 41 "And that has made all the difference.\n" 42 ) 43 44 var poemRefs = []struct { 45 dist int // Backward distance (0 if this is an insertion) 46 length int // Length of copy or insertion 47 }{ 48 {0, 38}, {33, 3}, {0, 48}, {79, 3}, {0, 11}, {34, 5}, {0, 6}, {23, 7}, 49 {0, 8}, {50, 3}, {0, 2}, {69, 3}, {34, 5}, {0, 4}, {97, 3}, {0, 4}, 50 {43, 5}, {0, 6}, {7, 4}, {88, 7}, {0, 12}, {80, 3}, {0, 2}, {141, 4}, 51 {0, 1}, {196, 3}, {0, 3}, {157, 3}, {0, 6}, {181, 3}, {0, 2}, {23, 3}, 52 {77, 3}, {28, 5}, {128, 3}, {110, 4}, {70, 3}, {0, 4}, {85, 6}, {0, 2}, 53 {182, 6}, {0, 4}, {133, 3}, {0, 7}, {47, 5}, {0, 20}, {112, 5}, {0, 1}, 54 {58, 3}, {0, 8}, {59, 3}, {0, 4}, {173, 3}, {0, 5}, {114, 3}, {0, 4}, 55 {92, 5}, {0, 2}, {71, 3}, {0, 2}, {76, 5}, {0, 1}, {46, 3}, {96, 4}, 56 {130, 4}, {0, 3}, {360, 3}, {0, 3}, {178, 5}, {0, 7}, {75, 3}, {0, 3}, 57 {45, 6}, {0, 6}, {299, 6}, {180, 3}, {70, 6}, {0, 1}, {48, 3}, {66, 4}, 58 {0, 3}, {47, 5}, {0, 9}, {325, 3}, {0, 1}, {359, 3}, {318, 3}, {0, 2}, 59 {199, 3}, {0, 1}, {344, 3}, {0, 3}, {248, 3}, {0, 10}, {310, 3}, {0, 3}, 60 {93, 6}, {0, 3}, {252, 3}, {157, 4}, {0, 2}, {273, 5}, {0, 14}, {99, 4}, 61 {0, 1}, {464, 4}, {0, 2}, {92, 4}, {495, 3}, {0, 1}, {322, 4}, {16, 4}, 62 {0, 3}, {402, 3}, {0, 2}, {237, 4}, {0, 2}, {432, 4}, {0, 1}, {483, 5}, 63 {0, 2}, {294, 4}, {0, 2}, {306, 3}, {113, 5}, {0, 1}, {26, 4}, {164, 3}, 64 {488, 4}, {0, 1}, {542, 3}, {248, 6}, {0, 5}, {205, 3}, {0, 8}, {48, 3}, 65 {449, 6}, {0, 2}, {192, 3}, {328, 4}, {9, 5}, {433, 3}, {0, 3}, {622, 25}, 66 {615, 5}, {46, 5}, {0, 2}, {104, 3}, {475, 10}, {549, 3}, {0, 4}, {597, 8}, 67 {314, 3}, {0, 1}, {473, 6}, {317, 5}, {0, 1}, {400, 3}, {0, 3}, {109, 3}, 68 {151, 3}, {48, 4}, {0, 4}, {125, 3}, {108, 3}, {0, 2}, 69 } 70 71 var got, want bytes.Buffer 72 var dd dictDecoder 73 dd.init(1<<11, nil) 74 75 var writeCopy = func(dist, length int) { 76 for length > 0 { 77 cnt := dd.tryWriteCopy(dist, length) 78 if cnt == 0 { 79 cnt = dd.writeCopy(dist, length) 80 } 81 82 length -= cnt 83 if dd.availWrite() == 0 { 84 got.Write(dd.readFlush()) 85 } 86 } 87 } 88 var writeString = func(str string) { 89 for len(str) > 0 { 90 cnt := copy(dd.writeSlice(), str) 91 str = str[cnt:] 92 dd.writeMark(cnt) 93 if dd.availWrite() == 0 { 94 got.Write(dd.readFlush()) 95 } 96 } 97 } 98 99 writeString(".") 100 want.WriteByte('.') 101 102 str := poem 103 for _, ref := range poemRefs { 104 if ref.dist == 0 { 105 writeString(str[:ref.length]) 106 } else { 107 writeCopy(ref.dist, ref.length) 108 } 109 str = str[ref.length:] 110 } 111 want.WriteString(poem) 112 113 writeCopy(dd.histSize(), 33) 114 want.Write(want.Bytes()[:33]) 115 116 writeString(abc) 117 writeCopy(len(abc), 59*len(abc)) 118 want.WriteString(strings.Repeat(abc, 60)) 119 120 writeString(fox) 121 writeCopy(len(fox), 9*len(fox)) 122 want.WriteString(strings.Repeat(fox, 10)) 123 124 writeString(".") 125 writeCopy(1, 9) 126 want.WriteString(strings.Repeat(".", 10)) 127 128 writeString(strings.ToUpper(poem)) 129 writeCopy(len(poem), 7*len(poem)) 130 want.WriteString(strings.Repeat(strings.ToUpper(poem), 8)) 131 132 writeCopy(dd.histSize(), 10) 133 want.Write(want.Bytes()[want.Len()-dd.histSize():][:10]) 134 135 got.Write(dd.readFlush()) 136 if got.String() != want.String() { 137 t.Errorf("final string mismatch:\ngot %q\nwant %q", got.String(), want.String()) 138 } 139 } 140