// Calling Close does not close the wrapped io.Writer originally // passed to NewWriterX. func (z *Writer) Close() error { if z.err != nil { return z.err } z.write(nil, Z_FINISH) if z.err != nil { return z.err } C.deflateEnd(&z.strm) z.err = io.EOF return nil }
// this is the main function: it advances the write with either // new data or something else to do, like a flush func (z *Writer) write(p []byte, flush int) int { if len(p) == 0 { z.strm.next_in = (*C.Bytef)(unsafe.Pointer(nil)) z.strm.avail_in = 0 } else { z.strm.next_in = (*C.Bytef)(unsafe.Pointer(&p[0])) z.strm.avail_in = (C.uInt)(len(p)) } // we loop until we don't get a full output buffer // each loop completely writes the output buffer to the underlying // writer for { // deflate one buffer z.strm.next_out = (*C.Bytef)(unsafe.Pointer(&z.out[0])) z.strm.avail_out = (C.uInt)(len(z.out)) ret := C.deflate(&z.strm, (C.int)(flush)) if ret == Z_STREAM_ERROR { // all the other error cases are normal, // and this should never happen panic(fmt.Errorf("cgzip: Unexpected error (1)")) } // write everything from := 0 have := len(z.out) - int(z.strm.avail_out) for have > 0 { var n int n, z.err = z.w.Write(z.out[from:have]) if z.err != nil { C.deflateEnd(&z.strm) return 0 } from += n have -= n } // we stop trying if we get a partial response if z.strm.avail_out != 0 { break } } // the library guarantees this if z.strm.avail_in != 0 { panic(fmt.Errorf("cgzip: Unexpected error (2)")) } return len(p) }