%PDF- %PDF-
Direktori : /lib/calibre/calibre/ebooks/pdb/ |
Current File : //lib/calibre/calibre/ebooks/pdb/header.py |
''' Read the header data from a pdb file. ''' __license__ = 'GPL v3' __copyright__ = '2009, John Schember <john@nachtimwald.com>' __docformat__ = 'restructuredtext en' import re import struct import time from polyglot.builtins import long_type class PdbHeaderReader: def __init__(self, stream): self.stream = stream self.ident = self.identity() self.num_sections = self.section_count() self.title = self.name() def identity(self): self.stream.seek(60) ident = self.stream.read(8) return ident.decode('utf-8') def section_count(self): self.stream.seek(76) return struct.unpack('>H', self.stream.read(2))[0] def name(self): self.stream.seek(0) return re.sub(b'[^-A-Za-z0-9 ]+', b'_', self.stream.read(32).replace(b'\x00', b'')) def full_section_info(self, number): if not (0 <= number < self.num_sections): raise ValueError('Not a valid section number %i' % number) self.stream.seek(78 + number * 8) offset, a1, a2, a3, a4 = struct.unpack('>LBBBB', self.stream.read(8))[0] flags, val = a1, a2 << 16 | a3 << 8 | a4 return (offset, flags, val) def section_offset(self, number): if not (0 <= number < self.num_sections): raise ValueError('Not a valid section number %i' % number) self.stream.seek(78 + number * 8) return struct.unpack('>LBBBB', self.stream.read(8))[0] def section_data(self, number): if not (0 <= number < self.num_sections): raise ValueError('Not a valid section number %i' % number) start = self.section_offset(number) if number == self.num_sections -1: self.stream.seek(0, 2) end = self.stream.tell() else: end = self.section_offset(number + 1) self.stream.seek(start) return self.stream.read(end - start) class PdbHeaderBuilder: def __init__(self, identity, title): self.identity = identity.ljust(3, '\x00')[:8].encode('utf-8') if isinstance(title, str): title = title.encode('ascii', 'replace') self.title = b'%s\x00' % re.sub(b'[^-A-Za-z0-9 ]+', b'_', title).ljust(31, b'\x00')[:31] def build_header(self, section_lengths, out_stream): ''' section_lengths = Length of each section in file. ''' now = int(time.time()) nrecords = len(section_lengths) out_stream.write(self.title + struct.pack('>HHIIIIII', 0, 0, now, now, 0, 0, 0, 0)) out_stream.write(self.identity + struct.pack('>IIH', nrecords, 0, nrecords)) offset = 78 + (8 * nrecords) + 2 for id, record in enumerate(section_lengths): out_stream.write(struct.pack('>LBBBB', long_type(offset), 0, 0, 0, 0)) offset += record out_stream.write(b'\x00\x00')