Update to gobook@27cf7b490526a0a0751ff12ed7cc4acd8afa2edc

This commit is contained in:
Alan Donovan 2015-12-06 11:23:30 -05:00
parent 34cd1719c0
commit b7e11892d0
4 changed files with 33 additions and 28 deletions

View File

@ -3,9 +3,10 @@
// See page 12. // See page 12.
// Dup3 prints the count and text of lines that appear more than once
// in the named input files.
//!+ //!+
// Dup3 prints the count and text of lines that
// appear more than once in the named input files.
package main package main
import ( import (

View File

@ -4,7 +4,7 @@
// See page 16. // See page 16.
//!+ //!+
// Fetch prints the content found at a URL. // Fetch prints the content found at each specified URL.
package main package main
import ( import (

View File

@ -2,6 +2,14 @@
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ // License: https://creativecommons.org/licenses/by-nc-sa/4.0/
// See page 362. // See page 362.
//
// The version of this program that appeared in the first and second
// printings did not comply with the proposed rules for passing
// pointers between Go and C, described here:
// https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md
//
// The version below, which appears in the third printing,
// has been corrected. See bzip2.go for explanation.
//!+ //!+
/* This file is gopl.io/ch13/bzip/bzip2.c, */ /* This file is gopl.io/ch13/bzip/bzip2.c, */
@ -17,12 +25,7 @@ int bz2compress(bz_stream *s, int action,
int r = BZ2_bzCompress(s, action); int r = BZ2_bzCompress(s, action);
*inlen -= s->avail_in; *inlen -= s->avail_in;
*outlen -= s->avail_out; *outlen -= s->avail_out;
s->next_in = s->next_out = NULL;
/* "C code may store a Go pointer in C memory subject to rule 2:
* it must stop storing the pointer before it returns to Go." */
s->next_in = NULL;
s->next_out = NULL;
return r; return r;
} }

View File

@ -2,19 +2,23 @@
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ // License: https://creativecommons.org/licenses/by-nc-sa/4.0/
// See page 362. // See page 362.
// The version of this file that appears in the book does not comply
// with the proposed rules for passing pointers between Go and C.
// (https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md)
// The rules forbid a C function like bz2compress from storing 'in' and
// 'out' (pointers to variables allocated by Go) into the Go variable 's',
// even temporarily.
// //
// To comply with the rules, the bz_stream variable must be allocated // The version of this program that appeared in the first and second
// by C code. We have introduced two C functions, bz2alloc and // printings did not comply with the proposed rules for passing
// bz2free, to allocate and free instances of the bz_stream type. // pointers between Go and C, described here:
// Also, we have changed bz2compress so that before it returns, it // https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md
// clears the fields of the bz_stream that contain point to Go //
// variables. // The rules forbid a C function like bz2compress from storing 'in'
// and 'out' (pointers to variables allocated by Go) into the Go
// variable 's', even temporarily.
//
// The version below, which appears in the third printing, has been
// corrected. To comply with the rules, the bz_stream variable must
// be allocated by C code. We have introduced two C functions,
// bz2alloc and bz2free, to allocate and free instances of the
// bz_stream type. Also, we have changed bz2compress so that before
// it returns, it clears the fields of the bz_stream that contain
// pointers to Go variables.
//!+ //!+
@ -26,11 +30,10 @@ package bzip
#cgo LDFLAGS: -L/usr/lib -lbz2 #cgo LDFLAGS: -L/usr/lib -lbz2
#include <bzlib.h> #include <bzlib.h>
#include <stdlib.h> #include <stdlib.h>
bz_stream* bz2alloc() { return calloc(1, sizeof(bz_stream)); } bz_stream* bz2alloc() { return calloc(1, sizeof(bz_stream)); }
int bz2compress(bz_stream *s, int action, int bz2compress(bz_stream *s, int action,
char *in, unsigned *inlen, char *out, unsigned *outlen); char *in, unsigned *inlen, char *out, unsigned *outlen);
void bz2free(bz_stream* s) { return free(s); } void bz2free(bz_stream* s) { free(s); }
*/ */
import "C" import "C"
@ -47,11 +50,9 @@ type writer struct {
// NewWriter returns a writer for bzip2-compressed streams. // NewWriter returns a writer for bzip2-compressed streams.
func NewWriter(out io.Writer) io.WriteCloser { func NewWriter(out io.Writer) io.WriteCloser {
const ( const blockSize = 9
blockSize = 9 const verbosity = 0
verbosity = 0 const workFactor = 30
workFactor = 30
)
w := &writer{w: out, stream: C.bz2alloc()} w := &writer{w: out, stream: C.bz2alloc()}
C.BZ2_bzCompressInit(w.stream, blockSize, verbosity, workFactor) C.BZ2_bzCompressInit(w.stream, blockSize, verbosity, workFactor)
return w return w