예제 #1
0
func (enc *Compressor) Write(in []byte) (n int, er error) {
	for n < len(in) {
		enc.handle.next_in = (*C.uint8_t)(unsafe.Pointer(&in[n]))
		enc.handle.avail_in = C.size_t(len(in) - n)
		enc.handle.next_out = (*C.uint8_t)(unsafe.Pointer(&enc.buffer[0]))
		enc.handle.avail_out = C.size_t(len(enc.buffer))

		ret := C.lzma_code(enc.handle, C.lzma_action(Run))
		switch Errno(ret) {
		case Ok:
			break
		default:
			er = Errno(ret)
		}

		n = len(in) - int(enc.handle.avail_in)
		// Write back result.
		produced := len(enc.buffer) - int(enc.handle.avail_out)
		_, er = enc.writer.Write(enc.buffer[:produced])
		if er != nil {
			// Short write.
			return
		}
	}
	return
}
예제 #2
0
파일: reader.go 프로젝트: robxu9/xzgo
func (r *Decompressor) Read(out []byte) (out_count int, er error) {
	if r.offset == len(r.buffer) {
		var n int
		n, er = r.rd.Read(r.buffer)
		if n == 0 {
			return 0, er
		}
		r.offset = 0
		r.handle.next_in = (*C.uint8_t)(unsafe.Pointer(&r.buffer[0]))
		r.handle.avail_in = C.size_t(n)
	}

	r.handle.next_out = (*C.uint8_t)(unsafe.Pointer(&out[0]))
	r.handle.avail_out = C.size_t(len(out))

	ret := C.lzma_code(&r.handle, C.lzma_action(Run))
	switch Errno(ret) {
	case Ok:
		break
	case StreamEnd:
		er = io.EOF
	default:
		er = Errno(ret)
	}

	r.offset = len(r.buffer) - int(r.handle.avail_in)

	return len(out) - int(r.handle.avail_out), er
}
예제 #3
0
func (enc *Compressor) Flush() error {
	enc.handle.avail_in = 0

	for {
		enc.handle.next_out = (*C.uint8_t)(unsafe.Pointer(&enc.buffer[0]))
		enc.handle.avail_out = C.size_t(len(enc.buffer))
		ret := C.lzma_code(enc.handle, C.lzma_action(Finish))

		// Write back result.
		produced := len(enc.buffer) - int(enc.handle.avail_out)
		to_write := bytes.NewBuffer(enc.buffer[:produced])
		_, er := io.Copy(enc.writer, to_write)
		if er != nil {
			// Short write.
			return er
		}

		if Errno(ret) == StreamEnd {
			return nil
		}
	}
	panic("unreachable")
}