|
- package packp
-
- import (
- "bytes"
- "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 {
- ur := NewUploadRequest()
- return &UploadPackRequest{
- UploadHaves: UploadHaves{},
- UploadRequest: *ur,
- }
- }
-
- // 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 {
- ur := NewUploadRequestFromCapabilities(adv)
- return &UploadPackRequest{
- UploadHaves: UploadHaves{},
- UploadRequest: *ur,
- }
- }
-
- // 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. If flush is true, a flush
- // command will be encoded at the end of the writer content.
- func (u *UploadHaves) Encode(w io.Writer, flush bool) error {
- e := pktline.NewEncoder(w)
-
- plumbing.HashesSort(u.Haves)
-
- var last plumbing.Hash
- for _, have := range u.Haves {
- if bytes.Equal(last[:], have[:]) {
- continue
- }
-
- if err := e.Encodef("have %s\n", have); err != nil {
- return fmt.Errorf("sending haves for %q: %s", have, err)
- }
-
- last = have
- }
-
- if flush && len(u.Haves) != 0 {
- if err := e.Flush(); err != nil {
- return fmt.Errorf("sending flush-pkt after haves: %s", err)
- }
- }
-
- return nil
- }
|