func (p *revParser) Parse() error { e := util.SafeParse(func() { if p.rev == "" { util.PanicErr("revision spec is empty") } if p.PeekByte() == ':' { util.PanicErr(": syntaxes not supported") // TODO } start := p.Count() // read until modifier or end for !p.EOF() { if !isModifier(p.PeekByte()) { p.ReadByte() } else { break } } end := p.Count() rev := p.rev[start:end] if rev == "" { util.PanicErr("revision is empty") } err := p.findObject(rev) if err != nil { util.PanicErr(err.Error()) } for !p.EOF() { var err error b := p.ReadByte() if b == '^' { if !p.EOF() && p.PeekByte() == '{' { p.ConsumeByte('{') otype := objects.ObjectType(p.ConsumeStrings(token.ObjectTypes)) err = applyDereference(p, otype) if err != nil { } p.ConsumeByte('}') } else { err = applyParentFunc(p, CommitNthParent) } } else if b == '~' { err = applyParentFunc(p, CommitNthAncestor) } else { util.PanicErrf("unexpected modifier: '%s'", string(b)) } if err != nil { util.PanicErr(err.Error()) } } }) return e }
func (p *objectParser) parseTag() *objects.Tag { p.ResetCount() // read the object id p.ConsumeString(markerObject) p.ConsumeByte(token.SP) target := p.ParseOid() p.ConsumeByte(token.LF) // read object type p.ConsumeString(markerType) p.ConsumeByte(token.SP) t := objects.ObjectType(p.ConsumeStrings(token.ObjectTypes)) p.ConsumeByte(token.LF) // read the tag name p.ConsumeString(markerTag) p.ConsumeByte(token.SP) name := p.ReadString(token.LF) // gets rid of the LF! // read the tagger tagger := p.parseWhoWhen(markerTagger) p.ConsumeByte(token.LF) // read the commit message p.ConsumeByte(token.LF) msg := p.String() if p.Count() != p.hdr.Size() { util.PanicErr("payload doesn't match prescibed size") } return objects.NewTag(p.oid, target, t, p.hdr, name, msg, tagger) }
func (p *Pack) parseDeltaEntry(bytes []byte, pot PackedObjectType, oid *objects.ObjectId, i int) *PackedObject { var ( deltaDeflated packedDelta baseOffset int64 dp *packedObjectParser err error ) e := p.idx.entries[i] switch pot { case ObjectRefDelta: var oid *objects.ObjectId deltaDeflated, oid = readPackedRefDelta(bytes) e := p.idx.entryById(oid) if e == nil { util.PanicErrf("nil entry for base object with id %s", oid.String()) } baseOffset = e.offset case ObjectOffsetDelta: if deltaDeflated, baseOffset, err = readPackedOffsetDelta(bytes); err != nil { util.PanicErrf("Err parsing size: %v. Could not determine size for %s", err, e.String()) } baseOffset = e.offset - baseOffset } base := p.findObjectByOffset(baseOffset) bytes = []byte(deltaDeflated) if dp, err = newPackedObjectParser(bytes, oid); err != nil { util.PanicErr(err.Error()) } return dp.applyDelta(base, oid) }
// parseBlob parses the payload of a binary blob object // and converts it to Blob. If there are parsing errors, // it panics with parseErr, so this method should be // called as a parameter a safeParse(). func (p *objectParser) parseBlob() *objects.Blob { p.ResetCount() data := p.Bytes() b := objects.NewBlob(p.oid, p.hdr, data) if p.Count() != p.hdr.Size() { util.PanicErr("payload doesn't match prescibed size") } return b }
func parseNonDeltaEntry(bytes []byte, pot PackedObjectType, oid *objects.ObjectId, size int64) (po *PackedObject) { var ( dp *packedObjectParser err error ) if dp, err = newPackedObjectParser(bytes, oid); err != nil { util.PanicErr(err.Error()) } else if int64(len(dp.bytes)) != size { util.PanicErrf("Expected object of %d bytes but found %d bytes", size, len(dp.bytes)) } switch pot { case PackedBlob: po = dp.parseBlob(size) case PackedCommit: po = dp.parseCommit(size) case PackedTree: po = dp.parseTree(size) case PackedTag: po = dp.parseTag(size) } return }
func (p *objectParser) parseCommit() *objects.Commit { parents := make([]*objects.ObjectId, 0) p.ResetCount() // read the tree line p.ConsumeString(markerTree) p.ConsumeByte(token.SP) treeOid := p.ParseOid() p.ConsumeByte(token.LF) // read an arbitrary number of parent lines n := len(markerParent) for p.PeekString(n) == markerParent { p.ConsumeString(markerParent) p.ConsumeByte(token.SP) parents = append(parents, p.ParseOid()) p.ConsumeByte(token.LF) } // parse author author := p.parseWhoWhen(markerAuthor) p.ConsumeByte(token.LF) // parse committer committer := p.parseWhoWhen(markerCommitter) p.ConsumeByte(token.LF) // commit message p.ConsumeByte(token.LF) message := p.String() if p.Count() != p.hdr.Size() { util.PanicErr("payload doesn't match prescibed size") } return objects.NewCommit(p.oid, treeOid, p.hdr.Size(), parents, author, committer, message) }