ContainerIO.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #
  2. # The Python Imaging Library.
  3. # $Id$
  4. #
  5. # a class to read from a container file
  6. #
  7. # History:
  8. # 1995-06-18 fl Created
  9. # 1995-09-07 fl Added readline(), readlines()
  10. #
  11. # Copyright (c) 1997-2001 by Secret Labs AB
  12. # Copyright (c) 1995 by Fredrik Lundh
  13. #
  14. # See the README file for information on usage and redistribution.
  15. #
  16. ##
  17. # A file object that provides read access to a part of an existing
  18. # file (for example a TAR file).
  19. import io
  20. class ContainerIO(object):
  21. def __init__(self, file, offset, length):
  22. """
  23. Create file object.
  24. :param file: Existing file.
  25. :param offset: Start of region, in bytes.
  26. :param length: Size of region, in bytes.
  27. """
  28. self.fh = file
  29. self.pos = 0
  30. self.offset = offset
  31. self.length = length
  32. self.fh.seek(offset)
  33. ##
  34. # Always false.
  35. def isatty(self):
  36. return False
  37. def seek(self, offset, mode=io.SEEK_SET):
  38. """
  39. Move file pointer.
  40. :param offset: Offset in bytes.
  41. :param mode: Starting position. Use 0 for beginning of region, 1
  42. for current offset, and 2 for end of region. You cannot move
  43. the pointer outside the defined region.
  44. """
  45. if mode == 1:
  46. self.pos = self.pos + offset
  47. elif mode == 2:
  48. self.pos = self.length + offset
  49. else:
  50. self.pos = offset
  51. # clamp
  52. self.pos = max(0, min(self.pos, self.length))
  53. self.fh.seek(self.offset + self.pos)
  54. def tell(self):
  55. """
  56. Get current file pointer.
  57. :returns: Offset from start of region, in bytes.
  58. """
  59. return self.pos
  60. def read(self, n=0):
  61. """
  62. Read data.
  63. :param n: Number of bytes to read. If omitted or zero,
  64. read until end of region.
  65. :returns: An 8-bit string.
  66. """
  67. if n:
  68. n = min(n, self.length - self.pos)
  69. else:
  70. n = self.length - self.pos
  71. if not n: # EOF
  72. return ""
  73. self.pos = self.pos + n
  74. return self.fh.read(n)
  75. def readline(self):
  76. """
  77. Read a line of text.
  78. :returns: An 8-bit string.
  79. """
  80. s = ""
  81. while True:
  82. c = self.read(1)
  83. if not c:
  84. break
  85. s = s + c
  86. if c == "\n":
  87. break
  88. return s
  89. def readlines(self):
  90. """
  91. Read multiple lines of text.
  92. :returns: A list of 8-bit strings.
  93. """
  94. lines = []
  95. while True:
  96. s = self.readline()
  97. if not s:
  98. break
  99. lines.append(s)
  100. return lines