@@ -76,10 +76,11 @@ func (pb *Packbuilder) WriteToFile(name string) error {
7676}
7777
7878func (pb * Packbuilder ) Write (w io.Writer ) error {
79- ch := pb .ForEach ()
79+ ch , stop := pb .ForEach ()
8080 for slice := range ch {
8181 _ , err := w .Write (slice )
8282 if err != nil {
83+ close (stop )
8384 return err
8485 }
8586 }
@@ -90,22 +91,40 @@ func (pb *Packbuilder) Written() uint32 {
9091 return uint32 (C .git_packbuilder_written (pb .ptr ))
9192}
9293
94+ type packbuilderCbData struct {
95+ ch chan <- []byte
96+ stop <- chan bool
97+ }
98+
9399//export packbuilderForEachCb
94100func packbuilderForEachCb (buf unsafe.Pointer , size C.size_t , payload unsafe.Pointer ) int {
95- ch := * (* chan []byte )(payload )
101+ data := (* packbuilderCbData )(payload )
102+ ch := data .ch
103+ stop := data .stop
96104
97105 slice := C .GoBytes (buf , C .int (size ))
98- ch <- slice
106+ select {
107+ case <- stop :
108+ return - 1
109+ case ch <- slice :
110+ }
111+
99112 return 0
100113}
101114
102- func (pb * Packbuilder ) forEachWrap (ch chan [] byte ) {
103- C ._go_git_packbuilder_foreach (pb .ptr , unsafe .Pointer (& ch ))
104- close (ch )
115+ func (pb * Packbuilder ) forEachWrap (data * packbuilderCbData ) {
116+ C ._go_git_packbuilder_foreach (pb .ptr , unsafe .Pointer (data ))
117+ close (data . ch )
105118}
106119
107- func (pb * Packbuilder ) ForEach () chan []byte {
108- ch := make (chan []byte , 0 )
109- go pb .forEachWrap (ch )
110- return ch
120+ // Foreach sends the packfile as slices through the "data" channel. If
121+ // you want to stop the pack-building process (e.g. there's an error
122+ // writing to the output), close or write a value into the "stop"
123+ // channel.
124+ func (pb * Packbuilder ) ForEach () (data <- chan []byte , stop chan <- bool ) {
125+ ch := make (chan []byte )
126+ stop := make (chan bool )
127+ data := packbuilderCbData {ch , stop }
128+ go pb .forEachWrap (& data )
129+ return ch , stop
111130}
0 commit comments