(dst io.Writer, base io.ReaderAt, delta io.Reader, typ plumbing.ObjectType, writeHeader objectHeaderWriter)
| 324 | } |
| 325 | |
| 326 | func patchDeltaWriter(dst io.Writer, base io.ReaderAt, delta io.Reader, |
| 327 | typ plumbing.ObjectType, writeHeader objectHeaderWriter) (uint, plumbing.Hash, error) { |
| 328 | deltaBuf := bufio.NewReaderSize(delta, 1024) |
| 329 | srcSz, err := decodeLEB128ByteReader(deltaBuf) |
| 330 | if err != nil { |
| 331 | if err == io.EOF { |
| 332 | return 0, plumbing.ZeroHash, ErrInvalidDelta |
| 333 | } |
| 334 | return 0, plumbing.ZeroHash, err |
| 335 | } |
| 336 | |
| 337 | if r, ok := base.(*bytes.Reader); ok && srcSz != uint(r.Size()) { |
| 338 | return 0, plumbing.ZeroHash, ErrInvalidDelta |
| 339 | } |
| 340 | |
| 341 | targetSz, err := decodeLEB128ByteReader(deltaBuf) |
| 342 | if err != nil { |
| 343 | if err == io.EOF { |
| 344 | return 0, plumbing.ZeroHash, ErrInvalidDelta |
| 345 | } |
| 346 | return 0, plumbing.ZeroHash, err |
| 347 | } |
| 348 | |
| 349 | // If header still needs to be written, caller will provide |
| 350 | // a LazyObjectWriterHeader. This seems to be the case when |
| 351 | // dealing with thin-packs. |
| 352 | if writeHeader != nil { |
| 353 | err = writeHeader(typ, int64(targetSz)) |
| 354 | if err != nil { |
| 355 | return 0, plumbing.ZeroHash, fmt.Errorf("could not lazy write header: %w", err) |
| 356 | } |
| 357 | } |
| 358 | |
| 359 | remainingTargetSz := targetSz |
| 360 | |
| 361 | hasher := plumbing.NewHasher(typ, int64(targetSz)) |
| 362 | mw := io.MultiWriter(dst, hasher) |
| 363 | |
| 364 | bufp := sync.GetByteSlice() |
| 365 | defer sync.PutByteSlice(bufp) |
| 366 | |
| 367 | sr := io.NewSectionReader(base, int64(0), int64(srcSz)) |
| 368 | // Keep both the io.LimitedReader types, so we can reset N. |
| 369 | baselr := io.LimitReader(sr, 0).(*io.LimitedReader) |
| 370 | deltalr := io.LimitReader(deltaBuf, 0).(*io.LimitedReader) |
| 371 | |
| 372 | for remainingTargetSz > 0 { |
| 373 | buf := *bufp |
| 374 | cmd, err := deltaBuf.ReadByte() |
| 375 | if err == io.EOF { |
| 376 | return 0, plumbing.ZeroHash, ErrInvalidDelta |
| 377 | } |
| 378 | if err != nil { |
| 379 | return 0, plumbing.ZeroHash, err |
| 380 | } |
| 381 | |
| 382 | if isCopyFromSrc(cmd) { |
| 383 | offset, err := decodeOffsetByteReader(cmd, deltaBuf) |
no test coverage detected
searching dependent graphs…