A Python UPnP Media Server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.1 KiB

  1. #!/usr/bin/env python
  2. # Copyright 2006 John-Mark Gurney <gurney_j@resnet.uoregon.edu>
  3. __version__ = '$Change$'
  4. # $Id$
  5. import binascii
  6. import os
  7. import zipfile
  8. from zipfile import *
  9. try:
  10. import zlib # We may need its compression method
  11. except ImportError:
  12. zlib = None
  13. __all__ = zipfile.__all__
  14. def dupfile(fp):
  15. if not hasattr(fp, 'fileno'):
  16. raise ValueError, 'must be operating on real file'
  17. newfp = os.fdopen(os.dup(fp.fileno()))
  18. return newfp
  19. class ZipFile(ZipFile):
  20. def readiter(self, name, blksize=16384):
  21. """Return file bytes (as a string) for name."""
  22. if self.mode not in ("r", "a"):
  23. raise RuntimeError, 'read() requires mode "r" or "a"'
  24. if not self.fp:
  25. raise RuntimeError, "Attempt to read ZIP archive " \
  26. "that was already closed"
  27. zinfo = self.getinfo(name)
  28. fp = dupfile(self.fp)
  29. fp.seek(zinfo.file_offset, 0)
  30. if zinfo.compress_type == ZIP_STORED:
  31. assert zinfo.file_size == zinfo.compress_size
  32. i = 0
  33. while i < zinfo.file_size:
  34. yield fp.read(min(blksize, zinfo.file_size - i))
  35. elif zinfo.compress_type == ZIP_DEFLATED:
  36. if not zlib:
  37. raise RuntimeError, "De-compression requires " \
  38. "the (missing) zlib module"
  39. # zlib compress/decompress code by Jeremy Hylton of CNRI
  40. uncomp = 0
  41. comp = 0
  42. dc = zlib.decompressobj(-15)
  43. crc = None
  44. doflush = False
  45. while uncomp < zinfo.file_size:
  46. if not dc.unconsumed_tail:
  47. compread = min(blksize,
  48. zinfo.compress_size - comp)
  49. bytes = fp.read(compread)
  50. comp += compread
  51. if compread == 0:
  52. doflush = True
  53. else:
  54. bytes = dc.unconsumed_tail
  55. if doflush:
  56. # need to feed in unused pad byte so
  57. # that zlib won't choke
  58. bytes = dc.decompress('Z') + dc.flush()
  59. else:
  60. bytes = dc.decompress(bytes, blksize)
  61. yield bytes
  62. uncomp += len(bytes)
  63. if crc is None:
  64. crc = binascii.crc32(bytes)
  65. else:
  66. crc = binascii.crc32(bytes, crc)
  67. if crc != zinfo.CRC:
  68. raise BadZipfile, "Bad CRC-32 for file %s" % \
  69. name
  70. else:
  71. raise BadZipfile, "Unsupported compression method " \
  72. "%d for file %s" % (zinfo.compress_type, name)