raczlib

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 19, 2019 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package raczlib provides access to RAC (Random Access Compression) files with the Zlib compression codec.

The RAC specification is at https://github.com/google/wuffs/blob/master/doc/spec/rac-spec.md

Example (RoundTrip)

Example_roundTrip demonstrates compressing (using a rac.Writer and a raczlib.CodecWriter) and decompressing (using a rac.Reader and a raczlib.CodecReader). This includes decompressing an excerpt of the original data, exercising the "random access" part of RAC.

package main

import (
	"bytes"
	"fmt"
	"io"
	"log"

	"github.com/google/wuffs/lib/rac"
	"github.com/google/wuffs/lib/raczlib"
)

func main() {
	// Create some test data.
	oBuf := &bytes.Buffer{}
	for i := 99; i > 0; i-- {
		fmt.Fprintf(oBuf, "%d bottles of beer on the wall, %d bottles of beer.\n"+
			"Take one down, pass it around, %d bottles of beer on the wall.\n",
			i, i, i-1)
	}
	original := oBuf.Bytes()

	// Create the RAC file.
	cBuf := &bytes.Buffer{}
	w := &rac.Writer{
		Writer:      cBuf,
		CodecWriter: &raczlib.CodecWriter{},
		// It's not necessary to explicitly declare the DChunkSize. The zero
		// value implies a reasonable default. Nonetheless, using a 1 KiB
		// DChunkSize (which is relatively small) makes for a more interesting
		// test, as the resultant RAC file then contains more than one chunk.
		DChunkSize: 1024,
		// We also use the default IndexLocation value, which makes for a
		// simpler example, but if you're copy/pasting this code, note that
		// using an explicit IndexLocationAtStart can result in slightly more
		// efficient RAC files, at the cost of using more memory to encode.
	}
	if _, err := w.Write(original); err != nil {
		log.Fatalf("Write: %v", err)
	}
	if err := w.Close(); err != nil {
		log.Fatalf("Close: %v", err)
	}
	compressed := cBuf.Bytes()

	// The exact compression ratio depends on the zlib encoder's algorithm,
	// which can change across Go standard library releases, but it should be
	// at least a 4x ratio. It'd be larger if we didn't specify an explicit
	// (but relatively small) DChunkSize.
	if ratio := len(original) / len(compressed); ratio < 4 {
		log.Fatalf("compression ratio (%dx) was too small", ratio)
	}

	// Prepare to decompress.
	r := &rac.Reader{
		ReadSeeker:     bytes.NewReader(compressed),
		CompressedSize: int64(len(compressed)),
		CodecReaders:   []rac.CodecReader{&raczlib.CodecReader{}},
	}
	defer r.Close()

	// Read the whole file.
	wBuf := &bytes.Buffer{}
	if _, err := io.Copy(wBuf, r); err != nil {
		log.Fatal(err)
	}
	wholeFile := wBuf.Bytes()
	if !bytes.Equal(wholeFile, original) {
		log.Fatal("round trip did not preserve whole file")
	} else {
		fmt.Printf("Whole file preserved (%d bytes).\n", len(wholeFile))
	}

	// Read an excerpt.
	const offset, length = 3000, 1200
	want := original[offset : offset+length]
	got := make([]byte, length)
	if _, err := r.Seek(offset, io.SeekStart); err != nil {
		log.Fatalf("Seek: %v", err)
	}
	if _, err := io.ReadFull(r, got); err != nil {
		log.Fatalf("ReadFull: %v", err)
	}
	if !bytes.Equal(got, want) {
		log.Fatal("round trip did not preserve excerpt")
	} else {
		fmt.Printf("Excerpt    preserved  (%d bytes).\n", len(got))
	}

}
Output:

Whole file preserved (11357 bytes).
Excerpt    preserved  (1200 bytes).

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CodecReader

type CodecReader struct {
	// contains filtered or unexported fields
}

CodecReader specializes a rac.Reader to decode Zlib-compressed chunks.

func (*CodecReader) Accepts

func (r *CodecReader) Accepts(c rac.Codec) bool

Accepts implements rac.CodecReader.

func (*CodecReader) Clone

func (r *CodecReader) Clone() rac.CodecReader

Clone implements rac.CodecReader.

func (*CodecReader) Close

func (r *CodecReader) Close() error

Close implements rac.CodecReader.

func (*CodecReader) MakeDecompressor

func (r *CodecReader) MakeDecompressor(racFile io.ReadSeeker, chunk rac.Chunk) (io.Reader, error)

MakeDecompressor implements rac.CodecReader.

type CodecWriter

type CodecWriter struct {
	// contains filtered or unexported fields
}

CodecWriter specializes a rac.Writer to encode Zlib-compressed chunks.

func (*CodecWriter) CanCut

func (w *CodecWriter) CanCut() bool

CanCut implements rac.CodecWriter.

func (*CodecWriter) Clone

func (w *CodecWriter) Clone() rac.CodecWriter

Clone implements rac.CodecWriter.

func (*CodecWriter) Close

func (w *CodecWriter) Close() error

Close implements rac.CodecWriter.

func (*CodecWriter) Compress

func (w *CodecWriter) Compress(p []byte, q []byte, resourcesData [][]byte) (
	codec rac.Codec, compressed []byte, secondaryResource int, tertiaryResource int, retErr error)

Compress implements rac.CodecWriter.

func (*CodecWriter) Cut

func (w *CodecWriter) Cut(codec rac.Codec, encoded []byte, maxEncodedLen int) (encodedLen int, decodedLen int, retErr error)

Cut implements rac.CodecWriter.

func (*CodecWriter) WrapResource

func (w *CodecWriter) WrapResource(raw []byte) ([]byte, error)

WrapResource implements rac.CodecWriter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL