matiasb/python-unrar — pull request #1 by uaply (2014-01-15 10:29:06+00:00)
Title: Add support for user-defined unrar events

I've added RARSetCallback function to unrarlib. It allows to implement non-standard processing of data.

For example I use it to crunch uncompressed data without storing it on disk:

```python

import ctypes
import unrar.constants
from unrar import rarfile
from unrar import unrarlib

class RarFileExt(rarfile.RarFile):

def _callback(self, msg, UserData, P1, P2):
if msg == unrar.constants.UCM_PROCESSDATA:
data = (ctypes.c_char*P2).from_address(P1).raw
# PROCESS DATA HERE
return 1

def _unrar_file(self, filename, pwd=None):
archive = unrarlib.RAROpenArchiveDataEx(
self.filename, mode=unrar.constants.RAR_OM_EXTRACT)
handle = self._open(archive)

password = pwd or self.pwd
if password is not None:
unrarlib.RARSetPassword(handle, rarfile.b(password))

try:
rarinfo = self._read_header(handle)
while rarinfo is not None:
if rarinfo.filename == filename:
_rar_callback = unrarlib.UNRARCALLBACK(self._callback)
unrarlib.RARSetCallback(handle, _rar_callback, 0)
self._process_current(
handle, unrar.constants.RAR_TEST) # RAR_EXTRACT will create files, so RAR_TEST
unrarlib.RARSetCallback(handle, unrarlib.UNRARCALLBACK(0), 0) # clean up, just in case
break
else:
self._process_current(handle, unrar.constants.RAR_SKIP)
rarinfo = self._read_header(handle)
except unrarlib.UnrarException:
raise BadRarFile("Bad RAR archive data.")
finally:
self._close(handle)

```