github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/runtime/pprof/internal/gzip0/gzip0.go (about)

     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 gzip0 implements writing of uncompressed (compression level 0) gzip files.
     6  // The data in the files is uncompressed but still framed and checksummed,
     7  // protecting against undetected corruption or truncation.
     8  package gzip0
     9  
    10  import "io"
    11  
    12  // A Writer is an io.WriteCloser.
    13  // Writes to a Writer are written to w in uncompressed gzip format.
    14  type Writer struct {
    15  	started bool
    16  	w       io.Writer
    17  	buf     [32]byte
    18  	size    int64
    19  	crc32   uint32
    20  	err     error
    21  }
    22  
    23  // NewWriter returns a new Writer.
    24  // Writes to the returned Writer are written to w in uncompressed gzip format.
    25  //
    26  // It is the caller's responsibility to call Close on the WriteCloser when done.
    27  // Writes may be buffered and not flushed until Close.
    28  func NewWriter(w io.Writer) *Writer {
    29  	return &Writer{w: w}
    30  }
    31  
    32  // buffer returns a temporary slice holding the given data,
    33  // to use as the argument of a w.w.Write call.
    34  func (w *Writer) buffer(data ...byte) []byte {
    35  	copy(w.buf[:len(data)], data)
    36  	return w.buf[:len(data)]
    37  }
    38  
    39  // start writes the gzip header if it hasn't been written yet.
    40  func (w *Writer) start() error {
    41  	if w.err != nil {
    42  		return w.err
    43  	}
    44  	if w.started {
    45  		return nil
    46  	}
    47  	w.started = true
    48  	_, w.err = w.w.Write(w.buffer(0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff))
    49  	return w.err
    50  }
    51  
    52  // Write writes a compressed form of p to the underlying io.Writer. The
    53  // compressed bytes are not necessarily flushed until the Writer is closed.
    54  func (w *Writer) Write(b []byte) (int, error) {
    55  	if err := w.start(); err != nil {
    56  		return 0, err
    57  	}
    58  	total := len(b)
    59  	for len(b) > 0 {
    60  		n := len(b)
    61  		if n > 0xffff {
    62  			n = 0xffff
    63  		}
    64  		_, w.err = w.w.Write(w.buffer(0x00, byte(n), byte(n>>8), ^byte(n), ^byte(n>>8)))
    65  		if w.err != nil {
    66  			return total - len(b), w.err
    67  		}
    68  		n, w.err = w.w.Write(b[:n])
    69  		w.size += int64(n)
    70  		w.crc32 = updateCRC32(w.crc32, b[:n])
    71  		b = b[n:]
    72  		if w.err != nil {
    73  			return total - len(b), w.err
    74  		}
    75  	}
    76  	return total, nil
    77  }
    78  
    79  // Close closes the Writer, flushing any unwritten data to the underlying
    80  // io.Writer, but does not close the underlying io.Writer.
    81  func (w *Writer) Close() error {
    82  	if err := w.start(); err != nil {
    83  		return err
    84  	}
    85  	_, w.err = w.w.Write(w.buffer(0x01, 0x00, 0x00, 0xff, 0xff, byte(w.crc32), byte(w.crc32>>8), byte(w.crc32>>16), byte(w.crc32>>24), byte(w.size), byte(w.size>>8), byte(w.size>>16), byte(w.size>>24)))
    86  	if w.err != nil {
    87  		return w.err
    88  	}
    89  	return nil
    90  }
    91  
    92  func updateCRC32(crc uint32, p []byte) uint32 {
    93  	crc = ^crc
    94  	for _, v := range p {
    95  		crc = crctab[byte(crc)^v] ^ (crc >> 8)
    96  	}
    97  	return ^crc
    98  }
    99  
   100  var crctab = [256]uint32{
   101  	/*
   102  	   package main
   103  
   104  	   import "fmt"
   105  
   106  	   func main() {
   107  	   	const poly = 0xedb88320
   108  	   	for i := 0; i < 256; i++ {
   109  	   		crc := uint32(i)
   110  	   		for j := 0; j < 8; j++ {
   111  	   			if crc&1 == 1 {
   112  	   				crc = (crc >> 1) ^ poly
   113  	   			} else {
   114  	   				crc >>= 1
   115  	   			}
   116  	   		}
   117  	   		fmt.Printf("%#08x, ", crc)
   118  	   		if i%8 == 7 {
   119  	   			fmt.Printf("\n")
   120  	   		}
   121  	   	}
   122  	   }
   123  	*/
   124  	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
   125  	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
   126  	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
   127  	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
   128  	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
   129  	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
   130  	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
   131  	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
   132  	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
   133  	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
   134  	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
   135  	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
   136  	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
   137  	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
   138  	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
   139  	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
   140  	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
   141  	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
   142  	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
   143  	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
   144  	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
   145  	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
   146  	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
   147  	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
   148  	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
   149  	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
   150  	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
   151  	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
   152  	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
   153  	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
   154  	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
   155  	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
   156  }