示例#1
0
// makeTreeFromTreeFile takes in a file in the same format TREE.writeToFile()
// puts out, and remakes a HuffTree from it.
func makeTreeFromTreeFile(file *os.File) (t *huffNode, err error) {
	bytes := make([]byte, 1)
	_, err = file.Read(bytes)
	if err != nil {
		return nil, err
	}
	length := int(bytes[0] + 1)

	// Now we read in all the characters and their associated bit strings,
	// and make a tree out of them
	root := huffNode{char: 1}
	for i := 0; i < length; i++ {
		_, err = file.Read(bytes)
		if err != nil {
			return nil, err
		}
		char := bytes[0]

		_, err = file.Read(bytes)
		if err != nil {
			return nil, err
		}
		numBits := int(bytes[0])

		br, err := bitIO.NewReaderOnFile(file)
		if err != nil {
			return nil, err
		}

		current := &root
		for j := 0; j < numBits; j++ {
			bit, err := br.ReadBit()
			if err != nil {
				return nil, err
			}

			if bit == 0 {
				if current.left == nil {
					current.left = &huffNode{char: 1}
				}
				current = current.left
			} else {
				if current.right == nil {
					current.right = &huffNode{char: 1}
				}
				current = current.right
			}
		}
		current.char = char
	}

	return &root, nil
}
示例#2
0
// writeDecodedText decompresses the bits in the passed file, and puts the decompressed
// text into a new file described by toFile. If toFile exists before this is called,
// it will be truncated. Returns a nil error on success, non-nil error otherwise.
func (t *huffNode) writeDecodedText(fromFile *os.File,
	toFile string, length uint64) (err error) {
	// Set up a BitReader on the file to decodes
	reader, err := bitIO.NewReaderOnFile(fromFile)
	if err != nil {
		return err
	}

	// Decode our bits
	toWrite := []byte{}
	current := t

	// until we've written as many bytes as are encoded...
	for uint64(len(toWrite)) < length {
		bit, err := reader.ReadBit()
		// Check for errors
		if err != nil {
			return err
		}

		if bit == 0 {
			current = current.left
		} else if bit == 1 {
			current = current.right
		} else {
			// Should never happen
			return errors.New("Got invalid bit")
		}

		if current.left == nil && current.right == nil {
			// We're at a leaf node, write out its character
			toWrite = append(toWrite, current.char)
			current = t
		}
	}

	// We've terminated, write it all out
	return ioutil.WriteFile(toFile, toWrite, 0644)
}