mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-09-22 20:09:04 +03:00
e817ed0d3e
Image data is expected to be read in bytes mode, not text mode so ContainerIO should return bytes in all methods. The passed in file handler is expected to be opened in bytes mode (as TarIO already does).
118 lines
2.7 KiB
Python
118 lines
2.7 KiB
Python
#
|
|
# 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.
|
|
#
|
|
|
|
##
|
|
# A file object that provides read access to a part of an existing
|
|
# file (for example a TAR file).
|
|
|
|
import io
|
|
|
|
|
|
class ContainerIO:
|
|
def __init__(self, file, offset, length):
|
|
"""
|
|
Create file object.
|
|
|
|
:param file: Existing file.
|
|
:param offset: Start of region, in bytes.
|
|
:param length: Size of region, in bytes.
|
|
"""
|
|
self.fh = file
|
|
self.pos = 0
|
|
self.offset = offset
|
|
self.length = length
|
|
self.fh.seek(offset)
|
|
|
|
##
|
|
# Always false.
|
|
|
|
def isatty(self):
|
|
return False
|
|
|
|
def seek(self, offset, mode=io.SEEK_SET):
|
|
"""
|
|
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.
|
|
"""
|
|
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)
|
|
|
|
def tell(self):
|
|
"""
|
|
Get current file pointer.
|
|
|
|
:returns: Offset from start of region, in bytes.
|
|
"""
|
|
return self.pos
|
|
|
|
def read(self, n=0):
|
|
"""
|
|
Read data.
|
|
|
|
:param n: Number of bytes to read. If omitted or zero,
|
|
read until end of region.
|
|
:returns: An 8-bit string.
|
|
"""
|
|
if n:
|
|
n = min(n, self.length - self.pos)
|
|
else:
|
|
n = self.length - self.pos
|
|
if not n: # EOF
|
|
return b""
|
|
self.pos = self.pos + n
|
|
return self.fh.read(n)
|
|
|
|
def readline(self):
|
|
"""
|
|
Read a line of text.
|
|
|
|
:returns: An 8-bit string.
|
|
"""
|
|
s = b""
|
|
while True:
|
|
c = self.read(1)
|
|
if not c:
|
|
break
|
|
s = s + c
|
|
if c == b"\n":
|
|
break
|
|
return s
|
|
|
|
def readlines(self):
|
|
"""
|
|
Read multiple lines of text.
|
|
|
|
:returns: A list of 8-bit strings.
|
|
"""
|
|
lines = []
|
|
while True:
|
|
s = self.readline()
|
|
if not s:
|
|
break
|
|
lines.append(s)
|
|
return lines
|