aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format/packfile/common.go
diff options
context:
space:
mode:
Diffstat (limited to 'plumbing/format/packfile/common.go')
-rw-r--r--plumbing/format/packfile/common.go79
1 files changed, 67 insertions, 12 deletions
diff --git a/plumbing/format/packfile/common.go b/plumbing/format/packfile/common.go
index beb015d..76254f0 100644
--- a/plumbing/format/packfile/common.go
+++ b/plumbing/format/packfile/common.go
@@ -2,9 +2,11 @@ package packfile
import (
"bytes"
+ "errors"
"io"
"sync"
+ "gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/utils/ioutil"
)
@@ -23,24 +25,24 @@ const (
maskType = uint8(112) // 0111 0000
)
-// UpdateObjectStorage updates the given storer.EncodedObjectStorer with the contents of the
+// UpdateObjectStorage updates the storer with the objects in the given
// packfile.
-func UpdateObjectStorage(s storer.EncodedObjectStorer, packfile io.Reader) error {
- if sw, ok := s.(storer.PackfileWriter); ok {
- return writePackfileToObjectStorage(sw, packfile)
+func UpdateObjectStorage(s storer.Storer, packfile io.Reader) error {
+ if pw, ok := s.(storer.PackfileWriter); ok {
+ return WritePackfileToObjectStorage(pw, packfile)
}
- stream := NewScanner(packfile)
- d, err := NewDecoder(stream, s)
- if err != nil {
- return err
- }
-
- _, err = d.Decode()
+ updater := newPackfileStorageUpdater(s)
+ _, err := NewParser(NewScanner(packfile), updater).Parse()
return err
}
-func writePackfileToObjectStorage(sw storer.PackfileWriter, packfile io.Reader) (err error) {
+// WritePackfileToObjectStorage writes all the packfile objects into the given
+// object storage.
+func WritePackfileToObjectStorage(
+ sw storer.PackfileWriter,
+ packfile io.Reader,
+) (err error) {
w, err := sw.PackfileWriter()
if err != nil {
return err
@@ -56,3 +58,56 @@ var bufPool = sync.Pool{
return bytes.NewBuffer(nil)
},
}
+
+var errMissingObjectContent = errors.New("missing object content")
+
+type packfileStorageUpdater struct {
+ storer.Storer
+ lastSize int64
+ lastType plumbing.ObjectType
+}
+
+func newPackfileStorageUpdater(s storer.Storer) *packfileStorageUpdater {
+ return &packfileStorageUpdater{Storer: s}
+}
+
+func (p *packfileStorageUpdater) OnHeader(count uint32) error {
+ return nil
+}
+
+func (p *packfileStorageUpdater) OnInflatedObjectHeader(
+ t plumbing.ObjectType,
+ objSize int64,
+ pos int64,
+) error {
+ if p.lastSize > 0 || p.lastType != plumbing.InvalidObject {
+ return errMissingObjectContent
+ }
+
+ p.lastType = t
+ p.lastSize = objSize
+ return nil
+}
+
+func (p *packfileStorageUpdater) OnInflatedObjectContent(
+ h plumbing.Hash,
+ pos int64,
+ crc uint32,
+ content []byte,
+) error {
+ obj := new(plumbing.MemoryObject)
+ obj.SetSize(p.lastSize)
+ obj.SetType(p.lastType)
+ if _, err := obj.Write(content); err != nil {
+ return err
+ }
+
+ _, err := p.SetEncodedObject(obj)
+ p.lastSize = 0
+ p.lastType = plumbing.InvalidObject
+ return err
+}
+
+func (p *packfileStorageUpdater) OnFooter(h plumbing.Hash) error {
+ return nil
+}