SickGear/lib/hachoir_core/field/sub_file.py

73 lines
2.6 KiB
Python
Raw Normal View History

from lib.hachoir_core.field import Bytes
from lib.hachoir_core.tools import makePrintable, humanFilesize
from lib.hachoir_core.stream import InputIOStream
class SubFile(Bytes):
"""
File stored in another file
"""
def __init__(self, parent, name, length, description=None,
parser=None, filename=None, mime_type=None, parser_class=None):
if filename:
if not isinstance(filename, unicode):
filename = makePrintable(filename, "ISO-8859-1")
if not description:
description = 'File "%s" (%s)' % (filename, humanFilesize(length))
Bytes.__init__(self, parent, name, length, description)
def createInputStream(cis, **args):
tags = args.setdefault("tags",[])
if parser_class:
tags.append(( "class", parser_class ))
if parser is not None:
tags.append(( "id", parser.PARSER_TAGS["id"] ))
if mime_type:
tags.append(( "mime", mime_type ))
if filename:
tags.append(( "filename", filename ))
return cis(**args)
self.setSubIStream(createInputStream)
class CompressedStream:
offset = 0
def __init__(self, stream, decompressor):
self.stream = stream
self.decompressor = decompressor(stream)
self._buffer = ''
def read(self, size):
d = self._buffer
data = [ d[:size] ]
size -= len(d)
if size > 0:
d = self.decompressor(size)
data.append(d[:size])
size -= len(d)
while size > 0:
n = 4096
if self.stream.size:
n = min(self.stream.size - self.offset, n)
if not n:
break
d = self.stream.read(self.offset, n)[1]
self.offset += 8 * len(d)
d = self.decompressor(size, d)
data.append(d[:size])
size -= len(d)
self._buffer = d[size+len(d):]
return ''.join(data)
def CompressedField(field, decompressor):
def createInputStream(cis, source=None, **args):
if field._parent:
stream = cis(source=source)
args.setdefault("tags", []).extend(stream.tags)
else:
stream = field.stream
input = CompressedStream(stream, decompressor)
if source is None:
source = "Compressed source: '%s' (offset=%s)" % (stream.source, field.absolute_address)
return InputIOStream(input, source=source, **args)
field.setSubIStream(createInputStream)
return field