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

Delta Between Two Patch Sets: src/pkg/archive/tar/reader.go

Issue 6700047: code review 6700047: archive/tar: read/write extended pax/gnu tar archives (Closed)
Left Patch Set: diff -r 1399878c6731 https://code.google.com/p/go Created 11 years, 2 months ago
Right Patch Set: diff -r 439cb8bad388 https://code.google.com/p/go Created 11 years, 1 month 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/archive/tar/common.go ('k') | src/pkg/archive/tar/reader_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 package tar 5 package tar
6 6
7 // TODO(dsymonds): 7 // TODO(dsymonds):
8 // - pax extensions 8 // - pax extensions
9 9
10 import ( 10 import (
(...skipping 10 matching lines...) Expand all
21 var ( 21 var (
22 ErrHeader = errors.New("archive/tar: invalid tar header") 22 ErrHeader = errors.New("archive/tar: invalid tar header")
23 ) 23 )
24 24
25 const maxNanoSecondIntSize = 9 25 const maxNanoSecondIntSize = 9
26 26
27 // A Reader provides sequential access to the contents of a tar archive. 27 // A Reader provides sequential access to the contents of a tar archive.
28 // A tar archive consists of a sequence of files. 28 // A tar archive consists of a sequence of files.
29 // The Next method advances to the next file in the archive (including the first ), 29 // The Next method advances to the next file in the archive (including the first ),
30 // and then it can be treated as an io.Reader to access the file's data. 30 // and then it can be treated as an io.Reader to access the file's data.
31 //
32 // Example:
33 // tr := tar.NewReader(r)
34 // for {
35 // hdr, err := tr.Next()
36 // if err == io.EOF {
37 // // end of tar archive
38 // break
39 // }
40 // if err != nil {
41 // // handle error
42 // }
43 // io.Copy(data, tr)
44 // }
45 type Reader struct { 31 type Reader struct {
46 r io.Reader 32 r io.Reader
47 err error 33 err error
48 nb int64 // number of unread bytes for current file entry 34 nb int64 // number of unread bytes for current file entry
49 pad int64 // amount of padding (ignored) after current file entry 35 pad int64 // amount of padding (ignored) after current file entry
50 } 36 }
51 37
52 // NewReader creates a new Reader reading from r. 38 // NewReader creates a new Reader reading from r.
53 func NewReader(r io.Reader) *Reader { return &Reader{r: r} } 39 func NewReader(r io.Reader) *Reader { return &Reader{r: r} }
54 40
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 if pos == -1 { 155 if pos == -1 {
170 seconds, err = strconv.ParseInt(t, 10, 0) 156 seconds, err = strconv.ParseInt(t, 10, 0)
171 if err != nil { 157 if err != nil {
172 return time.Time{}, err 158 return time.Time{}, err
173 } 159 }
174 } else { 160 } else {
175 seconds, err = strconv.ParseInt(string(buf[:pos]), 10, 0) 161 seconds, err = strconv.ParseInt(string(buf[:pos]), 10, 0)
176 if err != nil { 162 if err != nil {
177 return time.Time{}, err 163 return time.Time{}, err
178 } 164 }
179 nano_buf := string(buf[pos+1:]) 165 nano_buf := string(buf[pos+1:])
rsc 2013/01/09 19:43:49 nanoBuf
shanemhansen 2013/01/11 01:52:42 Done.
180 // Pad as needed before converting to a decimal. 166 // Pad as needed before converting to a decimal.
181 // For example .030 -> .030000000 -> 30000000 nanoseconds 167 // For example .030 -> .030000000 -> 30000000 nanoseconds
182 if len(nano_buf) < maxNanoSecondIntSize { 168 if len(nano_buf) < maxNanoSecondIntSize {
183 // Right pad 169 // Right pad
184 nano_buf += strings.Repeat("0", maxNanoSecondIntSize-len (nano_buf)) 170 nano_buf += strings.Repeat("0", maxNanoSecondIntSize-len (nano_buf))
185 } else if len(nano_buf) > maxNanoSecondIntSize { 171 } else if len(nano_buf) > maxNanoSecondIntSize {
186 // Right truncate 172 // Right truncate
187 nano_buf = nano_buf[:maxNanoSecondIntSize] 173 nano_buf = nano_buf[:maxNanoSecondIntSize]
188 } 174 }
189 nanoseconds, err = strconv.ParseInt(string(nano_buf), 10, 0) 175 nanoseconds, err = strconv.ParseInt(string(nano_buf), 10, 0)
(...skipping 13 matching lines...) Expand all
203 return nil, err 189 return nil, err
204 } 190 }
205 headers := make(map[string]string) 191 headers := make(map[string]string)
206 // Each record is constructed as 192 // Each record is constructed as
207 // "%d %s=%s\n", length, keyword, value 193 // "%d %s=%s\n", length, keyword, value
208 for len(buf) > 0 { 194 for len(buf) > 0 {
209 // or the header was empty to start with. 195 // or the header was empty to start with.
210 var sp int 196 var sp int
211 // The size field ends at the first space. 197 // The size field ends at the first space.
212 sp = bytes.IndexByte(buf, ' ') 198 sp = bytes.IndexByte(buf, ' ')
213 if sp == -1 { 199 if sp == -1 {
rsc 2013/01/09 19:43:49 sp < 0
shanemhansen 2013/01/11 01:52:42 Done.
214 return nil, ErrHeader 200 return nil, ErrHeader
215 } 201 }
216 // Parse the first token as a decimal integer. 202 // Parse the first token as a decimal integer.
217 n, err := strconv.ParseInt(string(buf[:sp]), 10, 0) 203 n, err := strconv.ParseInt(string(buf[:sp]), 10, 0)
218 if err != nil { 204 if err != nil {
219 return nil, ErrHeader 205 return nil, ErrHeader
220 } 206 }
221 // Extract everything between the decimal and the n -1 on the 207 // Extract everything between the decimal and the n -1 on the
222 // beginning to to eat the ' ', -1 on the end to skip the newlin e. 208 // beginning to to eat the ' ', -1 on the end to skip the newlin e.
223 var record []byte 209 var record []byte
224 record, buf = buf[sp+1:n-1], buf[n:] 210 record, buf = buf[sp+1:n-1], buf[n:]
225 // The first equals is guaranteed to mark the end of the key. 211 // The first equals is guaranteed to mark the end of the key.
226 // Everything else is value. 212 // Everything else is value.
227 eq := bytes.IndexByte(record, '=') 213 eq := bytes.IndexByte(record, '=')
228 if eq == -1 { 214 if eq == -1 {
rsc 2013/01/09 19:43:49 eq < 0
shanemhansen 2013/01/11 01:52:42 Done.
229 return nil, ErrHeader 215 return nil, ErrHeader
230 } 216 }
231 key, value := record[:eq], record[eq+1:] 217 key, value := record[:eq], record[eq+1:]
232 headers[string(key)] = string(value) 218 headers[string(key)] = string(value)
233 } 219 }
234 return headers, nil 220 return headers, nil
235 } 221 }
236 222
237 // cString parses bytes as a NUL-terminated C-style string. 223 // cString parses bytes as a NUL-terminated C-style string.
238 // If a NUL byte is not found then the whole slice is returned as a string. 224 // If a NUL byte is not found then the whole slice is returned as a string.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 } 385 }
400 n, err = tr.r.Read(b) 386 n, err = tr.r.Read(b)
401 tr.nb -= int64(n) 387 tr.nb -= int64(n)
402 388
403 if err == io.EOF && tr.nb > 0 { 389 if err == io.EOF && tr.nb > 0 {
404 err = io.ErrUnexpectedEOF 390 err = io.ErrUnexpectedEOF
405 } 391 }
406 tr.err = err 392 tr.err = err
407 return 393 return
408 } 394 }
LEFTRIGHT

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