diff options
Diffstat (limited to 'formats/packfile/parser.go')
-rw-r--r-- | formats/packfile/parser.go | 89 |
1 files changed, 42 insertions, 47 deletions
diff --git a/formats/packfile/parser.go b/formats/packfile/parser.go index a7c4047..8b7a692 100644 --- a/formats/packfile/parser.go +++ b/formats/packfile/parser.go @@ -8,7 +8,6 @@ import ( "io" "gopkg.in/src-d/go-git.v4/core" - "gopkg.in/src-d/go-git.v4/storage/memory" ) var ( @@ -30,6 +29,7 @@ const ( // Values from this type are not zero-value safe. See the NewParser function bellow. type Parser struct { ReadRecaller + ObjectFactory func() core.Object } // NewParser returns a new Parser that reads from the packfile represented by r. @@ -174,47 +174,43 @@ func moreBytesInLength(c byte) bool { // ReadObject reads and returns a git object from an object entry in the packfile. // Non-deltified and deltified objects are supported. -func (p Parser) ReadObject() (core.Object, error) { +func (p Parser) FillObject(obj core.Object) error { start, err := p.Offset() if err != nil { - return nil, err + return err } - var typ core.ObjectType - typ, _, err = p.ReadObjectTypeAndLength() + t, l, err := p.ReadObjectTypeAndLength() if err != nil { - return nil, err + return err } - var cont []byte - switch typ { + obj.SetSize(l) + + switch t { case core.CommitObject, core.TreeObject, core.BlobObject, core.TagObject: - cont, err = p.ReadNonDeltaObjectContent() + obj.SetType(t) + err = p.ReadNonDeltaObjectContent(obj) case core.REFDeltaObject: - cont, typ, err = p.ReadREFDeltaObjectContent() + err = p.ReadREFDeltaObjectContent(obj) case core.OFSDeltaObject: - cont, typ, err = p.ReadOFSDeltaObjectContent(start) + err = p.ReadOFSDeltaObjectContent(obj, start) default: - err = ErrInvalidObject.AddDetails("tag %q", typ) - } - if err != nil { - return nil, err + err = ErrInvalidObject.AddDetails("tag %q", t) } - return memory.NewObject(typ, int64(len(cont)), cont), nil + return err } // ReadNonDeltaObjectContent reads and returns a non-deltified object // from it zlib stream in an object entry in the packfile. -func (p Parser) ReadNonDeltaObjectContent() ([]byte, error) { - return p.readZip() -} - -func (p Parser) readZip() ([]byte, error) { - buf := bytes.NewBuffer(nil) - err := p.inflate(buf) +func (p Parser) ReadNonDeltaObjectContent(obj core.Object) error { + w, err := obj.Writer() + if err != nil { + return err + } - return buf.Bytes(), err + return p.inflate(w) } func (p Parser) inflate(w io.Writer) (err error) { @@ -239,23 +235,23 @@ func (p Parser) inflate(w io.Writer) (err error) { // ReadREFDeltaObjectContent reads and returns an object specified by a // REF-Delta entry in the packfile, form the hash onwards. -func (p Parser) ReadREFDeltaObjectContent() ([]byte, core.ObjectType, error) { +func (p Parser) ReadREFDeltaObjectContent(obj core.Object) error { refHash, err := p.ReadHash() if err != nil { - return nil, core.ObjectType(0), err + return err } - refObj, err := p.RecallByHash(refHash) + base, err := p.RecallByHash(refHash) if err != nil { - return nil, core.ObjectType(0), err + return err } - content, err := p.ReadSolveDelta(refObj.Content()) - if err != nil { - return nil, refObj.Type(), err + obj.SetType(base.Type()) + if err := p.ReadAndApplyDelta(obj, base); err != nil { + return err } - return content, refObj.Type(), nil + return nil } // ReadHash reads a hash. @@ -268,41 +264,40 @@ func (p Parser) ReadHash() (core.Hash, error) { return h, nil } -// ReadSolveDelta reads and returns the base patched with the contents +// ReadAndSolveDelta reads and returns the base patched with the contents // of a zlib compressed diff data in the delta portion of an object // entry in the packfile. -func (p Parser) ReadSolveDelta(base []byte) ([]byte, error) { - diff, err := p.readZip() - if err != nil { - return nil, err +func (p Parser) ReadAndApplyDelta(target, base core.Object) error { + buf := bytes.NewBuffer(nil) + if err := p.inflate(buf); err != nil { + return err } - return PatchDelta(base, diff), nil + return ApplyDelta(target, base, buf.Bytes()) } // ReadOFSDeltaObjectContent reads an returns an object specified by an // OFS-delta entry in the packfile from it negative offset onwards. The // start parameter is the offset of this particular object entry (the // current offset minus the already processed type and length). -func (p Parser) ReadOFSDeltaObjectContent(start int64) ( - []byte, core.ObjectType, error) { +func (p Parser) ReadOFSDeltaObjectContent(obj core.Object, start int64) error { jump, err := p.ReadNegativeOffset() if err != nil { - return nil, core.ObjectType(0), err + return err } - ref, err := p.RecallByOffset(start + jump) + base, err := p.RecallByOffset(start + jump) if err != nil { - return nil, core.ObjectType(0), err + return err } - content, err := p.ReadSolveDelta(ref.Content()) - if err != nil { - return nil, ref.Type(), err + obj.SetType(base.Type()) + if err := p.ReadAndApplyDelta(obj, base); err != nil { + return err } - return content, ref.Type(), nil + return nil } // ReadNegativeOffset reads and returns an offset from a OFS DELTA |