Seek sets the offset for the next read or write operation according to whence, which should be one of SeekStart, SeekAbsolute, SeekEnd, or SeekCurrent. When seeking relative to the end, the offset is subtracted from the current offset. Note that for historical reasons, these do not align with the us
(offset int64, whence int)
| 627 | // as in lseek(2) or os.Seek. |
| 628 | // The method returns the new absolute offset of the connection. |
| 629 | func (c *Conn) Seek(offset int64, whence int) (int64, error) { |
| 630 | seekDontCheck := (whence & SeekDontCheck) != 0 |
| 631 | whence &= ^SeekDontCheck |
| 632 | |
| 633 | switch whence { |
| 634 | case SeekStart, SeekAbsolute, SeekEnd, SeekCurrent: |
| 635 | default: |
| 636 | return 0, fmt.Errorf("whence must be one of 0, 1, 2, or 3. (whence = %d)", whence) |
| 637 | } |
| 638 | |
| 639 | if seekDontCheck { |
| 640 | if whence == SeekAbsolute { |
| 641 | c.mutex.Lock() |
| 642 | c.offset = offset |
| 643 | c.mutex.Unlock() |
| 644 | return offset, nil |
| 645 | } |
| 646 | |
| 647 | if whence == SeekCurrent { |
| 648 | c.mutex.Lock() |
| 649 | c.offset += offset |
| 650 | offset = c.offset |
| 651 | c.mutex.Unlock() |
| 652 | return offset, nil |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | if whence == SeekAbsolute { |
| 657 | c.mutex.Lock() |
| 658 | unchanged := offset == c.offset |
| 659 | c.mutex.Unlock() |
| 660 | if unchanged { |
| 661 | return offset, nil |
| 662 | } |
| 663 | } |
| 664 | |
| 665 | if whence == SeekCurrent { |
| 666 | c.mutex.Lock() |
| 667 | offset = c.offset + offset |
| 668 | c.mutex.Unlock() |
| 669 | } |
| 670 | |
| 671 | first, last, err := c.ReadOffsets() |
| 672 | if err != nil { |
| 673 | return 0, err |
| 674 | } |
| 675 | |
| 676 | switch whence { |
| 677 | case SeekStart: |
| 678 | offset = first + offset |
| 679 | case SeekEnd: |
| 680 | offset = last - offset |
| 681 | } |
| 682 | |
| 683 | if offset < first || offset > last { |
| 684 | return 0, OffsetOutOfRange |
| 685 | } |
| 686 |