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.

75 lines
2.0 KiB

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