summaryrefslogtreecommitdiff
path: root/src/lib/compress/gzip/gunzip.go
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-06-09 09:53:44 -0700
committerRob Pike <r@golang.org>2009-06-09 09:53:44 -0700
commit7249ea4df2b4f12a4e7ed446f270cea87e4ffd34 (patch)
tree7032a11d0cac2ae4d3e90f7a189b575b5a50f848 /src/lib/compress/gzip/gunzip.go
parentacf6ef7a82b3fe61516a1bac4563706552bdf078 (diff)
downloadgolang-7249ea4df2b4f12a4e7ed446f270cea87e4ffd34.tar.gz
mv src/lib to src/pkg
tests: all.bash passes, gobuild still works, godoc still works. R=rsc OCL=30096 CL=30102
Diffstat (limited to 'src/lib/compress/gzip/gunzip.go')
-rw-r--r--src/lib/compress/gzip/gunzip.go236
1 files changed, 0 insertions, 236 deletions
diff --git a/src/lib/compress/gzip/gunzip.go b/src/lib/compress/gzip/gunzip.go
deleted file mode 100644
index 32cc3ecb0..000000000
--- a/src/lib/compress/gzip/gunzip.go
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The gzip package implements reading (and eventually writing) of
-// gzip format compressed files, as specified in RFC 1952.
-package gzip
-
-import (
- "bufio";
- "compress/flate";
- "hash";
- "hash/crc32";
- "io";
- "os";
-)
-
-const (
- gzipID1 = 0x1f;
- gzipID2 = 0x8b;
-
- gzipDeflate = 8;
-
- flagText = 1<<0;
- flagHdrCrc = 1<<1;
- flagExtra = 1<<2;
- flagName = 1<<3;
- flagComment = 1<<4;
-)
-
-func makeReader(r io.Reader) flate.Reader {
- if rr, ok := r.(flate.Reader); ok {
- return rr;
- }
- return bufio.NewReader(r);
-}
-
-var HeaderError os.Error = os.ErrorString("invalid gzip header")
-var ChecksumError os.Error = os.ErrorString("gzip checksum error")
-
-// A GzipInflater is an io.Reader that can be read to retrieve
-// uncompressed data from a gzip-format compressed file.
-// The gzip file stores a header giving metadata about the compressed file.
-// That header is exposed as the fields of the GzipInflater struct.
-//
-// In general, a gzip file can be a concatenation of gzip files,
-// each with its own header. Reads from the GzipInflater
-// return the concatenation of the uncompressed data of each.
-// Only the first header is recorded in the GzipInflater fields.
-//
-// Gzip files store a length and checksum of the uncompressed data.
-// The GzipInflater will return a ChecksumError when Read
-// reaches the end of the uncompressed data if it does not
-// have the expected length or checksum. Clients should treat data
-// returned by Read as tentative until they receive the successful
-// (zero length, nil error) Read marking the end of the data.
-type GzipInflater struct {
- Comment string; // comment
- Extra []byte; // "extra data"
- Mtime uint32; // modification time (seconds since January 1, 1970)
- Name string; // file name
- OS byte; // operating system type
-
- r flate.Reader;
- inflater io.Reader;
- digest hash.Hash32;
- size uint32;
- flg byte;
- buf [512]byte;
- err os.Error;
- eof bool;
-}
-
-func (z *GzipInflater) readHeader(save bool) os.Error
-
-// NewGzipInflater creates a new GzipInflater reading the given reader.
-// The implementation buffers input and may read more data than necessary from r.
-func NewGzipInflater(r io.Reader) (*GzipInflater, os.Error) {
- z := new(GzipInflater);
- z.r = makeReader(r);
- z.digest = crc32.NewIEEE();
- if err := z.readHeader(true); err != nil {
- z.err = err;
- return nil, err;
- }
- return z, nil;
-}
-
-func get4(p []byte) uint32 {
- return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24;
-}
-
-func (z *GzipInflater) readString() (string, os.Error) {
- var err os.Error;
- for i := 0;; i++ {
- if i >= len(z.buf) {
- return "", HeaderError;
- }
- z.buf[i], err = z.r.ReadByte();
- if err != nil {
- return "", err;
- }
- if z.buf[i] == 0 {
- return string(z.buf[0:i]), nil;
- }
- }
- panic("not reached");
-}
-
-func (z *GzipInflater) read2() (uint32, os.Error) {
- _, err := z.r.Read(z.buf[0:2]);
- if err != nil {
- return 0, err;
- }
- return uint32(z.buf[0]) | uint32(z.buf[1])<<8, nil;
-}
-
-func (z *GzipInflater) readHeader(save bool) os.Error {
- n, err := io.FullRead(z.r, z.buf[0:10]);
- if err != nil {
- if n != 0 && err == io.ErrEOF {
- return HeaderError;
- }
- return err;
- }
- if z.buf[0] != gzipID1 || z.buf[1] != gzipID2 || z.buf[2] != gzipDeflate {
- return HeaderError;
- }
- z.flg = z.buf[3];
- if save {
- z.Mtime = get4(z.buf[4:8]);
- // z.buf[8] is xfl, ignored
- z.OS = z.buf[9];
- }
- z.digest.Reset();
- z.digest.Write(z.buf[0:10]);
-
- if z.flg & flagExtra != 0{
- n, err := z.read2();
- if err != nil {
- return err;
- }
- data := make([]byte, n);
- var nn int;
- if nn, err = io.FullRead(z.r, data); err != nil {
- return err;
- }
- if save {
- z.Extra = data;
- }
- }
-
- var s string;
- if z.flg & flagName != 0 {
- if s, err = z.readString(); err != nil {
- return err;
- }
- if save {
- z.Name = s;
- }
- }
-
- if z.flg & flagComment != 0 {
- if s, err = z.readString(); err != nil {
- return err;
- }
- if save {
- z.Comment = s;
- }
- }
-
- if z.flg & flagHdrCrc != 0 {
- n, err := z.read2();
- if err != nil {
- return err;
- }
- sum := z.digest.Sum32() & 0xFFFF;
- if n != sum {
- return HeaderError;
- }
- }
-
- z.digest.Reset();
- z.inflater = flate.NewInflater(z.r);
- return nil;
-}
-
-func (z *GzipInflater) Read(p []byte) (n int, err os.Error) {
- if z.err != nil {
- return 0, z.err;
- }
- if z.eof || len(p) == 0 {
- return 0, nil;
- }
-
- n, err = z.inflater.Read(p);
- z.digest.Write(p[0:n]);
- z.size += uint32(n);
- if n != 0 || err != nil {
- z.err = err;
- return;
- }
-
- // Finished file; check checksum + size.
- if _, err := io.FullRead(z.r, z.buf[0:8]); err != nil {
- z.err = err;
- return 0, err;
- }
- if err != nil {
- z.err = err;
- return 0, err;
- }
- crc32, isize := get4(z.buf[0:4]), get4(z.buf[4:8]);
- sum := z.digest.Sum32();
- if sum != crc32 || isize != z.size {
- z.err = ChecksumError;
- return 0, z.err;
- }
-
- // File is ok; is there another?
- switch err = z.readHeader(false); {
- case err == io.ErrEOF:
- err = nil;
- z.eof = true;
- return;
- case err != nil:
- z.err = err;
- return;
- }
-
- // Yes. Reset and read from it.
- z.digest.Reset();
- z.size = 0;
- return z.Read(p);
-}
-