Documentation
¶
Overview ¶
Package cabinet reads and writes Microsoft Cabinet (.cab) files.
Index ¶
- Variables
- func RegisterCompressor(method Compression, comp Compressor)
- func RegisterDecompressor(method Compression, dcomp Decompressor)
- type Compression
- type Compressor
- type Decompressor
- type File
- type FileHeader
- type ReadCloser
- type Reader
- type Writer
- func (w *Writer) AddFS(fsys fs.FS) error
- func (w *Writer) AddPath(name, path string) error
- func (w *Writer) Close() error
- func (w *Writer) Create(name string) (io.Writer, error)
- func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error)
- func (w *Writer) FlushFolder()
- func (w *Writer) RegisterCompressor(method Compression, comp Compressor)
- func (w *Writer) SetCompression(c Compression)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrFormat is returned when the data is not a valid Cabinet file. ErrFormat = errors.New("cabinet: not a valid cabinet file") // ErrAlreadyOpen is returned by [File.Open] when another reader for the same folder is still open. ErrAlreadyOpen = errors.New("cabinet: folder already has an open reader") // ErrChecksum is returned when a data block fails its checksum. ErrChecksum = errors.New("cabinet: checksum error") )
var ErrAlgorithm = errors.New("cabinet: unsupported compression algorithm")
ErrAlgorithm is returned when a folder uses a compression method that has no registered compressor or decompressor.
Functions ¶
func RegisterCompressor ¶
func RegisterCompressor(method Compression, comp Compressor)
RegisterCompressor registers a custom compressor for the given method. The built-in methods None and MSZip are registered by default.
func RegisterDecompressor ¶
func RegisterDecompressor(method Compression, dcomp Decompressor)
RegisterDecompressor registers a custom decompressor for the given method. The built-in methods None and MSZip are registered by default.
Types ¶
type Compression ¶
type Compression uint16
Compression identifies the compression algorithm used in a Cabinet folder.
const ( None Compression = 0 // no compression MSZip Compression = 1 // MS-ZIP compression Quantum Compression = 2 // Quantum compression; requires a third-party decompressor LZX Compression = 3 // LZX compression; requires a third-party decompressor )
Compression methods supported by the Cabinet format.
func (Compression) String ¶
func (c Compression) String() string
String returns the human-readable name of the compression method.
type Compressor ¶
type Compressor func(w io.Writer) (io.WriteCloser, error)
A Compressor returns a new compressing writer, writing to w. The WriteCloser's Close method must be used to flush pending data to w. If the returned writer implements `Flush() error`, it will be called after each block of input to ensure the compressed output for that block is complete before a data block boundary is written.
type Decompressor ¶
type Decompressor func(r io.Reader) io.ReadCloser
A Decompressor returns a new decompressing reader, reading from r. The io.ReadCloser's Close method must be used to release associated resources.
type File ¶
type File struct {
FileHeader
// contains filtered or unexported fields
}
A File is a single file in a Cabinet archive. The file information is in the embedded FileHeader. The file content can be accessed by calling File.Open.
func (*File) FolderIndex ¶
FolderIndex returns the index of the folder containing the file.
func (*File) OffsetInFolder ¶
OffsetInFolder returns the uncompressed byte offset of the file within its folder.
func (*File) Open ¶
func (f *File) Open() (io.ReadCloser, error)
Open returns an io.ReadCloser that provides access to the file's contents. Only one file within the same folder may be open at a time; opening a second returns ErrAlreadyOpen.
type FileHeader ¶
type FileHeader struct {
// Name is the name of the file.
Name string
// Modified is the modification time of the file.
Modified time.Time
// ReadOnly indicates the file is read-only.
ReadOnly bool
// Hidden indicates the file is hidden.
Hidden bool
// System indicates the file is a system file.
System bool
// Archive indicates the file has the archive attribute set.
Archive bool
// Exec indicates the file should be run after extraction.
Exec bool
// NonUTF8 indicates that Name is not encoded in UTF-8.
NonUTF8 bool
}
FileHeader describes a file within a Cabinet archive.
type ReadCloser ¶
type ReadCloser struct {
*Reader
// contains filtered or unexported fields
}
A ReadCloser is a Reader that must be closed when no longer needed.
func OpenReader ¶
func OpenReader(name string) (*ReadCloser, error)
OpenReader opens the named CAB file.
func (*ReadCloser) Close ¶
func (rc *ReadCloser) Close() error
Close closes the Cabinet file, rendering it unusable for I/O.
type Reader ¶
type Reader struct {
// Files is the list of files in the archive.
Files []*File
// SkipChecksum disables data block checksum verification.
SkipChecksum bool
// contains filtered or unexported fields
}
A Reader serves content from a Cabinet archive.
Example ¶
// Open a cabinet archive for reading.
r, err := cabinet.OpenReader("testdata/example.cab")
if err != nil {
log.Fatal(err)
}
defer r.Close()
// Iterate through the files in the archive,
// printing some of their contents.
for _, f := range r.Files {
fmt.Printf("Contents of %s:\n", f.Name)
rc, err := f.Open()
if err != nil {
log.Fatal(err)
}
_, err = io.Copy(os.Stdout, rc)
if err != nil {
log.Fatal(err)
}
rc.Close()
fmt.Println()
}
Output: Contents of README.md: This is an example cabinet file.
func (*Reader) Open ¶
Open opens the named file in the archive, using the semantics of fs.FS.Open: paths are always slash-separated, with no leading slash or dot-dot elements.
For best performance, open files in the order they appear in [Reader.Files], as reading out of order may require restarting decompression from the beginning of the folder.
func (*Reader) RegisterDecompressor ¶
func (rd *Reader) RegisterDecompressor(method Compression, dcomp Decompressor)
RegisterDecompressor registers or overrides a decompressor for the given method. If a decompressor for a given method is not found, Reader will default to looking up the decompressor at the package level.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer implements a Cabinet file writer.
Nothing is written to the underlying io.WriteSeeker until Writer.Close is called.
Example ¶
// Create a file to write our archive to.
f, err := os.CreateTemp("", "example-*.cab")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Create a new cabinet archive.
w := cabinet.NewWriter(f)
// Add some files to the archive.
files := []struct {
Name, Body string
}{
{"readme.txt", "This archive contains some text files."},
{"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
{"todo.txt", "Get animal handling licence.\nWrite more examples."},
}
for _, file := range files {
f, err := w.Create(file.Name)
if err != nil {
log.Fatal(err)
}
_, err = f.Write([]byte(file.Body))
if err != nil {
log.Fatal(err)
}
}
// Make sure to check the error on Close.
if err := w.Close(); err != nil {
log.Fatal(err)
}
func NewWriter ¶
func NewWriter(w io.WriteSeeker) *Writer
NewWriter returns a new Writer writing to w.
func (*Writer) AddFS ¶
AddFS adds the files from `fsys` to the archive, walking the fs.FS directory tree and maintaining the directory structure.
func (*Writer) AddPath ¶
AddPath adds a file or directory tree rooted at `path` to the archive. For directories, all files are added recursively with `name` as the path prefix.
func (*Writer) Close ¶
Close finalizes and writes the archive. It does not close the underlying writer.
func (*Writer) Create ¶
Create adds a file to the archive with the given name and returns an io.Writer to which the file contents should be written. The file's contents must be written before the next call to Writer.Create, Writer.CreateHeader, or Writer.Close.
func (*Writer) CreateHeader ¶
func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error)
CreateHeader adds a file to the archive using the provided FileHeader for the file metadata.
This returns an io.Writer to which the file contents should be written. The file's contents must be written before the next call to Writer.Create, Writer.CreateHeader, or Writer.Close.
func (*Writer) FlushFolder ¶
func (w *Writer) FlushFolder()
FlushFolder starts a new folder. It is a no-op if the current folder is empty.
func (*Writer) RegisterCompressor ¶
func (w *Writer) RegisterCompressor(method Compression, comp Compressor)
RegisterCompressor registers or overrides a compressor for the given method. If a compressor for a given method is not found, Writer will default to looking up the compressor at the package level.
Example ¶
// Override the default MS-ZIP compressor with a higher compression level.
// Create a file to write our archive to.
f, err := os.CreateTemp("", "example-*.cab")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Create a new cabinet archive.
w := cabinet.NewWriter(f)
// Register a custom MS-ZIP compressor.
w.RegisterCompressor(cabinet.MSZip, func(out io.Writer) (io.WriteCloser, error) {
return mszip.NewWriter(out, mszip.BestCompression)
})
// Proceed to add files to w.
func (*Writer) SetCompression ¶
func (w *Writer) SetCompression(c Compression)
SetCompression sets the compression method for subsequently added files. If the current folder already contains files, it starts a new folder.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package mszip implements the MS-ZIP compression format as defined by [MS-MCI]: Microsoft ZIP (MSZIP) Compression and Decompression Data Structure https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-mci/27f0a9bf-9567-4e40-ad66-6ae9ab9d2786
|
Package mszip implements the MS-ZIP compression format as defined by [MS-MCI]: Microsoft ZIP (MSZIP) Compression and Decompression Data Structure https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-mci/27f0a9bf-9567-4e40-ad66-6ae9ab9d2786 |