func choosePartRange(partIndex int, offset int64, info *uploadInfo) (p0, p1 int64, err error) {
	if offset >= info.size {
		return info.size, info.size, errFinished
	}
	if partIndex < len(info.Parts.Parts) {
		if part := info.Parts.Parts[partIndex]; part.Complete {
			if part.Offset != offset {
				return 0, 0, errgo.Newf("offset mismatch at part %d (want %d got %d)", partIndex, offset, part.Offset)
			}
			return offset, offset + part.Size, errAlreadyUploaded
		}
	}

	nextOffset := info.size
	nextUploadedPart := -1
	// Find the offset of the next uploaded part, if any.
	for i := partIndex + 1; i < len(info.Parts.Parts); i++ {
		if info.Parts.Parts[i].Valid() {
			nextOffset = info.Parts.Parts[i].Offset
			nextUploadedPart = i
			break
		}
	}
	if nextUploadedPart == partIndex+1 {
		// Exactly one part to fill in.
		p0, p1 = offset, nextOffset
		if p1-p0 < info.MinPartSize {
			return 0, 0, errgo.Newf("remaining part is too small")
		}
		if p1-p0 > info.MaxPartSize {
			return 0, 0, errgo.Newf("remaining part is too large")
		}
		return p0, p1, nil
	}
	if nextUploadedPart == -1 {
		// No next part, so we can choose for ourselves.
		p0 = offset
		p1 = offset + info.preferredPartSize
		if p1 > info.size {
			p1 = info.size
		}
		return p0, p1, nil
	}
	// There's an already-uploaded part more than one away, so
	// divide it equally (rounding errors will be allocated to the last
	// part, which should be dealt with by the "exactly one part" case
	// above).
	partSize := (nextOffset - offset) / int64(nextUploadedPart-partIndex)
	return offset, offset + partSize, nil
}
// choosePartRange returns the file range to use for the part with the given index.
// It returns errAlreadyUploaded if the part is complete and errFinished if the part is
// at the end.
choosePartRange returns the file range to use for the part with the given index.
It returns errAlreadyUploaded if the part is complete and errFinished if the part is
at the end.
// choosePartRange returns the file range to use for the part with the given index . // It returns errAlreadyUploaded if the part is complete and errFinished if the part is // at the end .
func choosePartRange(partIndex int, offset int64, info *uploadInfo) (p0, p1 int64, err error) {
	if offset >= info.size {
		return info.size, info.size, errFinished
	}
	if partIndex < len(info.Parts.Parts) {
		if part := info.Parts.Parts[partIndex]; part.Complete {
			if part.Offset != offset {
				return 0, 0, errgo.Newf("offset mismatch at part %d (want %d got %d)", partIndex, offset, part.Offset)
			}
			return offset, offset + part.Size, errAlreadyUploaded
		}
	}
	nextOffset := info.size
	nextUploadedPart := -1
	for i := partIndex + 1; i < len(info.Parts.Parts); i++ {
		if info.Parts.Parts[i].Valid() {
			nextOffset = info.Parts.Parts[i].Offset
			nextUploadedPart = i
			break
		}
	}
	if nextUploadedPart == partIndex+1 {
		p0, p1 = offset, nextOffset
		if p1-p0 < info.MinPartSize {
			return 0, 0, errgo.Newf("remaining part is too small")
		}
		if p1-p0 > info.MaxPartSize {
			return 0, 0, errgo.Newf("remaining part is too large")
		}
		return p0, p1, nil
	}
	if nextUploadedPart == -1 {
		p0 = offset
		p1 = offset + info.preferredPartSize
		if p1 > info.size {
			p1 = info.size
		}
		return p0, p1, nil
	}
	partSize := (nextOffset - offset) / int64(nextUploadedPart-partIndex)
	return offset, offset + partSize, nil
}
func choosePartRange ( partIndex int , offset int64 , info * uploadInfo ) ( p0 , p1 int64 , err error ) { if offset >= info . size { return info . size , info . size , errFinished } if partIndex < len ( info . Parts . Parts ) { if part := info . Parts . Parts [ partIndex ] ; part . Complete { if part . Offset != offset { return 0 , 0 , errgo . Newf ( " " , partIndex , offset , part . Offset ) } return offset , offset + part . Size , errAlreadyUploaded } } nextOffset := info . size nextUploadedPart := - 1 for i := partIndex + 1 ; i < len ( info . Parts . Parts ) ; i ++ { if info . Parts . Parts [ i ] . Valid ( ) { nextOffset = info . Parts . Parts [ i ] . Offset nextUploadedPart = i break } } if nextUploadedPart == partIndex + 1 { p0 , p1 = offset , nextOffset if p1 - p0 < info . MinPartSize { return 0 , 0 , errgo . Newf ( " " ) } if p1 - p0 > info . MaxPartSize { return 0 , 0 , errgo . Newf ( " " ) } return p0 , p1 , nil } if nextUploadedPart == - 1 { p0 = offset p1 = offset + info . preferredPartSize if p1 > info . size { p1 = info . size } return p0 , p1 , nil } partSize := ( nextOffset - offset ) / int64 ( nextUploadedPart - partIndex ) return offset , offset + partSize , nil }
choosePartRange returns the file range to use for the part with the given index.
choosePartRange returns the file range to use for the part with the given index .
// Find the offset of the next uploaded part, if any. // Exactly one part to fill in. // No next part, so we can choose for ourselves. // There's an already-uploaded part more than one away, so // divide it equally (rounding errors will be allocated to the last // part, which should be dealt with by the "exactly one part" case // above).