public function seek($offset, $whence) {
    if ($whence == SEEK_END) {
      if (isset($this->object_total_length)) {
        $whence = SEEK_SET;
        $offset = $this->object_total_length + $offset;
      } else {
        trigger_error("Unable to seek from end for objects with unknown size",
                      E_USER_WARNING);
        return false;
      }
    }

    if ($whence != SEEK_SET) {
      trigger_error(sprintf("Unsupported seek mode: %d", $whence),
                    E_USER_WARNING);
      return false;
    }
    // If we know the size, then make sure they are only seeking within it.
    if (isset($this->object_total_length) &&
        $offset >= $this->object_total_length) {
      return false;
    }
    if ($offset < 0) {
      return false;
    }
    // Clear EOF and work it out next time they read.
    $this->eof = false;

    // Check if we can seek inside the current buffer
    $block_start = $this->object_block_start_position;
    $buffer_end = $block_start + strlen($this->read_buffer);
    if ($block_start <= $offset && $offset < $buffer_end) {
      $this->buffer_read_position = $offset - $block_start;
    } else {
      $this->read_buffer = "";
      $this->buffer_read_position = 0;
      $this->next_read_position = $offset;
    }
    return true;
  }