about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/PIL/ContainerIO.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/PIL/ContainerIO.py')
-rw-r--r--.venv/lib/python3.12/site-packages/PIL/ContainerIO.py173
1 files changed, 173 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/PIL/ContainerIO.py b/.venv/lib/python3.12/site-packages/PIL/ContainerIO.py
new file mode 100644
index 00000000..ec9e66c7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/PIL/ContainerIO.py
@@ -0,0 +1,173 @@
+#
+# The Python Imaging Library.
+# $Id$
+#
+# a class to read from a container file
+#
+# History:
+# 1995-06-18 fl     Created
+# 1995-09-07 fl     Added readline(), readlines()
+#
+# Copyright (c) 1997-2001 by Secret Labs AB
+# Copyright (c) 1995 by Fredrik Lundh
+#
+# See the README file for information on usage and redistribution.
+#
+from __future__ import annotations
+
+import io
+from collections.abc import Iterable
+from typing import IO, AnyStr, NoReturn
+
+
+class ContainerIO(IO[AnyStr]):
+    """
+    A file object that provides read access to a part of an existing
+    file (for example a TAR file).
+    """
+
+    def __init__(self, file: IO[AnyStr], offset: int, length: int) -> None:
+        """
+        Create file object.
+
+        :param file: Existing file.
+        :param offset: Start of region, in bytes.
+        :param length: Size of region, in bytes.
+        """
+        self.fh: IO[AnyStr] = file
+        self.pos = 0
+        self.offset = offset
+        self.length = length
+        self.fh.seek(offset)
+
+    ##
+    # Always false.
+
+    def isatty(self) -> bool:
+        return False
+
+    def seekable(self) -> bool:
+        return True
+
+    def seek(self, offset: int, mode: int = io.SEEK_SET) -> int:
+        """
+        Move file pointer.
+
+        :param offset: Offset in bytes.
+        :param mode: Starting position. Use 0 for beginning of region, 1
+           for current offset, and 2 for end of region.  You cannot move
+           the pointer outside the defined region.
+        :returns: Offset from start of region, in bytes.
+        """
+        if mode == 1:
+            self.pos = self.pos + offset
+        elif mode == 2:
+            self.pos = self.length + offset
+        else:
+            self.pos = offset
+        # clamp
+        self.pos = max(0, min(self.pos, self.length))
+        self.fh.seek(self.offset + self.pos)
+        return self.pos
+
+    def tell(self) -> int:
+        """
+        Get current file pointer.
+
+        :returns: Offset from start of region, in bytes.
+        """
+        return self.pos
+
+    def readable(self) -> bool:
+        return True
+
+    def read(self, n: int = -1) -> AnyStr:
+        """
+        Read data.
+
+        :param n: Number of bytes to read. If omitted, zero or negative,
+            read until end of region.
+        :returns: An 8-bit string.
+        """
+        if n > 0:
+            n = min(n, self.length - self.pos)
+        else:
+            n = self.length - self.pos
+        if n <= 0:  # EOF
+            return b"" if "b" in self.fh.mode else ""  # type: ignore[return-value]
+        self.pos = self.pos + n
+        return self.fh.read(n)
+
+    def readline(self, n: int = -1) -> AnyStr:
+        """
+        Read a line of text.
+
+        :param n: Number of bytes to read. If omitted, zero or negative,
+            read until end of line.
+        :returns: An 8-bit string.
+        """
+        s: AnyStr = b"" if "b" in self.fh.mode else ""  # type: ignore[assignment]
+        newline_character = b"\n" if "b" in self.fh.mode else "\n"
+        while True:
+            c = self.read(1)
+            if not c:
+                break
+            s = s + c
+            if c == newline_character or len(s) == n:
+                break
+        return s
+
+    def readlines(self, n: int | None = -1) -> list[AnyStr]:
+        """
+        Read multiple lines of text.
+
+        :param n: Number of lines to read. If omitted, zero, negative or None,
+            read until end of region.
+        :returns: A list of 8-bit strings.
+        """
+        lines = []
+        while True:
+            s = self.readline()
+            if not s:
+                break
+            lines.append(s)
+            if len(lines) == n:
+                break
+        return lines
+
+    def writable(self) -> bool:
+        return False
+
+    def write(self, b: AnyStr) -> NoReturn:
+        raise NotImplementedError()
+
+    def writelines(self, lines: Iterable[AnyStr]) -> NoReturn:
+        raise NotImplementedError()
+
+    def truncate(self, size: int | None = None) -> int:
+        raise NotImplementedError()
+
+    def __enter__(self) -> ContainerIO[AnyStr]:
+        return self
+
+    def __exit__(self, *args: object) -> None:
+        self.close()
+
+    def __iter__(self) -> ContainerIO[AnyStr]:
+        return self
+
+    def __next__(self) -> AnyStr:
+        line = self.readline()
+        if not line:
+            msg = "end of region"
+            raise StopIteration(msg)
+        return line
+
+    def fileno(self) -> int:
+        return self.fh.fileno()
+
+    def flush(self) -> None:
+        self.fh.flush()
+
+    def close(self) -> None:
+        self.fh.close()