%a{annotate:rdoc:skip}
module Zlib
  # <!-- rdoc-file=ext/zlib/zlib.c -->
  # Zlib::GzipReader is the class for reading a gzipped file.  GzipReader should
  # be used as an IO, or -IO-like, object.
  #
  #     Zlib::GzipReader.open('hoge.gz') {|gz|
  #       print gz.read
  #     }
  #
  #     File.open('hoge.gz') do |f|
  #       gz = Zlib::GzipReader.new(f)
  #       print gz.read
  #       gz.close
  #     end
  #
  # ## Method Catalogue
  #
  # The following methods in Zlib::GzipReader are just like their counterparts in
  # IO, but they raise Zlib::Error or Zlib::GzipFile::Error exception if an error
  # was found in the gzip file.
  # *   #each
  # *   #each_line
  # *   #each_byte
  # *   #gets
  # *   #getc
  # *   #lineno
  # *   #lineno=
  # *   #read
  # *   #readchar
  # *   #readline
  # *   #readlines
  # *   #ungetc
  #
  # Be careful of the footer of the gzip file. A gzip file has the checksum of
  # pre-compressed data in its footer. GzipReader checks all uncompressed data
  # against that checksum at the following cases, and if it fails, raises
  # `Zlib::GzipFile::NoFooter`, `Zlib::GzipFile::CRCError`, or
  # `Zlib::GzipFile::LengthError` exception.
  #
  # *   When an reading request is received beyond the end of file (the end of
  #     compressed data). That is, when Zlib::GzipReader#read,
  #     Zlib::GzipReader#gets, or some other methods for reading returns nil.
  # *   When Zlib::GzipFile#close method is called after the object reaches the
  #     end of file.
  # *   When Zlib::GzipReader#unused method is called after the object reaches the
  #     end of file.
  #
  # The rest of the methods are adequately described in their own documentation.
  #
  class GzipReader < Zlib::GzipFile
    include Enumerable[String]

    def self.wrap: (IO io) -> instance
                 | (IO io) { (instance gz) -> void } -> void

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - Zlib::GzipReader.open(filename) {|gz| ... }
    # -->
    # Opens a file specified by `filename` as a gzipped file, and returns a
    # GzipReader object associated with that file.  Further details of this method
    # are in Zlib::GzipReader.new and ZLib::GzipFile.wrap.
    #
    def self.open: (String | _ToPath filename) -> instance
                 | (String | _ToPath filename) { (instance gz) -> void } -> void

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - Zlib::GzipReader.zcat(io, options = {}, &block) => nil
    #   - Zlib::GzipReader.zcat(io, options = {}) => string
    # -->
    # Decompresses all gzip data in the `io`, handling multiple gzip streams until
    # the end of the `io`.  There should not be any non-gzip data after the gzip
    # streams.
    #
    # If a block is given, it is yielded strings of uncompressed data, and the
    # method returns `nil`. If a block is not given, the method returns the
    # concatenation of all uncompressed data in all gzip streams.
    #
    def self.zcat: (IO io, **untyped) -> String
                 | (IO io, **untyped) { (String chunk) -> void } -> nil

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - each(*args)
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def each: (*untyped) { (String) -> void } -> void

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - each_byte()
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def each_byte: () { (String) -> void } -> void

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - each_char()
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def each_char: () { (String) -> void } -> void

    # <!-- rdoc-file=ext/zlib/zlib.c -->
    # See Zlib::GzipReader documentation for a description.
    #
    def each_line: (*untyped) { (String) -> void } -> void

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - eof()
    # -->
    # Returns `true` or `false` whether the stream has reached the end.
    #
    def eof: () -> bool

    # <!-- rdoc-file=ext/zlib/zlib.c -->
    # Returns `true` or `false` whether the stream has reached the end.
    #
    def eof?: () -> bool

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - external_encoding()
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def external_encoding: () -> Encoding

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - getbyte()
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def getbyte: () -> Integer?

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - getc()
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def getc: () -> String?

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - gets(*args)
    # -->
    # See Zlib::GzipReader documentation for a description. However, note that this
    # method can return `nil` even if #eof? returns false, unlike the behavior of
    # File#gets.
    #
    def gets: (?String sep, ?Integer limit) -> String?

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - lineno()
    # -->
    # The line number of the last row read from this file.
    #
    def lineno: () -> Integer

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - lineno=(p1)
    # -->
    # Specify line number of the last row read from this file.
    #
    def lineno=: (Integer arg0) -> Integer

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - pos()
    # -->
    # Total number of output bytes output so far.
    #
    def pos: () -> Integer

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - read(p1 = v1, p2 = v2)
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def read: (?int? length, ?string outbuf) -> String?

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - readbyte()
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def readbyte: () -> Integer

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - readchar()
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def readchar: () -> String

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - readline(*args)
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def readline: (?String sep, ?Integer limit) -> String

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - readlines(*args)
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def readlines: (?String sep, ?Integer limit) -> ::Array[String]

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - gzipreader.readpartial(maxlen [, outbuf]) => string, outbuf
    # -->
    # Reads at most *maxlen* bytes from the gzipped stream but it blocks only if
    # *gzipreader* has no data immediately available. If the optional *outbuf*
    # argument is present, it must reference a String, which will receive the data.
    # It raises `EOFError` on end of file.
    #
    def readpartial: (int maxlen, ?string outbuf) -> String

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - rewind()
    # -->
    # Resets the position of the file pointer to the point created the GzipReader
    # object.  The associated IO object needs to respond to the `seek` method.
    #
    def rewind: () -> Integer

    # <!-- rdoc-file=ext/zlib/zlib.c -->
    # Total number of output bytes output so far.
    #
    def tell: () -> Integer

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - ungetbyte(p1)
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def ungetbyte: (String | Integer arg0) -> NilClass

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - ungetc(p1)
    # -->
    # See Zlib::GzipReader documentation for a description.
    #
    def ungetc: (String arg0) -> NilClass

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - unused()
    # -->
    # Returns the rest of the data which had read for parsing gzip format, or `nil`
    # if the whole gzip file is not parsed yet.
    #
    def unused: () -> String?

    private

    # <!--
    #   rdoc-file=ext/zlib/zlib.c
    #   - Zlib::GzipReader.new(io, options = {})
    # -->
    # Creates a GzipReader object associated with `io`. The GzipReader object reads
    # gzipped data from `io`, and parses/decompresses it.  The `io` must have a
    # `read` method that behaves same as the IO#read.
    #
    # The `options` hash may be used to set the encoding of the data.
    # `:external_encoding`, `:internal_encoding` and `:encoding` may be set as in
    # IO::new.
    #
    # If the gzip file header is incorrect, raises an Zlib::GzipFile::Error
    # exception.
    #
    def initialize: (_Reader io, **untyped opts) -> void
  end
end
