本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.4KB

  1. package packp
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "gopkg.in/src-d/go-git.v4/plumbing"
  7. "gopkg.in/src-d/go-git.v4/plumbing/format/pktline"
  8. "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability"
  9. )
  10. // UploadPackRequest represents a upload-pack request.
  11. // Zero-value is not safe, use NewUploadPackRequest instead.
  12. type UploadPackRequest struct {
  13. UploadRequest
  14. UploadHaves
  15. }
  16. // NewUploadPackRequest creates a new UploadPackRequest and returns a pointer.
  17. func NewUploadPackRequest() *UploadPackRequest {
  18. ur := NewUploadRequest()
  19. return &UploadPackRequest{
  20. UploadHaves: UploadHaves{},
  21. UploadRequest: *ur,
  22. }
  23. }
  24. // NewUploadPackRequestFromCapabilities creates a new UploadPackRequest and
  25. // returns a pointer. The request capabilities are filled with the most optiomal
  26. // ones, based on the adv value (advertaised capabilities), the UploadPackRequest
  27. // it has no wants, haves or shallows and an infinite depth
  28. func NewUploadPackRequestFromCapabilities(adv *capability.List) *UploadPackRequest {
  29. ur := NewUploadRequestFromCapabilities(adv)
  30. return &UploadPackRequest{
  31. UploadHaves: UploadHaves{},
  32. UploadRequest: *ur,
  33. }
  34. }
  35. // IsEmpty a request if empty if Haves are contained in the Wants, or if Wants
  36. // length is zero
  37. func (r *UploadPackRequest) IsEmpty() bool {
  38. return isSubset(r.Wants, r.Haves)
  39. }
  40. func isSubset(needle []plumbing.Hash, haystack []plumbing.Hash) bool {
  41. for _, h := range needle {
  42. found := false
  43. for _, oh := range haystack {
  44. if h == oh {
  45. found = true
  46. break
  47. }
  48. }
  49. if !found {
  50. return false
  51. }
  52. }
  53. return true
  54. }
  55. // UploadHaves is a message to signal the references that a client has in a
  56. // upload-pack. Do not use this directly. Use UploadPackRequest request instead.
  57. type UploadHaves struct {
  58. Haves []plumbing.Hash
  59. }
  60. // Encode encodes the UploadHaves into the Writer. If flush is true, a flush
  61. // command will be encoded at the end of the writer content.
  62. func (u *UploadHaves) Encode(w io.Writer, flush bool) error {
  63. e := pktline.NewEncoder(w)
  64. plumbing.HashesSort(u.Haves)
  65. var last plumbing.Hash
  66. for _, have := range u.Haves {
  67. if bytes.Equal(last[:], have[:]) {
  68. continue
  69. }
  70. if err := e.Encodef("have %s\n", have); err != nil {
  71. return fmt.Errorf("sending haves for %q: %s", have, err)
  72. }
  73. last = have
  74. }
  75. if flush && len(u.Haves) != 0 {
  76. if err := e.Flush(); err != nil {
  77. return fmt.Errorf("sending flush-pkt after haves: %s", err)
  78. }
  79. }
  80. return nil
  81. }
上海开阖软件有限公司 沪ICP备12045867号-1