ggstd 0.1.0

Partial implementation of Go standard library
Documentation
// // Copyright 2010 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.

// package gzip

// import (
// 	"compress/flate"
// 	"errors"
// 	"fmt"
// 	"hash/crc32"
// 	"io"
// 	"time"
// )

// // These constants are copied from the flate package, so that code that imports
// // "compress/gzip" does not also have to import "compress/flate".
// const (
// 	NoCompression      = flate.NoCompression
// 	BestSpeed          = flate.BestSpeed
// 	BestCompression    = flate.BestCompression
// 	DefaultCompression = flate.DefaultCompression
// 	HuffmanOnly        = flate.HuffmanOnly
// )

// // A Writer is an io.WriteCloser.
// // Writes to a Writer are compressed and written to w.
// type Writer struct {
// 	Header      // written at first call to Write, Flush, or Close
// 	w           io.Writer
// 	level       int
// 	wroteHeader bool
// 	compressor  *flate.Writer
// 	digest      uint32 // CRC-32, IEEE polynomial (section 8)
// 	size        uint32 // Uncompressed size (section 2.3.1)
// 	closed      bool
// 	buf         [10]byte
// 	err         error
// }

// // NewWriter returns a new Writer.
// // Writes to the returned writer are compressed and written to w.
// //
// // It is the caller's responsibility to call Close on the Writer when done.
// // Writes may be buffered and not flushed until Close.
// //
// // Callers that wish to set the fields in Writer.Header must do so before
// // the first call to Write, Flush, or Close.
// func NewWriter(w io.Writer) *Writer {
// 	z, _ := NewWriterLevel(w, DefaultCompression)
// 	return z
// }

// // NewWriterLevel is like NewWriter but specifies the compression level instead
// // of assuming DefaultCompression.
// //
// // The compression level can be DefaultCompression, NoCompression, HuffmanOnly
// // or any integer value between BestSpeed and BestCompression inclusive.
// // The error returned will be nil if the level is valid.
// func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
// 	if level < HuffmanOnly || level > BestCompression {
// 		return nil, fmt.Errorf("gzip: invalid compression level: %d", level)
// 	}
// 	z := new(Writer)
// 	z.init(w, level)
// 	return z, nil
// }

// func (z *Writer) init(w io.Writer, level int) {
// 	compressor := z.compressor
// 	if compressor != nil {
// 		compressor.Reset(w)
// 	}
// 	*z = Writer{
// 		Header: Header{
// 			OS: 255, // unknown
// 		},
// 		w:          w,
// 		level:      level,
// 		compressor: compressor,
// 	}
// }

// // Reset discards the Writer z's state and makes it equivalent to the
// // result of its original state from NewWriter or NewWriterLevel, but
// // writing to w instead. This permits reusing a Writer rather than
// // allocating a new one.
// func (z *Writer) Reset(w io.Writer) {
// 	z.init(w, z.level)
// }

// // writeBytes writes a length-prefixed byte slice to z.w.
// func (z *Writer) writeBytes(b []byte) error {
// 	if len(b) > 0xffff {
// 		return errors.New("gzip.Write: Extra data is too large")
// 	}
// 	le.PutUint16(z.buf[:2], uint16(len(b)))
// 	_, err := z.w.Write(z.buf[:2])
// 	if err != nil {
// 		return err
// 	}
// 	_, err = z.w.Write(b)
// 	return err
// }

// // writeString writes a UTF-8 string s in GZIP's format to z.w.
// // GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).
// func (z *Writer) writeString(s string) (err error) {
// 	// GZIP stores Latin-1 strings; error if non-Latin-1; convert if non-ASCII.
// 	needconv := false
// 	for _, v := range s {
// 		if v == 0 || v > 0xff {
// 			return errors.New("gzip.Write: non-Latin-1 header string")
// 		}
// 		if v > 0x7f {
// 			needconv = true
// 		}
// 	}
// 	if needconv {
// 		b := make([]byte, 0, len(s))
// 		for _, v := range s {
// 			b = append(b, byte(v))
// 		}
// 		_, err = z.w.Write(b)
// 	} else {
// 		_, err = io.WriteString(z.w, s)
// 	}
// 	if err != nil {
// 		return err
// 	}
// 	// GZIP strings are NUL-terminated.
// 	z.buf[0] = 0
// 	_, err = z.w.Write(z.buf[:1])
// 	return err
// }

