Seek sets the offset for the next Read or Write to offset, interpreted according to whence: 0 means relative to the origin of the file, 1 means relative to the current offset, and 2 means relative to the end. Seek returns the new offset and an error, if any. Seeking to a negative offset is an error
(offset int64, whence int)
| 545 | // offset is legal, subsequent io operations succeed until the |
| 546 | // underlying object is not closed. |
| 547 | func (o *Object) Seek(offset int64, whence int) (n int64, err error) { |
| 548 | if o == nil { |
| 549 | return 0, errInvalidArgument("Object is nil") |
| 550 | } |
| 551 | |
| 552 | // Locking. |
| 553 | o.mutex.Lock() |
| 554 | defer o.mutex.Unlock() |
| 555 | |
| 556 | // At EOF seeking is legal allow only io.EOF, for any other errors we return. |
| 557 | if o.prevErr != nil && o.prevErr != io.EOF { |
| 558 | return 0, o.prevErr |
| 559 | } |
| 560 | |
| 561 | // Negative offset is valid for whence of '2'. |
| 562 | if offset < 0 && whence != 2 { |
| 563 | return 0, errInvalidArgument(fmt.Sprintf("Negative position not allowed for %d", whence)) |
| 564 | } |
| 565 | |
| 566 | // This is the first request. So before anything else |
| 567 | // get the ObjectInfo. |
| 568 | if !o.isStarted || !o.objectInfoSet { |
| 569 | // Create the new Seek request. |
| 570 | seekReq := getRequest{ |
| 571 | isReadOp: false, |
| 572 | Offset: offset, |
| 573 | isFirstReq: true, |
| 574 | } |
| 575 | // Send and receive from the seek request. |
| 576 | _, err := o.doGetRequest(seekReq) |
| 577 | if err != nil { |
| 578 | // Save the error. |
| 579 | o.prevErr = err |
| 580 | return 0, err |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | newOffset := o.currOffset |
| 585 | |
| 586 | // Switch through whence. |
| 587 | switch whence { |
| 588 | default: |
| 589 | return 0, errInvalidArgument(fmt.Sprintf("Invalid whence %d", whence)) |
| 590 | case 0: |
| 591 | if o.objectInfo.Size > -1 && offset > o.objectInfo.Size { |
| 592 | return 0, io.EOF |
| 593 | } |
| 594 | newOffset = offset |
| 595 | case 1: |
| 596 | if o.objectInfo.Size > -1 && o.currOffset+offset > o.objectInfo.Size { |
| 597 | return 0, io.EOF |
| 598 | } |
| 599 | newOffset += offset |
| 600 | case 2: |
| 601 | // If we don't know the object size return an error for io.SeekEnd |
| 602 | if o.objectInfo.Size < 0 { |
| 603 | return 0, errInvalidArgument("Whence END is not supported when the object size is unknown") |
| 604 | } |
no test coverage detected