home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' import struct import time from datetime import datetime from calibre.devices.errors import PacketError WORD = '<H' DWORD = '<I' DDWORD = '<Q' class PathResponseCodes(object): NOT_FOUND = 0xFFFFFFD7L INVALID = 0xFFFFFFF9L IS_FILE = 0xFFFFFFD2L HAS_CHILDREN = 0xFFFFFFCCL PERMISSION_DENIED = 0xFFFFFFD6L class TransferBuffer(list): def __init__(self, packet): pass def __add__(self, tb): return TransferBuffer(list.__add__(self, tb)) def __getslice__(self, start, end): return TransferBuffer(list.__getslice__(self, start, end)) def __str__(self): ans = ': '.rjust(10, '0') ascii = '' for i in range(0, len(self), 2): for b in range(2): try: ans += TransferBuffer.phex(self[i + b]) None += ascii if self[i + b] > 31 and self[i + b] < 127 else '.' continue except IndexError: break continue ans = ans + ' ' if (i + 2) % 16 == 0: if i + 2 < len(self): ans += ' ' + ascii + '\n' + (TransferBuffer.phex(i + 2) + ': ').rjust(10, '0') ascii = '' i + 2 < len(self) last_line = ans[ans.rfind('\n') + 1:] padding = 50 - len(last_line) ans += ''.ljust(padding) + ' ' + ascii return ans.strip() def unpack(self, fmt = DWORD, start = 0): end = start + struct.calcsize(fmt) return ''.join([], []([ chr(i) for i in list.__getslice__(self, start, end) ])) def pack(self, val, fmt = DWORD, start = 0): if fmt == WORD: val = val % 65536 self[start:start + struct.calcsize(fmt)] = [ ord(i) for i in struct.pack(fmt, val) ] def _normalize(self): for i in range(len(self)): if self[i] < 0: self[i] = 256 + self[i] continue def phex(cls, num): (index, sign) = (2, '') if num < 0: (index, sign) = (3, '-') h = hex(num)[index:] if len(h) < 2: h = '0' + h return sign + h phex = classmethod(phex) class field(object): def __init__(self, start = 16, fmt = DWORD): self._fmt = fmt self._start = start def __get__(self, obj, typ = None): return obj.unpack(start = self._start, fmt = self._fmt)[0] def __set__(self, obj, val): obj.pack(val, start = self._start, fmt = self._fmt) def __repr__(self): typ = '' if self._fmt == DWORD: typ = 'unsigned int' if self._fmt == DDWORD: typ = 'unsigned long long' return 'An ' + typ + ' stored in ' + str(struct.calcsize(self._fmt)) + ' bytes starting at byte ' + str(self._start) class stringfield(object): def __init__(self, length_field, start = 16): self._length_field = length_field self._start = start def __get__(self, obj, typ = None): length = str(self._length_field.__get__(obj)) return obj.unpack(start = self._start, fmt = '<' + length + 's')[0] def __set__(self, obj, val): if isinstance(val, unicode): val = val.encode('utf8') else: val = str(val) obj.pack(val, start = self._start, fmt = '<' + str(len(val)) + 's') def __repr__(self): return 'A string starting at byte ' + str(self._start) class Command(TransferBuffer): number = field(start = 0, fmt = DWORD) type = field(start = 4, fmt = DDWORD) length = field(start = 12, fmt = DWORD) def data(self): doc = ' \n The data part of this command. Returned/set as/by a TransferBuffer. \n Stored at byte 16.\n \n Setting it by default changes self.length to the length of the new \n buffer. You may have to reset it to the significant part of the buffer.\n You would normally use the C{command} property of \n L{ShortCommand} or L{LongCommand} instead.\n ' def fget(self): return self[16:] def fset(self, buff): self[16:] = buff self.length = len(buff) return property(doc = doc, fget = fget, fset = fset) data = dynamic_property(data) def __init__(self, packet): if ('__len__' in dir(packet) or len(packet) < 16 or '__len__' not in dir(packet)) and packet < 16: raise PacketError(str(self.__class__)[7:-2] + ' packets must have length atleast 16') packet < 16 TransferBuffer.__init__(self, packet) class SetTime(Command): NUMBER = 260 timezone = field(start = 16, fmt = DWORD) year = field(start = 20, fmt = DWORD) month = field(start = 24, fmt = DWORD) day = field(start = 28, fmt = DWORD) hour = field(start = 32, fmt = DWORD) minute = field(start = 36, fmt = DWORD) second = field(start = 40, fmt = DWORD) def __init__(self, t = None): self.number = SetTime.NUMBER self.type = 1 self.length = 28 td = datetime.now() - datetime.utcnow() tz = int((td.days * 24 * 3600 + td.seconds) / 60) self.timezone = None if tz > 0 else 0x100000000L + tz if not t: t = time.time() t = time.gmtime(t) self.year = t[0] self.month = t[1] self.day = t[2] self.hour = t[3] self.minute = t[4] self.second = None if t[5] < 60 else 59 class ShortCommand(Command): SIZE = 20 command = field(start = 16, fmt = DWORD) def __init__(self, number = 0, type = 0, command = 0): Command.__init__(self, ShortCommand.SIZE) self.number = number self.type = type self.length = 4 self.command = command class DirRead(ShortCommand): NUMBER = 53 def __init__(self, _id): ShortCommand.__init__(self, number = DirRead.NUMBER, type = 1, command = _id) class DirClose(ShortCommand): NUMBER = 52 def __init__(self, _id): ShortCommand.__init__(self, number = DirClose.NUMBER, type = 1, command = _id) class BeginEndSession(ShortCommand): NUMBER = 1 def __init__(self, end = True): command = None if end else 1 ShortCommand.__init__(self, number = BeginEndSession.NUMBER, type = 1, command = command) class GetUSBProtocolVersion(ShortCommand): NUMBER = 0 def __init__(self): ShortCommand.__init__(self, number = GetUSBProtocolVersion.NUMBER, type = 1, command = 0) class SetBulkSize(Command): NUMBER = 263 chunk_size = field(fmt = WORD, start = 16) unknown = field(fmt = WORD, start = 18) def __init__(self, chunk_size = 32768, unknown = 2): []([], [ 0 for i in range(24) ]) self.number = SetBulkSize.NUMBER self.type = 1 self.chunk_size = chunk_size self.unknown = unknown class UnlockDevice(Command): NUMBER = 262 key = stringfield(8, start = 16) def __init__(self, key = '-1\x00\x00\x00\x00\x00\x00'): Command.__init__(self, 24) self.number = UnlockDevice.NUMBER self.type = 1 self.length = 8 self.key = key class LongCommand(Command): SIZE = 32 def __init__(self, number = 0, type = 0, command = 0): Command.__init__(self, LongCommand.SIZE) self.number = number self.type = type self.length = 16 self.command = command def command(self): doc = ' \n Usually carries extra information needed for the command\n It is a list of C{unsigned integers} of length between 1 and 4. 4 \n C{unsigned int} stored in 16 bytes at byte 16.\n ' def fget(self): return self.unpack(start = 16, fmt = '<' + str(self.length / 4) + 'I') def fset(self, val): if '__len__' not in dir(val): val = (val,) start = 16 for command in val: self.pack(command, start = start, fmt = DWORD) start += struct.calcsize(DWORD) return property(doc = doc, fget = fget, fset = fset) command = dynamic_property(command) class PathCommand(Command): path_length = field(start = 16, fmt = DWORD) path = stringfield(path_length, start = 20) def __init__(self, path, number, path_len_at_byte = 16): Command.__init__(self, path_len_at_byte + 4 + len(path)) if isinstance(path, unicode): path = path.encode('utf8') self.path_length = len(path) self.path = path self.type = 1 self.length = len(self) - 16 self.number = number class TotalSpaceQuery(PathCommand): NUMBER = 83 def __init__(self, path): PathCommand.__init__(self, path, TotalSpaceQuery.NUMBER) class FreeSpaceQuery(ShortCommand): NUMBER = 259 def __init__(self, where): c = 0 if where.startswith('a:'): c = 1 elif where.startswith('b:'): c = 2 ShortCommand.__init__(self, number = FreeSpaceQuery.NUMBER, type = 1, command = c) class DirCreate(PathCommand): NUMBER = 48 def __init__(self, path): PathCommand.__init__(self, path, DirCreate.NUMBER) class DirOpen(PathCommand): NUMBER = 51 def __init__(self, path): PathCommand.__init__(self, path, DirOpen.NUMBER) class AcknowledgeBulkRead(LongCommand): def __init__(self, bulk_read_id): LongCommand.__init__(self, number = 4096, type = 0, command = bulk_read_id) class DeviceInfoQuery(Command): NUMBER = 257 def __init__(self): Command.__init__(self, 16) self.number = DeviceInfoQuery.NUMBER self.type = 1 class FileClose(ShortCommand): NUMBER = 17 def __init__(self, _id): ShortCommand.__init__(self, number = FileClose.NUMBER, type = 1, command = _id) class FileCreate(PathCommand): NUMBER = 26 def __init__(self, path): PathCommand.__init__(self, path, FileCreate.NUMBER) class FileDelete(PathCommand): NUMBER = 27 def __init__(self, path): PathCommand.__init__(self, path, FileDelete.NUMBER) class DirDelete(PathCommand): NUMBER = 49 def __init__(self, path): PathCommand.__init__(self, path, DirDelete.NUMBER) class FileOpen(PathCommand): NUMBER = 16 READ = 0 WRITE = 1 path_length = field(start = 20, fmt = DWORD) path = stringfield(path_length, start = 24) def __init__(self, path, mode = 0): PathCommand.__init__(self, path, FileOpen.NUMBER, path_len_at_byte = 20) self.mode = mode def mode(self): doc = ' \n The file open mode. Is either L{FileOpen.READ} \n or L{FileOpen.WRITE}. C{unsigned int} stored at byte 16. \n ' def fget(self): return self.unpack(start = 16, fmt = DWORD)[0] def fset(self, val): self.pack(val, start = 16, fmt = DWORD) return property(doc = doc, fget = fget, fset = fset) mode = dynamic_property(mode) class FileIO(Command): RNUMBER = 22 WNUMBER = 23 id = field(start = 16, fmt = DWORD) offset = field(start = 20, fmt = DDWORD) size = field(start = 28, fmt = DWORD) def __init__(self, _id, offset, size, mode = 22): Command.__init__(self, 32) self.number = mode self.type = 1 self.length = 16 self.id = _id self.offset = offset self.size = size class PathQuery(PathCommand): NUMBER = 24 def __init__(self, path): PathCommand.__init__(self, path, PathQuery.NUMBER) class SetFileInfo(PathCommand): NUMBER = 25 def __init__(self, path): PathCommand.__init__(self, path, SetFileInfo.NUMBER) class Response(Command): SIZE = 32 rnumber = field(start = 16, fmt = DWORD) code = field(start = 20, fmt = DWORD) data_size = field(start = 28, fmt = DWORD) def __init__(self, packet): if len(packet) != Response.SIZE: raise PacketError(str(self.__class__)[7:-2] + ' packets must have exactly ' + str(Response.SIZE) + ' bytes not ' + str(len(packet))) len(packet) != Response.SIZE Command.__init__(self, packet) if self.number != 4096: raise PacketError('Response packets must have their number set to ' + hex(4096)) self.number != 4096 def data(self): doc = ' \n The last 3 DWORDs (12 bytes) of data in this \n response packet. Returned as a list of unsigned integers.\n ' def fget(self): return self.unpack(start = 20, fmt = '<III') def fset(self, val): self.pack(val, start = 20, fmt = '<III') return property(doc = doc, fget = fget, fset = fset) data = dynamic_property(data) class ListResponse(Response): IS_FILE = 0xFFFFFFD2L IS_INVALID = 0xFFFFFFF9L IS_UNMOUNTED = 0xFFFFFFC8L IS_EOL = 0xFFFFFFFAL PATH_NOT_FOUND = 0xFFFFFFD7L PERMISSION_DENIED = 0xFFFFFFD6L def is_file(self): doc = ' True iff queried path is a file ' def fget(self): return self.code == ListResponse.IS_FILE return property(doc = doc, fget = fget) is_file = dynamic_property(is_file) def is_invalid(self): doc = ' True iff queried path is invalid ' def fget(self): return self.code == ListResponse.IS_INVALID return property(doc = doc, fget = fget) is_invalid = dynamic_property(is_invalid) def path_not_found(self): doc = ' True iff queried path is not found ' def fget(self): return self.code == ListResponse.PATH_NOT_FOUND return property(doc = doc, fget = fget) path_not_found = dynamic_property(path_not_found) def permission_denied(self): doc = ' True iff permission is denied for path operations ' def fget(self): return self.code == ListResponse.PERMISSION_DENIED return property(doc = doc, fget = fget) permission_denied = dynamic_property(permission_denied) def is_unmounted(self): doc = ' True iff queried path is unmounted (i.e. removed storage card) ' def fget(self): return self.code == ListResponse.IS_UNMOUNTED return property(doc = doc, fget = fget) is_unmounted = dynamic_property(is_unmounted) def is_eol(self): doc = ' True iff there are no more items in the list ' def fget(self): return self.code == ListResponse.IS_EOL return property(doc = doc, fget = fget) is_eol = dynamic_property(is_eol) class Answer(TransferBuffer): number = field(start = 0, fmt = DWORD) length = field(start = 12, fmt = DWORD) def __init__(self, packet): if '__len__' in dir(packet): if len(packet) < 16: raise PacketError(str(self.__class__)[7:-2] + ' packets must have a length of atleast 16 bytes. Got initializer of ' + str(len(packet)) + ' bytes.') len(packet) < 16 elif packet < 16: raise PacketError(str(self.__class__)[7:-2] + ' packets must have a length of atleast 16 bytes') TransferBuffer.__init__(self, packet) class FileProperties(Answer): file_size = field(start = 16, fmt = DDWORD) file_type = field(start = 24, fmt = DWORD) ctime = field(start = 28, fmt = DWORD) wtime = field(start = 32, fmt = DWORD) permissions = field(start = 36, fmt = DWORD) def is_dir(self): doc = 'True if path points to a directory, False if it points to a file.' def fget(self): return self.file_type == 2 def fset(self, val): if val: val = 2 else: val = 1 self.file_type = val return property(doc = doc, fget = fget, fset = fset) is_dir = dynamic_property(is_dir) def is_readonly(self): doc = ' Whether this file is readonly.' def fget(self): return self.unpack(start = 36, fmt = DWORD)[0] != 0 def fset(self, val): if val: val = 4 else: val = 0 self.pack(val, start = 36, fmt = DWORD) return property(doc = doc, fget = fget, fset = fset) is_readonly = dynamic_property(is_readonly) class USBProtocolVersion(Answer): version = field(start = 16, fmt = DDWORD) class IdAnswer(Answer): def id(self): doc = ' \n The identifier. C{unsigned int} stored in 4 bytes \n at byte 16. Should be sent in commands asking \n for the next item in the list. \n ' def fget(self): return self.unpack(start = 16, fmt = DWORD)[0] def fset(self, val): self.pack(val, start = 16, fmt = DWORD) return property(doc = doc, fget = fget, fset = fset) id = dynamic_property(id) class DeviceInfo(Answer): device_name = field(start = 16, fmt = '<32s') device_version = field(start = 48, fmt = '<32s') software_version = field(start = 80, fmt = '<24s') mime_type = field(start = 104, fmt = '<32s') class TotalSpaceAnswer(Answer): total = field(start = 24, fmt = DDWORD) free_space = field(start = 32, fmt = DDWORD) class FreeSpaceAnswer(Answer): SIZE = 24 free = field(start = 16, fmt = DDWORD) class ListAnswer(Answer): name_length = field(start = 20, fmt = DWORD) name = stringfield(name_length, start = 24) def is_dir(self): doc = ' \n True if list item points to a directory, False if it points to a file.\n C{unsigned int} stored in 4 bytes at byte 16.\n ' def fget(self): return self.unpack(start = 16, fmt = DWORD)[0] == 2 def fset(self, val): if val: val = 2 else: val = 1 self.pack(val, start = 16, fmt = DWORD) return property(doc = doc, fget = fget, fset = fset) is_dir = dynamic_property(is_dir)