// // Write writes a compressed form of p to the underlying io.Writer. The
// // compressed bytes are not necessarily flushed until the Writer is closed.
// func (z *Writer) Write(p []byte) (int, error) {
// 	if z.err != nil {
// 		return 0, z.err
// 	}
// 	var n int
// 	// Write the GZIP header lazily.
// 	if !z.wroteHeader {
// 		z.wroteHeader = true
// 		z.buf = [10]byte{0: gzipID1, 1: gzipID2, 2: gzipDeflate}
// 		if z.Extra != nil {
// 			z.buf[3] |= 0x04
// 		}
// 		if z.Name != "" {
// 			z.buf[3] |= 0x08
// 		}
// 		if z.Comment != "" {
// 			z.buf[3] |= 0x10
// 		}
// 		if z.ModTime.After(time.Unix(0, 0)) {
// 			// Section 2.3.1, the zero value for MTIME means that the
// 			// modified time is not set.
// 			le.PutUint32(z.buf[4:8], uint32(z.ModTime.Unix()))
// 		}
// 		if z.level == BestCompression {
// 			z.buf[8] = 2
// 		} else if z.level == BestSpeed {
// 			z.buf[8] = 4
// 		}
// 		z.buf[9] = z.OS
// 		_, z.err = z.w.Write(z.buf[:10])
// 		if z.err != nil {
// 			return 0, z.err
// 		}
// 		if z.Extra != nil {
// 			z.err = z.writeBytes(z.Extra)
// 			if z.err != nil {
// 				return 0, z.err
// 			}
// 		}
// 		if z.Name != "" {
// 			z.err = z.writeString(z.Name)
// 			if z.err != nil {
// 				return 0, z.err
// 			}
// 		}
// 		if z.Comment != "" {
// 			z.err = z.writeString(z.Comment)
// 			if z.err != nil {
// 				return 0, z.err
// 			}
// 		}
// 		if z.compressor == nil {
// 			z.compressor, _ = flate.NewWriter(z.w, z.level)
// 		}
// 	}
// 	z.size += uint32(len(p))
// 	z.digest = crc32.Update(z.digest, crc32.IEEETable, p)
// 	n, z.err = z.compressor.Write(p)
// 	return n, z.err
// }

// // Flush flushes any pending compressed data to the underlying writer.
// //
// // It is useful mainly in compressed network protocols, to ensure that
// // a remote reader has enough data to reconstruct a packet. Flush does
// // not return until the data has been written. If the underlying
// // writer returns an error, Flush returns that error.
// //
// // In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.
// func (z *Writer) Flush() error {
// 	if z.err != nil {
// 		return z.err
// 	}
// 	if z.closed {
// 		return nil
// 	}
// 	if !z.wroteHeader {
// 		z.Write(nil)
// 		if z.err != nil {
// 			return z.err
// 		}
// 	}
// 	z.err = z.compressor.Flush()
// 	return z.err
// }

// // Close closes the Writer by flushing any unwritten data to the underlying
// // io.Writer and writing the GZIP footer.
// // It does not close the underlying io.Writer.
// func (z *Writer) Close() error {
// 	if z.err != nil {
// 		return z.err
// 	}
// 	if z.closed {
// 		return nil
// 	}
// 	z.closed = true
// 	if !z.wroteHeader {
// 		z.Write(nil)
// 		if z.err != nil {
// 			return z.err
// 		}
// 	}
// 	z.err = z.compressor.Close()
// 	if z.err != nil {
// 		return z.err
// 	}
// 	le.PutUint32(z.buf[:4], z.digest)
// 	le.PutUint32(z.buf[4:8], z.size)
// 	_, z.err = z.w.Write(z.buf[:8])
// 	return z.err
// }