diff options
Diffstat (limited to 'plumbing/protocol/packp/uppackreq.go')
-rw-r--r-- | plumbing/protocol/packp/uppackreq.go | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/plumbing/protocol/packp/uppackreq.go b/plumbing/protocol/packp/uppackreq.go new file mode 100644 index 0000000..2b1cb84 --- /dev/null +++ b/plumbing/protocol/packp/uppackreq.go @@ -0,0 +1,84 @@ +package packp + +import ( + "fmt" + "io" + + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/format/pktline" + "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability" +) + +// UploadPackRequest represents a upload-pack request. +// Zero-value is not safe, use NewUploadPackRequest instead. +type UploadPackRequest struct { + *UploadRequest + *UploadHaves +} + +// NewUploadPackRequest creates a new UploadPackRequest and returns a pointer. +func NewUploadPackRequest() *UploadPackRequest { + return &UploadPackRequest{ + UploadHaves: &UploadHaves{}, + UploadRequest: NewUploadRequest(), + } +} + +// NewUploadPackRequestFromCapabilities creates a new UploadPackRequest and +// returns a pointer. The request capabilities are filled with the most optiomal +// ones, based on the adv value (advertaised capabilities), the UploadPackRequest +// it has no wants, haves or shallows and an infinite depth +func NewUploadPackRequestFromCapabilities(adv *capability.List) *UploadPackRequest { + return &UploadPackRequest{ + UploadHaves: &UploadHaves{}, + UploadRequest: NewUploadRequestFromCapabilities(adv), + } +} + +// IsEmpty a request if empty if Haves are contained in the Wants, or if Wants +// length is zero +func (r *UploadPackRequest) IsEmpty() bool { + return isSubset(r.Wants, r.Haves) +} + +func isSubset(needle []plumbing.Hash, haystack []plumbing.Hash) bool { + for _, h := range needle { + found := false + for _, oh := range haystack { + if h == oh { + found = true + break + } + } + + if !found { + return false + } + } + + return true +} + +// UploadHaves is a message to signal the references that a client has in a +// upload-pack. Do not use this directly. Use UploadPackRequest request instead. +type UploadHaves struct { + Haves []plumbing.Hash +} + +// Encode encodes the UploadHaves into the Writer. +func (u *UploadHaves) Encode(w io.Writer) error { + e := pktline.NewEncoder(w) + for _, have := range u.Haves { + if err := e.Encodef("have %s\n", have); err != nil { + return fmt.Errorf("sending haves for %q: %s", have, err) + } + } + + if len(u.Haves) != 0 { + if err := e.Flush(); err != nil { + return fmt.Errorf("sending flush-pkt after haves: %s", err) + } + } + + return nil +} |