code: def _blk_read_lims(start, stop, buf_len):
      """Deal with indexing in the middle of a data block.
  
      Parameters
      ----------
      start : int
          Starting index.
      stop : int
          Ending index (exclusive).
      buf_len : int
          Buffer size in samples.
  
      Returns
      -------
      block_start_idx : int
          The first block to start reading from.
      r_lims : list
          The read limits.
      d_lims : list
          The write limits.
  
      Notes
      -----
      Consider this example::
  
          >>> start, stop, buf_len = 2, 27, 10
  
                      +---------+---------+---------
      File structure: |  buf0   |   buf1  |   buf2  |
                      +---------+---------+---------
      File time:      0        10        20        30
                      +---------+---------+---------
      Requested time:   2                       27
  
                      |                             |
                  blockstart                    blockstop
                        |                        |
                      start                    stop
  
      We need 27 - 2 = 25 samples (per channel) to store our data, and
      we need to read from 3 buffers (30 samples) to get all of our data.
  
      On all reads but the first, the data we read starts at
      the first sample of the buffer. On all reads but the last,
      the data we read ends on the last sample of the buffer.
  
      We call ``this_data`` the variable that stores the current buffer's data,
      and ``data`` the variable that stores the total output.
  
      On the first read, we need to do this::
  
          >>> data[0:buf_len-2] = this_data[2:buf_len]  # doctest: +SKIP
  
      On the second read, we need to do::
  
          >>> data[1*buf_len-2:2*buf_len-2] = this_data[0:buf_len]  # doctest: +SKIP
  
      On the final read, we need to do::
  
          >>> data[2*buf_len-2:3*buf_len-2-3] = this_data[0:buf_len-3]  # doctest: +SKIP
  
      This function encapsulates this logic to allow a loop over blocks, where
      data is stored using the following limits::
  
          >>> data[d_lims[ii, 0]:d_lims[ii, 1]] = this_data[r_lims[ii, 0]:r_lims[ii, 1]]  # doctest: +SKIP
  
      """  # noqa: E501
      # this is used to deal with indexing in the middle of a sampling period
      assert all(isinstance(x, int) for x in (start, stop, buf_len))
      block_start_idx = start // buf_len
      block_start = block_start_idx * buf_len
      last_used_samp = stop - 1
      block_stop = last_used_samp - last_used_samp % buf_len + buf_len
      read_size = block_stop - block_start
      n_blk = read_size // buf_len + (read_size % buf_len != 0)
      start_offset = start - block_start
      end_offset = block_stop - stop
      d_lims = np.empty((n_blk, 2), int)
      r_lims = np.empty((n_blk, 2), int)
      for bi in range(n_blk):
          # Triage start (sidx) and end (eidx) indices for
          # data (d) and read (r)
          if bi == 0:
              d_sidx = 0
              r_sidx = start_offset
          else:
              d_sidx = bi * buf_len - start_offset
              r_sidx = 0
          if bi == n_blk - 1:
              d_eidx = stop - start
              r_eidx = buf_len - end_offset
          else:
              d_eidx = (bi + 1) * buf_len - start_offset
              r_eidx = buf_len
          d_lims[bi] = [d_sidx, d_eidx]
          r_lims[bi] = [r_sidx, r_eidx]
      return block_start_idx, r_lims, d_lims
  
file_path: mne-python/mne/_fiff/utils.py
imports: import os
  import os.path
  import numpy
  from .constants import FIFF
  from .meas_info import _get_valid_units
label_desc: Use image node_id 4 for calling a global function with example usage: _blk_read_lims(start, stop, buf_len) and returns: block_start_idx,  r_lims,  d_lims