Documentation
¶
Overview ¶
Package wapp provides the WAPP (Wippy Application Pack) binary archive format.
WAPP is designed for packaging filesystem trees, registry entries, and metadata into a single binary file. It supports lazy loading, per-file compression, and integrity verification.
Format Structure ¶
A WAPP file consists of:
- Header (268 bytes): Magic, version, data offset/size, SHA-256 hash
- Data frames: Compressed file content in 10MB frames
- TOC: Msgpack-encoded table of contents (zstd compressed)
- Footer (16 bytes): TOC offset and size
Contents ¶
A WAPP file can contain:
- Metadata: Pack-level key-value metadata
- Registry Entries: Typed records with ID, Kind, Meta, and Data fields
- Resources: Filesystem trees with per-file compression
Writing ¶
Use Writer to create WAPP files:
writer := wapp.NewWriter() err := writer.Pack(metadata, entries, fsys, resourceID, resourceMeta, output)
Reading ¶
Use Reader to read WAPP files:
reader, err := wapp.NewReader(file) entries, err := reader.GetEntries() fsys, err := reader.GetFS(resourceID)
Features ¶
- Per-file zstd compression (skips already-compressed formats)
- Lazy loading with footer-first reading
- Multiple filesystem tree resources per pack
- Registry entries for structured data storage
- SHA-256 integrity verification
- O(1) file and resource lookups
- Concurrent-safe reads with decompression cache
- fs.FS interface compatibility
Index ¶
- Constants
- Variables
- func WriteFooter(w io.Writer, f *Footer) error
- func WriteHeader(w io.Writer, h *Header) error
- type ChunkInfo
- type Entry
- type FileEntry
- type FileLocation
- type Footer
- type FormatError
- type FrameInfo
- type FrameReader
- type Header
- type ID
- type Metadata
- type ProgressCallback
- type ReadError
- type Reader
- func (r *Reader) GetEntries() ([]Entry, error)
- func (r *Reader) GetFS(id ID) (fs.ReadDirFS, error)
- func (r *Reader) GetMetadata() (Metadata, error)
- func (r *Reader) Header() *Header
- func (r *Reader) ListResources() []ResourceInfo
- func (r *Reader) ReadFrameData(frameInfo FrameInfo, offset, size uint64) ([]byte, error)
- type ReaderOption
- type ResourceFrame
- type ResourceInfo
- type ResourceSpec
- type TOC
- type TreeResource
- type WriteError
- type Writer
- type WriterOption
Constants ¶
const ( // Magic header identifying WAPP files. Magic = "WIPPYPACK" // Version1 is the current format version. Version1 byte = 0x01 // HeaderSize is the fixed header size in bytes. HeaderSize = 268 FooterSize = 16 )
const ( // ChunkSize is the default chunk size for large files (1MB). ChunkSize uint64 = 1024 * 1024 // ResourceTypeTree identifies a filesystem tree resource. ResourceTypeTree = "tree" )
Variables ¶
var ( ErrDataCorrupted = errors.New("data corrupted") ErrNegativePosition = errors.New("negative position") ErrIsDirectory = errors.New("is a directory") ErrInvalidMagic = errors.New("invalid magic") ErrUnsupportedVersion = errors.New("unsupported version") ErrResourceNotFound = errors.New("resource not found") ErrFrameNotFound = errors.New("frame not found") ErrInvalidWhence = errors.New("invalid whence") ErrDataSizeExceeded = errors.New("data size exceeded") ErrResourceNotTree = errors.New("resource not a tree") ErrUnknownResourceType = errors.New("unknown resource type") ErrInsufficientFrames = errors.New("insufficient frames") ErrResourceCountExceeded = errors.New("resource count exceeded") ErrInvalidResourceFS = errors.New("invalid resource filesystem") ErrInvalidTOC = errors.New("invalid toc") ErrFrameOutOfBounds = errors.New("frame out of bounds") ErrFrameHashMismatch = errors.New("frame hash mismatch") )
Sentinel errors for errors.Is checks.
var DefaultCompressionFunc = func(filename string) bool { ext := strings.ToLower(filepath.Ext(filename)) _, skip := defaultSkipCompressedExts[ext] return !skip }
DefaultCompressionFunc provides default logic for compression decision. Skips compression for already-compressed formats.
Functions ¶
Types ¶
type ChunkInfo ¶
type ChunkInfo struct {
Size uint32 `json:"Size" msgpack:"size"`
Offset uint64 `json:"Offset" msgpack:"offset"`
FrameIndex uint32 `json:"FrameIndex" msgpack:"frame"`
FrameOffset uint64 `json:"FrameOffset" msgpack:"frame_offset"`
}
ChunkInfo describes a chunk of a large file.
type Entry ¶
type Entry struct {
ID ID `json:"ID" msgpack:"ID"`
Kind string `json:"Kind" msgpack:"Kind"`
Meta Metadata `json:"Meta,omitempty" msgpack:"Meta,omitempty"`
Data any `json:"Data,omitempty" msgpack:"Data,omitempty"`
}
Entry represents a registry entry stored in the pack.
type FileEntry ¶
type FileEntry struct {
Size uint64 `json:"Size" msgpack:"size"`
CompressedSize uint64 `json:"CompressedSize,omitempty" msgpack:"compressed_size,omitempty"`
Mode uint32 `json:"Mode" msgpack:"mode"`
ModTime int64 `json:"ModTime" msgpack:"mtime"`
Hash string `json:"Hash" msgpack:"hash"`
Compressed bool `json:"Compressed" msgpack:"compressed"`
Meta Metadata `json:"Meta,omitempty" msgpack:"meta,omitempty"`
Location FileLocation `json:"Location" msgpack:"location"`
}
FileEntry describes a file in a tree resource.
type FileLocation ¶
type FileLocation struct {
FrameIndex uint32 `json:"FrameIndex" msgpack:"frame"`
Offset uint64 `json:"Offset" msgpack:"offset"`
Chunks []ChunkInfo `json:"Chunks,omitempty" msgpack:"chunks,omitempty"`
}
FileLocation describes where file content is stored.
type Footer ¶
type Footer struct {
}
Footer represents the WAPP file footer.
func ReadFooter ¶
func ReadFooter(r io.ReadSeeker) (*Footer, error)
ReadFooter reads a WAPP footer from a seeker.
type FormatError ¶
FormatError wraps format validation errors.
func (*FormatError) Error ¶
func (e *FormatError) Error() string
func (*FormatError) Unwrap ¶
func (e *FormatError) Unwrap() error
type FrameInfo ¶
type FrameInfo struct {
Offset uint64 `json:"Offset" msgpack:"offset"`
Size uint64 `json:"Size" msgpack:"size"`
UncompressedSize uint64 `json:"UncompressedSize" msgpack:"uncomp_size"`
// Hash is the hex-encoded SHA-256 of the compressed frame bytes.
Hash string `json:"Hash" msgpack:"hash"`
}
FrameInfo describes a data frame location and integrity.
type FrameReader ¶
type FrameReader interface {
ReadFrameData(frameInfo FrameInfo, offset, size uint64) ([]byte, error)
}
FrameReader interface abstracts frame data reading.
type Header ¶
type Header struct {
Magic [9]byte // "WIPPYPACK"
Version byte // 0x01
Flags uint16 // Reserved flags
DataOffset uint64 // Offset to data section
DataSize uint64 // Total size of data section
DataHash [32]byte // SHA-256 of data section
Reserved [208]byte // Reserved for future use
}
Header represents the WAPP file header.
type ID ¶
type ID struct {
Namespace string `json:"ns" msgpack:"ns"`
Name string `json:"name" msgpack:"name"`
}
ID represents a namespaced identifier for resources and entries.
type ProgressCallback ¶
ProgressCallback reports packing progress.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader reads WAPP files with lazy loading.
func NewReader ¶
NewReader creates a WAPP reader using footer-first reading. It uses the default decompression cache limit.
func NewReaderWithOptions ¶
func NewReaderWithOptions(r io.ReaderAt, opts ...ReaderOption) (*Reader, error)
NewReaderWithOptions creates a WAPP reader with options.
func (*Reader) GetEntries ¶
GetEntries returns registry entries (lazy loaded).
func (*Reader) GetMetadata ¶
GetMetadata returns pack metadata (lazy loaded).
func (*Reader) ListResources ¶
func (r *Reader) ListResources() []ResourceInfo
ListResources returns resource metadata from TOC.
type ReaderOption ¶
type ReaderOption func(*Reader)
ReaderOption configures Reader behavior.
func WithDecompressionCacheLimit ¶
func WithDecompressionCacheLimit(maxBytes int64) ReaderOption
WithDecompressionCacheLimit sets the maximum cached decompressed bytes. Use 0 to disable the cache.
type ResourceFrame ¶
type ResourceFrame struct {
ID ID `json:"ID" msgpack:"id"`
Type string `json:"Type" msgpack:"type"` // ResourceTypeTree
Meta Metadata `json:"Meta" msgpack:"meta"`
Frame FrameInfo `json:"Frame" msgpack:"frame"`
FileCount uint32 `json:"FileCount,omitempty" msgpack:"file_count,omitempty"`
TotalSize uint64 `json:"TotalSize,omitempty" msgpack:"total_size,omitempty"`
}
ResourceFrame describes a resource in the pack.
type ResourceInfo ¶
type ResourceInfo struct {
ID ID
Type string // ResourceTypeTree
Meta Metadata
Hash string
Size uint64
FileCount uint32
}
ResourceInfo provides summary information about a resource.
type ResourceSpec ¶
ResourceSpec specifies a filesystem resource to pack.
type TOC ¶
type TOC struct {
// Pack metadata frame.
Metadata FrameInfo `json:"Metadata" msgpack:"metadata"`
// Registry entries frame.
Entries FrameInfo `json:"Entries" msgpack:"entries"`
// Resource frames (filesystem trees).
Resources []ResourceFrame `json:"Resources" msgpack:"resources"`
// Data frames containing file content.
DataFrames []FrameInfo `json:"DataFrames" msgpack:"data_frames"`
}
TOC represents the table of contents.
type TreeResource ¶
type TreeResource struct {
ID ID `json:"ID" msgpack:"id"`
Meta Metadata `json:"Meta" msgpack:"meta"`
// Path index for O(1) file lookups.
Files map[string]FileEntry `json:"Files" msgpack:"files"`
// Directory listings for ReadDir.
Dirs map[string][]string `json:"Dirs" msgpack:"dirs"`
}
TreeResource represents a filesystem tree in the pack.
type WriteError ¶
WriteError wraps errors during write operations.
func (*WriteError) Error ¶
func (e *WriteError) Error() string
func (*WriteError) Unwrap ¶
func (e *WriteError) Unwrap() error
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer writes WAPP files.
func (*Writer) Pack ¶
func (w *Writer) Pack( metadata Metadata, entries []Entry, fsys fs.FS, resourceID ID, resourceMeta Metadata, out io.Writer, ) error
Pack creates a WAPP file from filesystem and entries.
func (*Writer) PackEntries ¶
PackEntries creates a WAPP file with only metadata and entries.
func (*Writer) PackWithResources ¶
func (w *Writer) PackWithResources( metadata Metadata, entries []Entry, resources []ResourceSpec, out io.Writer, ) error
PackWithResources creates a WAPP file with multiple filesystem resources.
type WriterOption ¶
type WriterOption func(*Writer)
WriterOption configures Writer.
func WithCompressionFunc ¶
func WithCompressionFunc(fn func(string) bool) WriterOption
WithCompressionFunc sets custom compression decision function.
func WithProgressCallback ¶
func WithProgressCallback(fn ProgressCallback) WriterOption
WithProgressCallback sets a progress callback.