Source file src/compress/gzip/example_test.go

     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 gzip_test
     6  
     7  import (
     8  	"bytes"
     9  	"compress/gzip"
    10  	"fmt"
    11  	"io"
    12  	"log"
    13  	"net/http"
    14  	"net/http/httptest"
    15  	"os"
    16  	"strings"
    17  	"time"
    18  )
    19  
    20  func Example_writerReader() {
    21  	var buf bytes.Buffer
    22  	zw := gzip.NewWriter(&buf)
    23  
    24  	// Setting the Header fields is optional.
    25  	zw.Name = "a-new-hope.txt"
    26  	zw.Comment = "an epic space opera by George Lucas"
    27  	zw.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
    28  
    29  	_, err := zw.Write([]byte("A long time ago in a galaxy far, far away..."))
    30  	if err != nil {
    31  		log.Fatal(err)
    32  	}
    33  
    34  	if err := zw.Close(); err != nil {
    35  		log.Fatal(err)
    36  	}
    37  
    38  	zr, err := gzip.NewReader(&buf)
    39  	if err != nil {
    40  		log.Fatal(err)
    41  	}
    42  
    43  	fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())
    44  
    45  	if _, err := io.Copy(os.Stdout, zr); err != nil {
    46  		log.Fatal(err)
    47  	}
    48  
    49  	if err := zr.Close(); err != nil {
    50  		log.Fatal(err)
    51  	}
    52  
    53  	// Output:
    54  	// Name: a-new-hope.txt
    55  	// Comment: an epic space opera by George Lucas
    56  	// ModTime: 1977-05-25 00:00:00 +0000 UTC
    57  	//
    58  	// A long time ago in a galaxy far, far away...
    59  }
    60  
    61  func ExampleReader_Multistream() {
    62  	var buf bytes.Buffer
    63  	zw := gzip.NewWriter(&buf)
    64  
    65  	var files = []struct {
    66  		name    string
    67  		comment string
    68  		modTime time.Time
    69  		data    string
    70  	}{
    71  		{"file-1.txt", "file-header-1", time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC), "Hello Gophers - 1"},
    72  		{"file-2.txt", "file-header-2", time.Date(2007, time.March, 2, 4, 5, 6, 1, time.UTC), "Hello Gophers - 2"},
    73  	}
    74  
    75  	for _, file := range files {
    76  		zw.Name = file.name
    77  		zw.Comment = file.comment
    78  		zw.ModTime = file.modTime
    79  
    80  		if _, err := zw.Write([]byte(file.data)); err != nil {
    81  			log.Fatal(err)
    82  		}
    83  
    84  		if err := zw.Close(); err != nil {
    85  			log.Fatal(err)
    86  		}
    87  
    88  		zw.Reset(&buf)
    89  	}
    90  
    91  	zr, err := gzip.NewReader(&buf)
    92  	if err != nil {
    93  		log.Fatal(err)
    94  	}
    95  
    96  	for {
    97  		zr.Multistream(false)
    98  		fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())
    99  
   100  		if _, err := io.Copy(os.Stdout, zr); err != nil {
   101  			log.Fatal(err)
   102  		}
   103  
   104  		fmt.Print("\n\n")
   105  
   106  		err = zr.Reset(&buf)
   107  		if err == io.EOF {
   108  			break
   109  		}
   110  		if err != nil {
   111  			log.Fatal(err)
   112  		}
   113  	}
   114  
   115  	if err := zr.Close(); err != nil {
   116  		log.Fatal(err)
   117  	}
   118  
   119  	// Output:
   120  	// Name: file-1.txt
   121  	// Comment: file-header-1
   122  	// ModTime: 2006-02-01 03:04:05 +0000 UTC
   123  	//
   124  	// Hello Gophers - 1
   125  	//
   126  	// Name: file-2.txt
   127  	// Comment: file-header-2
   128  	// ModTime: 2007-03-02 04:05:06 +0000 UTC
   129  	//
   130  	// Hello Gophers - 2
   131  }
   132  
   133  func Example_compressingReader() {
   134  	// This is an example of writing a compressing reader.
   135  	// This can be useful for an HTTP client body, as shown.
   136  
   137  	const testdata = "the data to be compressed"
   138  
   139  	// This HTTP handler is just for testing purposes.
   140  	handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
   141  		zr, err := gzip.NewReader(req.Body)
   142  		if err != nil {
   143  			log.Fatal(err)
   144  		}
   145  
   146  		// Just output the data for the example.
   147  		if _, err := io.Copy(os.Stdout, zr); err != nil {
   148  			log.Fatal(err)
   149  		}
   150  	})
   151  	ts := httptest.NewServer(handler)
   152  	defer ts.Close()
   153  
   154  	// The remainder is the example code.
   155  
   156  	// The data we want to compress, as an io.Reader
   157  	dataReader := strings.NewReader(testdata)
   158  
   159  	// bodyReader is the body of the HTTP request, as an io.Reader.
   160  	// httpWriter is the body of the HTTP request, as an io.Writer.
   161  	bodyReader, httpWriter := io.Pipe()
   162  
   163  	// Make sure that bodyReader is always closed, so that the
   164  	// goroutine below will always exit.
   165  	defer bodyReader.Close()
   166  
   167  	// gzipWriter compresses data to httpWriter.
   168  	gzipWriter := gzip.NewWriter(httpWriter)
   169  
   170  	// errch collects any errors from the writing goroutine.
   171  	errch := make(chan error, 1)
   172  
   173  	go func() {
   174  		defer close(errch)
   175  		sentErr := false
   176  		sendErr := func(err error) {
   177  			if !sentErr {
   178  				errch <- err
   179  				sentErr = true
   180  			}
   181  		}
   182  
   183  		// Copy our data to gzipWriter, which compresses it to
   184  		// gzipWriter, which feeds it to bodyReader.
   185  		if _, err := io.Copy(gzipWriter, dataReader); err != nil && err != io.ErrClosedPipe {
   186  			sendErr(err)
   187  		}
   188  		if err := gzipWriter.Close(); err != nil && err != io.ErrClosedPipe {
   189  			sendErr(err)
   190  		}
   191  		if err := httpWriter.Close(); err != nil && err != io.ErrClosedPipe {
   192  			sendErr(err)
   193  		}
   194  	}()
   195  
   196  	// Send an HTTP request to the test server.
   197  	req, err := http.NewRequest("PUT", ts.URL, bodyReader)
   198  	if err != nil {
   199  		log.Fatal(err)
   200  	}
   201  
   202  	// Note that passing req to http.Client.Do promises that it
   203  	// will close the body, in this case bodyReader.
   204  	resp, err := ts.Client().Do(req)
   205  	if err != nil {
   206  		log.Fatal(err)
   207  	}
   208  
   209  	// Check whether there was an error compressing the data.
   210  	if err := <-errch; err != nil {
   211  		log.Fatal(err)
   212  	}
   213  
   214  	// For this example we don't care about the response.
   215  	resp.Body.Close()
   216  
   217  	// Output: the data to be compressed
   218  }
   219  

View as plain text