aboutsummaryrefslogtreecommitdiff
path: root/pack_pack_write.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-01-29 14:38:18 +0100
committerGravatar Runxi Yu2026-01-29 14:51:10 +0100
commit33de7fd28ce870d0b98016fcb42aa9ae5c0ca78a (patch)
tree06e2ef213cb07396bf59e979096df910ed477ede /pack_pack_write.go
parentpack: Harden pack writing test with 1000 1kb files (diff)
signatureNo signature
packed: More uniform file naming scheme
Diffstat (limited to 'pack_pack_write.go')
-rw-r--r--pack_pack_write.go273
1 files changed, 0 insertions, 273 deletions
diff --git a/pack_pack_write.go b/pack_pack_write.go
deleted file mode 100644
index 435c9edb..00000000
--- a/pack_pack_write.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package furgit
-
-import (
- "crypto/sha1"
- "crypto/sha256"
- "encoding/binary"
- "errors"
- "hash"
- "io"
-
- "codeberg.org/lindenii/furgit/internal/zlib"
-)
-
-// TODO
-var errPackDeltaUnimplemented = errors.New("furgit: pack: delta writing not implemented")
-
-// packWriter writes a PACKv2 stream.
-type packWriter struct {
- w io.Writer
- h hash.Hash
- algo hashAlgorithm
- objCount uint32
- wroteHeader bool
- bytesWritten uint64
-}
-
-func newPackWriter(w io.Writer, algo hashAlgorithm, objCount uint32) (*packWriter, error) {
- if w == nil {
- return nil, ErrInvalidObject
- }
- h, err := newHashWriter(algo)
- if err != nil {
- return nil, err
- }
- return &packWriter{
- w: w,
- h: h,
- algo: algo,
- objCount: objCount,
- }, nil
-}
-
-func newHashWriter(algo hashAlgorithm) (hash.Hash, error) {
- switch algo {
- case hashAlgoSHA1:
- return sha1.New(), nil
- case hashAlgoSHA256:
- return sha256.New(), nil
- default:
- return nil, ErrInvalidObject
- }
-}
-
-func (pw *packWriter) writePacked(p []byte) error {
- if len(p) == 0 {
- return nil
- }
- n, err := pw.w.Write(p)
- if n > 0 {
- _, _ = pw.h.Write(p[:n])
- pw.bytesWritten += uint64(n)
- }
- if err != nil {
- return err
- }
- if n != len(p) {
- return io.ErrShortWrite
- }
- return nil
-}
-
-func (pw *packWriter) WriteHeader() error {
- if pw == nil || pw.wroteHeader {
- return ErrInvalidObject
- }
- var hdr [12]byte
- binary.BigEndian.PutUint32(hdr[0:4], packMagic)
- binary.BigEndian.PutUint32(hdr[4:8], packVersion2)
- binary.BigEndian.PutUint32(hdr[8:12], pw.objCount)
- if err := pw.writePacked(hdr[:]); err != nil {
- return err
- }
- pw.wroteHeader = true
- return nil
-}
-
-func (pw *packWriter) WriteObject(ty ObjectType, body []byte) error {
- if pw == nil || !pw.wroteHeader {
- return ErrInvalidObject
- }
- switch ty {
- case ObjectTypeCommit, ObjectTypeTree, ObjectTypeBlob, ObjectTypeTag:
- // remember that go switches don't fallthrough lol
- default:
- return ErrInvalidObject
- }
- if body == nil {
- body = []byte{}
- }
-
- hdr, err := packHeaderEncode(ty, len(body))
- if err != nil {
- return err
- }
- if err := pw.writePacked(hdr); err != nil {
- return err
- }
-
- zw := zlib.NewWriter(&packHashWriter{pw: pw})
- if _, err := zw.Write(body); err != nil {
- _ = zw.Close()
- return err
- }
- return zw.Close()
-}
-
-func (pw *packWriter) WriteOfsDelta(baseOffset uint64, baseSize, resultSize int, delta []byte) error {
- _ = baseOffset
- _ = baseSize
- _ = resultSize
- _ = delta
- return errPackDeltaUnimplemented
-}
-
-func (pw *packWriter) WriteRefDelta(base Hash, baseSize, resultSize int, delta []byte) error {
- _ = base
- _ = baseSize
- _ = resultSize
- _ = delta
- return errPackDeltaUnimplemented
-}
-
-func (pw *packWriter) Close() (Hash, error) {
- if pw == nil || !pw.wroteHeader {
- return Hash{}, ErrInvalidObject
- }
- sum := pw.h.Sum(nil)
- if _, err := pw.w.Write(sum); err != nil {
- return Hash{}, err
- }
- var out Hash
- copy(out.data[:], sum)
- out.algo = pw.algo
- return out, nil
-}
-
-type packHashWriter struct {
- pw *packWriter
-}
-
-func (w *packHashWriter) Write(p []byte) (int, error) {
- if w == nil || w.pw == nil {
- return 0, ErrInvalidObject
- }
- if err := w.pw.writePacked(p); err != nil {
- return 0, err
- }
- return len(p), nil
-}
-
-// packHeaderEncode encodes a pack object header (type + size).
-func packHeaderEncode(ty ObjectType, size int) ([]byte, error) {
- if size < 0 {
- return nil, ErrInvalidObject
- }
- var out [16]byte
- pos := 0
-
- b := byte(size & 0x0f)
- size >>= 4
- b |= byte(ty&0x07) << 4
- if size > 0 {
- b |= 0x80
- }
- out[pos] = b
- pos++
-
- for size > 0 {
- b = byte(size & 0x7f)
- size >>= 7
- if size > 0 {
- b |= 0x80
- }
- out[pos] = b
- pos++
- }
-
- return out[:pos], nil
-}
-
-// packVarintEncode encodes a 7-bit varint.
-func packVarintEncode(size int) ([]byte, error) {
- if size < 0 {
- return nil, ErrInvalidObject
- }
- var out [16]byte
- pos := 0
- for {
- b := byte(size & 0x7f)
- size >>= 7
- if size != 0 {
- b |= 0x80
- }
- out[pos] = b
- pos++
- if size == 0 {
- break
- }
- }
- return out[:pos], nil
-}
-
-// packOfsEncode encodes an ofs-delta distance.
-func packOfsEncode(dist uint64) ([]byte, error) {
- if dist == 0 {
- return nil, ErrInvalidObject
- }
- var out [16]byte
- pos := 0
- out[pos] = byte(dist & 0x7f)
- pos++
- dist >>= 7
- for dist != 0 {
- b := byte((dist - 1) & 0x7f)
- out[pos] = b | 0x80
- pos++
- dist >>= 7
- }
- for i, j := 0, pos-1; i < j; i, j = i+1, j-1 {
- out[i], out[j] = out[j], out[i]
- }
- return out[:pos], nil
-}
-
-// packWrite writes a pack stream for the provided object ids.
-func (repo *Repository) packWrite(w io.Writer, objects []Hash, opts packWriteOptions) (Hash, error) {
- if repo == nil {
- return Hash{}, ErrInvalidObject
- }
- if opts.EnableDeltas || opts.EnableThinPack {
- return Hash{}, errPackDeltaUnimplemented
- }
- if len(objects) > int(^uint32(0)) {
- return Hash{}, ErrInvalidObject
- }
-
- pw, err := newPackWriter(w, repo.hashAlgo, uint32(len(objects)))
- if err != nil {
- return Hash{}, err
- }
- if err := pw.WriteHeader(); err != nil {
- return Hash{}, err
- }
-
- for _, id := range objects {
- ty, body, err := repo.ReadObjectTypeRaw(id)
- if err != nil {
- return Hash{}, err
- }
- if err := pw.WriteObject(ty, body); err != nil {
- return Hash{}, err
- }
- }
-
- return pw.Close()
-}
-
-type packWriteOptions struct {
- EnableDeltas bool
- EnableThinPack bool
- MinDeltaSavings int
- MaxDeltaDepth int
-}