~ubuntu-branches/ubuntu/karmic/calibre/karmic

« back to all changes in this revision

Viewing changes to src/calibre/ebooks/pdb/header.py

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-30 12:49:41 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730124941-qjdsmri25zt8zocn
Tags: 0.6.3+dfsg-0ubuntu1
* New upstream release. Please see http://calibre.kovidgoyal.net/new_in_6/
  for the list of new features and changes.
* remove_postinstall.patch: Update for new version.
* build_debug.patch: Does not apply any more, disable for now. Might not be
  necessary any more.
* debian/copyright: Fix reference to versionless GPL.
* debian/rules: Drop obsolete dh_desktop call.
* debian/rules: Add workaround for weird Python 2.6 setuptools behaviour of
  putting compiled .so files into src/calibre/plugins/calibre/plugins
  instead of src/calibre/plugins.
* debian/rules: Drop hal fdi moving, new upstream version does not use hal
  any more. Drop hal dependency, too.
* debian/rules: Install udev rules into /lib/udev/rules.d.
* Add debian/calibre.preinst: Remove unmodified
  /etc/udev/rules.d/95-calibre.rules on upgrade.
* debian/control: Bump Python dependencies to 2.6, since upstream needs
  it now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
'''
 
3
Read the header data from a pdb file.
 
4
'''
 
5
 
 
6
__license__   = 'GPL v3'
 
7
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
 
8
__docformat__ = 'restructuredtext en'
 
9
 
 
10
import re
 
11
import struct
 
12
import time
 
13
 
 
14
class PdbHeaderReader(object):
 
15
 
 
16
    def __init__(self, stream):
 
17
        self.stream = stream
 
18
        self.ident = self.identity()
 
19
        self.num_sections = self.section_count()
 
20
        self.title = self.name()
 
21
 
 
22
    def identity(self):
 
23
        self.stream.seek(60)
 
24
        ident = self.stream.read(8)
 
25
        return ident
 
26
 
 
27
    def section_count(self):
 
28
        self.stream.seek(76)
 
29
        return struct.unpack('>H', self.stream.read(2))[0]
 
30
 
 
31
    def name(self):
 
32
        self.stream.seek(0)
 
33
        return self.stream.read(32).replace('\x00', '')
 
34
 
 
35
    def full_section_info(self, number):
 
36
        if number not in range(0, self.num_sections):
 
37
            raise ValueError('Not a valid section number %i' % number)
 
38
 
 
39
        self.stream.seek(78 + number * 8)
 
40
        offset, a1, a2, a3, a4 = struct.unpack('>LBBBB', self.stream.read(8))[0]
 
41
        flags, val = a1, a2 << 16 | a3 << 8 | a4
 
42
        return (offset, flags, val)
 
43
 
 
44
    def section_offset(self, number):
 
45
        if number not in range(0, self.num_sections):
 
46
            raise ValueError('Not a valid section number %i' % number)
 
47
 
 
48
        self.stream.seek(78 + number * 8)
 
49
        return struct.unpack('>LBBBB', self.stream.read(8))[0]
 
50
 
 
51
    def section_data(self, number):
 
52
        if number not in range(0, self.num_sections):
 
53
            raise ValueError('Not a valid section number %i' % number)
 
54
 
 
55
        start = self.section_offset(number)
 
56
        if number == self.num_sections -1:
 
57
            self.stream.seek(0, 2)
 
58
            end = self.stream.tell()
 
59
        else:
 
60
            end = self.section_offset(number + 1)
 
61
        self.stream.seek(start)
 
62
        return self.stream.read(end - start)
 
63
 
 
64
 
 
65
class PdbHeaderBuilder(object):
 
66
 
 
67
    def __init__(self, identity, title):
 
68
        self.identity = identity.ljust(3, '\x00')[:8]
 
69
        self.title = '%s\x00' % re.sub('[^-A-Za-z0-9 ]+', '_', title).ljust(31, '\x00')[:31].encode('ascii', 'replace')
 
70
 
 
71
    def build_header(self, section_lengths, out_stream):
 
72
        '''
 
73
        section_lengths = Lenght of each section in file.
 
74
        '''
 
75
 
 
76
        now = int(time.time())
 
77
        nrecords = len(section_lengths)
 
78
 
 
79
        out_stream.write(self.title + struct.pack('>HHIIIIII', 0, 0, now, now, 0, 0, 0, 0))
 
80
        out_stream.write(self.identity + struct.pack('>IIH', nrecords, 0, nrecords))
 
81
 
 
82
        offset = 78 + (8 * nrecords) + 2
 
83
        for id, record in enumerate(section_lengths):
 
84
            out_stream.write(struct.pack('>LBBBB', long(offset), 0, 0, 0, 0))
 
85
            offset += record
 
86
        out_stream.write('\x00\x00')
 
87