// Return exit code, number of bits written func (this *BlockCompressor) call() (int, uint64) { var msg string printOut("Input file name set to '"+this.inputName+"'", this.verbose) printOut("Output file name set to '"+this.outputName+"'", this.verbose) msg = fmt.Sprintf("Block size set to %d bytes", this.blockSize) printOut(msg, this.verbose) msg = fmt.Sprintf("Verbose set to %t", this.verbose) printOut(msg, this.verbose) msg = fmt.Sprintf("Overwrite set to %t", this.overwrite) printOut(msg, this.verbose) msg = fmt.Sprintf("Checksum set to %t", this.checksum) printOut(msg, this.verbose) w1 := "no" if this.transform != "NONE" { w1 = this.transform } msg = fmt.Sprintf("Using %s transform (stage 1)", w1) printOut(msg, this.verbose) w2 := "no" if this.entropyCodec != "NONE" { w2 = this.entropyCodec } msg = fmt.Sprintf("Using %s entropy codec (stage 2)", w2) printOut(msg, this.verbose) prefix := "" if this.jobs > 1 { prefix = "s" } msg = fmt.Sprintf("Using %d job%s", this.jobs, prefix) printOut(msg, this.verbose) written := uint64(0) var output *os.File var bos kanzi.OutputStream if strings.ToUpper(this.outputName) != "NONE" { var err error output, err = os.OpenFile(this.outputName, os.O_RDWR, 666) if err == nil { // File exists output.Close() if this.overwrite == false { fmt.Print("The output file exists and the 'overwrite' command ") fmt.Println("line option has not been provided") return io.ERR_OVERWRITE_FILE, written } } output, err = os.Create(this.outputName) if err != nil { fmt.Printf("Cannot open output file '%v' for writing: %v\n", this.outputName, err) return io.ERR_CREATE_FILE, written } defer output.Close() bos, err = io.NewBufferedOutputStream(output) if err != nil { fmt.Printf("Cannot create compressed stream: %s\n", err.Error()) return io.ERR_CREATE_COMPRESSOR, written } } else { bos, _ = io.NewNullOutputStream() } verboseWriter := os.Stdout if this.verbose == false { verboseWriter = nil } cos, err := io.NewCompressedOutputStream(this.entropyCodec, this.transform, bos, this.blockSize, this.checksum, verboseWriter, this.jobs) if err != nil { if ioerr, isIOErr := err.(io.IOError); isIOErr == true { fmt.Printf("%s\n", ioerr.Error()) return ioerr.ErrorCode(), written } else { fmt.Printf("Cannot create compressed stream: %s\n", err.Error()) return io.ERR_CREATE_COMPRESSOR, written } } defer cos.Close() input, err := os.Open(this.inputName) if err != nil { fmt.Printf("Cannot open input file '%v': %v\n", this.inputName, err) return io.ERR_OPEN_FILE, written } defer input.Close() for e := this.listeners.Front(); e != nil; e = e.Next() { cos.AddListener(e.Value.(io.BlockListener)) } // Encode len := 0 read := int64(0) printOut("Encoding ...", !this.silent) written = cos.GetWritten() buffer := make([]byte, COMP_DEFAULT_BUFFER_SIZE) before := time.Now() len, err = input.Read(buffer) for len > 0 { if err != nil { fmt.Printf("Failed to read block from file '%v': %v\n", this.inputName, err) return io.ERR_READ_FILE, written } read += int64(len) if _, err = cos.Write(buffer[0:len]); err != nil { if ioerr, isIOErr := err.(io.IOError); isIOErr == true { fmt.Printf("%s\n", ioerr.Error()) return ioerr.ErrorCode(), written } else { fmt.Printf("An unexpected condition happened. Exiting ...\n%v\n", err.Error()) return io.ERR_PROCESS_BLOCK, written } } len, err = input.Read(buffer) } if read == 0 { fmt.Println("Empty input file ... nothing to do") return WARN_EMPTY_INPUT, written } // Close streams to ensure all data are flushed // Deferred close is fallback for error paths if err := cos.Close(); err != nil { fmt.Printf("%v\n", err) return io.ERR_PROCESS_BLOCK, written } after := time.Now() delta := after.Sub(before).Nanoseconds() / 1000000 // convert to ms printOut("", !this.silent) msg = fmt.Sprintf("Encoding: %d ms", delta) printOut(msg, !this.silent) msg = fmt.Sprintf("Input size: %d", read) printOut(msg, !this.silent) msg = fmt.Sprintf("Output size: %d", cos.GetWritten()) printOut(msg, !this.silent) msg = fmt.Sprintf("Ratio: %f", float64(cos.GetWritten())/float64(read)) printOut(msg, !this.silent) if delta > 0 { msg = fmt.Sprintf("Throughput (KB/s): %d", ((read*int64(1000))>>10)/delta) printOut(msg, !this.silent) } printOut("", !this.silent) return 0, cos.GetWritten() }
// Return exit code, number of bits written func (this *BlockDecompressor) call() (int, uint64) { var msg string printOut("Input file name set to '"+this.inputName+"'", this.verbose) printOut("Output file name set to '"+this.outputName+"'", this.verbose) msg = fmt.Sprintf("Verbose set to %t", this.verbose) printOut(msg, this.verbose) msg = fmt.Sprintf("Overwrite set to %t", this.overwrite) printOut(msg, this.verbose) prefix := "" if this.jobs > 1 { prefix = "s" } msg = fmt.Sprintf("Using %d job%s", this.jobs, prefix) printOut(msg, this.verbose) var output kanzi.OutputStream if strings.ToUpper(this.outputName) == "NONE" { output, _ = io.NewNullOutputStream() } else { var err error output, err = os.OpenFile(this.outputName, os.O_RDWR, 666) if err == nil { // File exists if this.overwrite == false { fmt.Printf("The output file '%v' exists and the 'overwrite' command ", this.outputName) fmt.Println("line option has not been provided") output.Close() return io.ERR_OVERWRITE_FILE, 0 } } else { // File does not exist, create output, err = os.Create(this.outputName) if err != nil { fmt.Printf("Cannot open output file '%v' for writing: %v\n", this.outputName, err) return io.ERR_CREATE_FILE, 0 } } } defer output.Close() // Decode read := uint64(0) printOut("Decoding ...", !this.silent) input, err := os.Open(this.inputName) if err != nil { fmt.Printf("Cannot open input file '%v': %v\n", this.inputName, err) return io.ERR_OPEN_FILE, read } defer input.Close() verboseWriter := os.Stdout if this.verbose == false { verboseWriter = nil } bis, err := io.NewBufferedInputStream(input) if err != nil { fmt.Printf("Cannot create compressed stream: %v\n", err) return io.ERR_CREATE_DECOMPRESSOR, read } cis, err := io.NewCompressedInputStream(bis, verboseWriter, this.jobs) if err != nil { if err.(*io.IOError) != nil { fmt.Printf("%s\n", err.(*io.IOError).Message()) return err.(*io.IOError).ErrorCode(), read } else { fmt.Printf("Cannot create compressed stream: %v\n", err) return io.ERR_CREATE_DECOMPRESSOR, read } } for e := this.listeners.Front(); e != nil; e = e.Next() { cis.AddListener(e.Value.(io.BlockListener)) } buffer := make([]byte, DECOMP_DEFAULT_BUFFER_SIZE) decoded := len(buffer) before := time.Now() // Decode next block for decoded == len(buffer) { if decoded, err = cis.Read(buffer); err != nil { if ioerr, isIOErr := err.(*io.IOError); isIOErr == true { fmt.Printf("%s\n", ioerr.Message()) return ioerr.ErrorCode(), read } else { fmt.Printf("An unexpected condition happened. Exiting ...\n%v\n", err) return io.ERR_PROCESS_BLOCK, read } } if decoded > 0 { _, err = output.Write(buffer[0:decoded]) if err != nil { fmt.Printf("Failed to write decompressed block to file '%v': %v\n", this.outputName, err) return io.ERR_WRITE_FILE, read } read += uint64(decoded) } } // Close streams to ensure all data are flushed // Deferred close is fallback for error paths if err := cis.Close(); err != nil { fmt.Printf("%v\n", err) return io.ERR_PROCESS_BLOCK, read } after := time.Now() delta := after.Sub(before).Nanoseconds() / 1000000 // convert to ms printOut("", !this.silent) msg = fmt.Sprintf("Decoding: %d ms", delta) printOut(msg, !this.silent) msg = fmt.Sprintf("Input size: %d", cis.GetRead()) printOut(msg, !this.silent) msg = fmt.Sprintf("Output size: %d", read) printOut(msg, !this.silent) if delta > 0 { msg = fmt.Sprintf("Throughput (KB/s): %d", ((read*uint64(1000))>>10)/uint64(delta)) printOut(msg, !this.silent) } printOut("", !this.silent) return 0, cis.GetRead() }