Artifact dc7b90e535b7654ac49fb41f71291ca647c8898520bc41440454e1024c56d53b:
- File
internal/blob/compress.go
— part of check-in
[f5744359d3]
at
2026-04-19 16:30:54
on branch trunk
— Initial open source release
libfossil is a pure-Go implementation of the Fossil SCM, reading and writing the same .fossil SQLite repository format as upstream Fossil.
This is the first public release of code that previously lived in a private repository. The module path is github.com/danmestas/libfossil and the binary is named libfossil to avoid $PATH collisions with upstream fossil.
Included: - Repo lifecycle (create, clone), checkout/checkin, timeline, merge, diff, annotate, shun, tag, branch, bisect, stash, undo/redo - Sync-over-HTTP protocol (client and handler) - Two SQLite drivers: modernc (pure Go, default) and ncruces (wasm-capable) - Observer interfaces (SyncObserver, CheckoutObserver) with an optional OpenTelemetry implementation in observer/otel (separate submodule) - Deterministic simulation testing harness with BUGGIFY fault injection - Kong-based embeddable CLI under cli/ and a standalone binary under cmd/libfossil/ (user: [email protected], size: 2030) [annotate] [blame] [check-ins using]
package blob import ( "bytes" "compress/zlib" "encoding/binary" "fmt" "io" "github.com/danmestas/libfossil/simio" ) // Compress produces Fossil-compatible compressed blob content: // [4-byte big-endian uncompressed size][zlib-compressed data]. // This matches Fossil's blob_compress() in src/blob.c. func Compress(data []byte) (result []byte, err error) { if data == nil { panic("blob.Compress: data must not be nil") } defer func() { if err == nil && len(result) == 0 { panic("blob.Compress: postcondition violated: result is empty with no error") } }() var buf bytes.Buffer // 4-byte big-endian uncompressed size prefix. if err := binary.Write(&buf, binary.BigEndian, uint32(len(data))); err != nil { return nil, fmt.Errorf("write size prefix: %w", err) } w := zlib.NewWriter(&buf) if _, err := w.Write(data); err != nil { return nil, fmt.Errorf("zlib compress: %w", err) } if err := w.Close(); err != nil { return nil, fmt.Errorf("zlib close: %w", err) } return buf.Bytes(), nil } // Decompress handles Fossil's compressed blob format: // [4-byte big-endian uncompressed size][zlib-compressed data]. // The 4-byte prefix is skipped before decompressing. func Decompress(data []byte) (result []byte, err error) { if data == nil { panic("blob.Decompress: data must not be nil") } defer func() { if err == nil && result == nil { panic("blob.Decompress: postcondition violated: result is nil with no error") } }() if len(data) < 5 { return nil, fmt.Errorf("zlib decompress: data too short (%d bytes)", len(data)) } // Skip the 4-byte size prefix. zlibData := data[4:] r, err := zlib.NewReader(bytes.NewReader(zlibData)) if err != nil { return nil, fmt.Errorf("zlib decompress: %w", err) } defer r.Close() out, err := io.ReadAll(r) if err != nil { return nil, fmt.Errorf("zlib read: %w", err) } // BUGGIFY: truncate decompressed output to exercise partial-read handling. if simio.Buggify(0.02) && len(out) > 1 { out = out[:len(out)/2] } return out, nil }