@@ -3,10 +3,11 @@ import ( iou "0dev.org/ioutil" "fmt" "io" // "io/ioutil" + "bytes" "os" "sort" ) func main() { @@ -29,28 +30,48 @@ if err != nil { os.Stderr.WriteString("Error while constructing application reader. " + err.Error()) os.Exit(1) } - // count, err := io.Copy(ioutil.Discard, reader) - // if err != nil { - // os.Stderr.WriteString("Error while applying recommendations. " + err.Error()) - // os.Exit(1) - // } - // fmt.Println(count) - - _, err = io.Copy(os.Stdout, reader) + var buf bytes.Buffer + _, err = io.Copy(&buf, reader) + if err != nil { + os.Stderr.WriteString("Error while applying recommendations. " + err.Error()) + os.Exit(1) + } + + var in *bytes.Reader = bytes.NewReader(buf.Bytes()) + rev, err := apply(rec.reverse(), in) + if err != nil { + os.Stderr.WriteString("Error while constructing application reader. " + err.Error()) + os.Exit(1) + } + + _, err = io.Copy(os.Stdout, rev) if err != nil { os.Stderr.WriteString("Error while applying recommendations. " + err.Error()) os.Exit(1) } } type recommendation struct { - p2s map[uint16]byte - s2p map[byte]uint16 - unmapped byte + p2s map[uint16]byte + s2p map[byte]uint16 +} + +// Produces a reversed recommendation struct +func (r *recommendation) reverse() *recommendation { + var rec recommendation + rec.p2s = make(map[uint16]byte) + for k, v := range r.s2p { + rec.p2s[v] = k + } + rec.s2p = make(map[byte]uint16) + for k, v := range r.p2s { + rec.s2p[v] = k + } + return &rec } // Returns an io.Reader that reads from the underlying one while applying the given recommendations func apply(rec *recommendation, reader io.Reader) (io.Reader, error) { // The symbol reader replaces symbols with pairs according to the s2p mapping @@ -117,11 +138,11 @@ for i, pairsLength := 0, len(pairs); i < pairsLength; i++ { currentPair := pairs[i] // Termination condition for when we are out of symbols - if len(symbols) == 1 { + if len(symbols) == 1 { // TODO drop to zero ? break } gain := currentPair.count - 4 // 4 bytes for the default header currentSymbol := symbols[0] @@ -150,11 +171,10 @@ // Mark the current pair for replacement by the current symbol rec.p2s[currentPair.value] = currentSymbol.value } symbols = symbols[1:] } - rec.unmapped = symbols[len(symbols)-1].value return &rec } // Reads the provided input and returns information about the available byte pair and used symbols func analyze(reader io.Reader) (pairSlice, symbolSlice) {