Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1514)

Delta Between Two Patch Sets: src/compress/zlib/reader.go

Issue 97140043: code review 97140043: compress/flate: add Reset() to allow reusing large buffers to compress multipl
Left Patch Set: diff -r e473e77e84ff https://code.google.com/p/go Created 9 years, 10 months ago
Right Patch Set: diff -r b91b31b57771240403a02a9257fbf8f0c6ea5f09 https://code.google.com/p/go Created 9 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/compress/gzip/gunzip.go ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 /* 5 /*
6 Package zlib implements reading and writing of zlib format compressed data, 6 Package zlib implements reading and writing of zlib format compressed data,
7 as specified in RFC 1950. 7 as specified in RFC 1950.
8 8
9 The implementation provides filters that uncompress during reading 9 The implementation provides filters that uncompress during reading
10 and compress during writing. For example, to write compressed data 10 and compress during writing. For example, to write compressed data
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 ) 44 )
45 45
46 type reader struct { 46 type reader struct {
47 r flate.Reader 47 r flate.Reader
48 decompressor io.ReadCloser 48 decompressor io.ReadCloser
49 digest hash.Hash32 49 digest hash.Hash32
50 err error 50 err error
51 scratch [4]byte 51 scratch [4]byte
52 } 52 }
53 53
54 // NewReader creates a new io.ReadCloser. 54 // Resetter resets a ReadCloser returned by NewReader or NewReaderDict to
55 // Reads from the returned io.ReadCloser read and decompress data from r. 55 // to switch to a new underlying Reader. This permits reusing a ReadCloser
56 // instead of allocating a new one.
57 type Resetter interface {
58 » // Reset discards any buffered data and resets the Resetter as if it was
59 » // newly initialized with the given reader.
60 » Reset(r io.Reader, dict []byte) error
61 }
62
63 // NewReader creates a new ReadCloser.
64 // Reads from the returned ReadCloser read and decompress data from r.
56 // The implementation buffers input and may read more data than necessary from r . 65 // The implementation buffers input and may read more data than necessary from r .
57 // It is the caller's responsibility to call Close on the ReadCloser when done. 66 // It is the caller's responsibility to call Close on the ReadCloser when done.
67 //
68 // The ReadCloser returned by NewReader also implements Resetter.
58 func NewReader(r io.Reader) (io.ReadCloser, error) { 69 func NewReader(r io.Reader) (io.ReadCloser, error) {
59 return NewReaderDict(r, nil) 70 return NewReaderDict(r, nil)
60 } 71 }
61 72
62 // NewReaderDict is like NewReader but uses a preset dictionary. 73 // NewReaderDict is like NewReader but uses a preset dictionary.
63 // NewReaderDict ignores the dictionary if the compressed data does not refer to it. 74 // NewReaderDict ignores the dictionary if the compressed data does not refer to it.
64 // If the compressed data refers to a different dictionary, NewReaderDict return s ErrDictionary. 75 // If the compressed data refers to a different dictionary, NewReaderDict return s ErrDictionary.
76 //
77 // The ReadCloser returned by NewReaderDict also implements Resetter.
65 func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) { 78 func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) {
66 z := new(reader) 79 z := new(reader)
67 » if fr, ok := r.(flate.Reader); ok { 80 » err := z.Reset(r, dict)
68 » » z.r = fr
69 » } else {
70 » » z.r = bufio.NewReader(r)
71 » }
72 » _, err := io.ReadFull(z.r, z.scratch[0:2])
73 if err != nil { 81 if err != nil {
74 return nil, err 82 return nil, err
75 } 83 }
76 h := uint(z.scratch[0])<<8 | uint(z.scratch[1])
77 if (z.scratch[0]&0x0f != zlibDeflate) || (h%31 != 0) {
78 return nil, ErrHeader
79 }
80 if z.scratch[1]&0x20 != 0 {
81 _, err = io.ReadFull(z.r, z.scratch[0:4])
82 if err != nil {
83 return nil, err
84 }
85 checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
86 if checksum != adler32.Checksum(dict) {
87 return nil, ErrDictionary
88 }
89 z.decompressor = flate.NewReaderDict(z.r, dict)
90 } else {
91 z.decompressor = flate.NewReader(z.r)
92 }
93 z.digest = adler32.New()
94 return z, nil 84 return z, nil
95 } 85 }
96 86
97 func (z *reader) Read(p []byte) (n int, err error) { 87 func (z *reader) Read(p []byte) (n int, err error) {
98 if z.err != nil { 88 if z.err != nil {
99 return 0, z.err 89 return 0, z.err
100 } 90 }
101 if len(p) == 0 { 91 if len(p) == 0 {
102 return 0, nil 92 return 0, nil
103 } 93 }
(...skipping 20 matching lines...) Expand all
124 } 114 }
125 115
126 // Calling Close does not close the wrapped io.Reader originally passed to NewRe ader. 116 // Calling Close does not close the wrapped io.Reader originally passed to NewRe ader.
127 func (z *reader) Close() error { 117 func (z *reader) Close() error {
128 if z.err != nil { 118 if z.err != nil {
129 return z.err 119 return z.err
130 } 120 }
131 z.err = z.decompressor.Close() 121 z.err = z.decompressor.Close()
132 return z.err 122 return z.err
133 } 123 }
124
125 func (z *reader) Reset(r io.Reader, dict []byte) error {
126 if fr, ok := r.(flate.Reader); ok {
127 z.r = fr
128 } else {
129 z.r = bufio.NewReader(r)
130 }
131 _, err := io.ReadFull(z.r, z.scratch[0:2])
132 if err != nil {
133 return err
134 }
135 h := uint(z.scratch[0])<<8 | uint(z.scratch[1])
136 if (z.scratch[0]&0x0f != zlibDeflate) || (h%31 != 0) {
137 return ErrHeader
138 }
139 haveDict := z.scratch[1]&0x20 != 0
140 if haveDict {
141 _, err = io.ReadFull(z.r, z.scratch[0:4])
142 if err != nil {
143 return err
144 }
145 checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
146 if checksum != adler32.Checksum(dict) {
147 return ErrDictionary
148 }
149 }
150 if z.decompressor == nil {
151 if haveDict {
152 z.decompressor = flate.NewReaderDict(z.r, dict)
153 } else {
154 z.decompressor = flate.NewReader(z.r)
155 }
156 } else {
157 z.decompressor.(flate.Resetter).Reset(z.r, dict)
158 }
159 z.digest = adler32.New()
160 return nil
161 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b