lib/care.rb
# Returns the maximum possible byte string that can be
# recovered from the given `io` at the given offset.
# If the IO has been exhausted, `nil` will be returned
# instead. Will use the cached pages where available,
# or fetch pages where necessary
#
# @param io[#seek, #read] the IO to read data from
# @param at[Integer] at which offset we have to read
# @param n_bytes[Integer] how many bytes we want to read/cache
# @return [String, nil] the content read from the IO or `nil` if no data was available
# @raise ArgumentError
Returns the maximum possible byte string that can be
recovered from the given `io` at the given offset.
If the IO has been exhausted, `nil` will be returned
instead. Will use the cached pages where available,
or fetch pages where necessary
Returns the maximum possible byte string that can be recovered from the given ` io ` at the given offset . If the IO has been exhausted ` nil ` will be returned instead . Will use the cached pages where available or fetch pages where necessary
def byteslice(io, at, n_bytes)
      if n_bytes < 1
        raise ArgumentError, "The number of bytes to fetch must be a positive Integer, but was #{n_bytes}"
      end
      if at < 0
        raise ArgumentError, "Negative offsets are not supported (got #{at})"
      end
      first_page = at / @page_size
      last_page = (at + n_bytes) / @page_size
      relevant_pages = (first_page..last_page).map { |i| hydrate_page(io, i) }
      slab = if relevant_pages.length > 1
        relevant_pages.join
      else 
        relevant_pages.first || ''
      end
      offset_in_slab = at % @page_size
      slice = slab.byteslice(offset_in_slab, n_bytes)
      slice if slice && !slice.empty?
    end
def byteslice ( io , at , n_bytes ) if n_bytes < 1 raise ArgumentError , "The number of bytes to fetch must be a positive Integer, but was #{n_bytes}" end if at < 0 raise ArgumentError , "Negative offsets are not supported (got #{at})" end first_page = at / @page_size last_page = ( at + n_bytes ) / @page_size relevant_pages = ( first_page .. last_page ) . map { | i | hydrate_page ( io , i ) } slab = if relevant_pages . length > 1 relevant_pages . join else relevant_pages . first || '' end offset_in_slab = at % @page_size slice = slab . byteslice ( offset_in_slab , n_bytes ) slice if slice && ! slice . empty? end
Returns the maximum possible byte string that can be
recovered from the given `io` at the given offset.
Returns the maximum possible byte string that can be recovered from the given ` io ` at the given offset .
# Create one string combining all the pages which are relevant for # us - it is much easier to address that string instead of piecing # the output together page by page, and joining arrays of strings # is supposed to be optimized. # If our read overlaps multiple pages, we do have to join them, this is # the general case # We only have one page # Optimize a little. If we only have one page that we need to read from # - which is likely going to be the case *often* we can avoid allocating # a new string for the joined pages and juse use the only page # directly as the slab. Since it might contain a `nil` and we do # not join (which casts nils to strings) we take care of that too # Returning an empty string from read() is very confusing for the caller, # and no builtins do this - if we are at EOF we should return nil
the content read from the IO or `nil` if no data was available
the content read from the IO or ` nil ` if no data was available
String, nil
None
io
the IO to read data from
the IO to read data from
at
at which offset we have to read
at which offset we have to read
n_bytes
None