// writeEncodedTextToFile encodes the text in the passed file under the tree // it was called on, and writes out the encoded bits to the passed file. Is called // by EncodeText. Returns a non-nil error on failure, nil otherwise. func (t *huffNode) writeEncodedText(fromFile string, toFile *os.File) (err error, length uint64) { toEncode, err := ioutil.ReadFile(fromFile) if err != nil { return err, 0 } bitReps := t.getByteMap() bw, err := bitIO.NewWriterOnFile(toFile) if err != nil { return err, 0 } // Write 'em length = 0 for _, char := range toEncode { length++ bitRep := bitReps[char] for _, bit := range bitRep { err = bw.WriteBit(byte(bit - '0')) if err != nil { return err, 0 } } } _, err = bw.CloseAndReturnFile() return err, length }
// writeToFile writes the tree out to the passed os.File. // Will be called by EncodeText to write the tree out to the beginning // of the encoded file. func (t *huffNode) writeToFile(f *os.File) (err error) { // First, get the map of byte->string of 0s and 1s (character->binary representation) var bytes map[byte]string = t.getByteMap() // Then, write the number of bytes we have in the tree err = binary.Write(f, endianness, int8(len(bytes)-1)) if err != nil { return err } // Now for each byte, we write: // - The byte // - The length of its binary (as a uint16) // - The binary for char, repString := range bytes { // First the character _, err = f.Write([]byte{char}) if err != nil { return err } // Now the length of the binary err = binary.Write(f, endianness, int8(len(repString))) if err != nil { return err } // And the actual bits bw, err := bitIO.NewWriterOnFile(f) if err != nil { return err } for _, c := range repString { err = bw.WriteBit(byte(c - '0')) // WriteBit() wants a byte, we have runes if err != nil { return err } } f, err = bw.CloseAndReturnFile() if err != nil { return err } } return nil }