~sylvain-pineau/checkbox-core/bug983035

« back to all changes in this revision

Viewing changes to checkbox/journal/header.py

  • Committer: Marc Tardif
  • Date: 2012-04-12 18:58:39 UTC
  • Revision ID: marc.tardif@canonical.com-20120412185839-5lxr7972gntlpl2z
Added journal component.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright (c) 2012 Canonical
 
3
#
 
4
# This file is part of Checkbox.
 
5
#
 
6
# Storm is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU Lesser General Public License as
 
8
# published by the Free Software Foundation; either version 2.1 of
 
9
# the License, or (at your option) any later version.
 
10
#
 
11
# Storm is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU Lesser General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU Lesser General Public License
 
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
#
 
19
__metaclass__ = type
 
20
 
 
21
__all__ = [
 
22
    "Header",
 
23
    "HeaderReader",
 
24
    "HeaderWriter",
 
25
    ]
 
26
 
 
27
import re
 
28
 
 
29
from checkbox.journal.event import (
 
30
    Event,
 
31
    EventOutcome,
 
32
    EventType,
 
33
    )
 
34
 
 
35
 
 
36
JOURNAL_PATTERN = (
 
37
    r"Global Journal:"
 
38
     " ctime=(?P<ctime>\d+)"
 
39
     " id=(?P<id>[^ ]+)"
 
40
     " sequence=(?P<sequence>\d+)"
 
41
     " size=(?P<size>\d+)L?"
 
42
     " events=(?P<events>\d+)L?"
 
43
     " offset=(?P<offset>\d+)L?"
 
44
     " event_offset=(?P<event_offset>\d+)L?")
 
45
JOURNAL_RE = re.compile(JOURNAL_PATTERN)
 
46
 
 
47
 
 
48
class Header:
 
49
    """Simple class to extract info from a journal header event."""
 
50
 
 
51
    __slots__ = (
 
52
        "id",
 
53
        "sequence",
 
54
        "ctime",
 
55
        "size",
 
56
        "num_events",
 
57
        "file_offset",
 
58
        "event_offset",
 
59
        "_valid",
 
60
        )
 
61
 
 
62
    def __init__(self, other=None):
 
63
        if other is None:
 
64
            self.id = None
 
65
            self.sequence = 0
 
66
            self.ctime = 0
 
67
            self.size = 0
 
68
            self.num_events = 0
 
69
            self.file_offset = 0
 
70
            self.event_offset = 0
 
71
            self._valid = False
 
72
        else:
 
73
            self.copyFrom(other)
 
74
 
 
75
    def copyFrom(self, other):
 
76
        """Copy the parameters from another header object into this one.
 
77
 
 
78
        :param other: Other header object.
 
79
        """
 
80
        self.id = other.id
 
81
        self.sequence = other.sequence
 
82
        self.ctime = other.ctime
 
83
        self.size = other.size
 
84
        self.num_events = other.num_events
 
85
        self.file_offset = other.file_offset
 
86
        self.event_offset = other.event_offset
 
87
        self._valid = other._valid
 
88
 
 
89
    @property
 
90
    def is_valid(self):
 
91
        """Return true if the header is valid."""
 
92
        return self._valid
 
93
 
 
94
    def incrementSequence(self):
 
95
        """Increment the sequence number."""
 
96
        self.sequence += 1
 
97
 
 
98
    def addFileOffset(self, offset):
 
99
        """Add to the file offset.
 
100
 
 
101
        :param offset: Offset to add.
 
102
        """
 
103
        self.file_offset += offset
 
104
 
 
105
    def addEventOffset(self, offset):
 
106
        """Add to the event offset.
 
107
 
 
108
        :param offset: Offset to add.
 
109
        """
 
110
        self.event_offset += offset
 
111
 
 
112
    def extractEvent(self, event):
 
113
        """Extract data from an event and update the header.
 
114
 
 
115
        :param event: Event from which to extract.
 
116
        """
 
117
        if event.type != EventType.GENERIC:
 
118
            return EventOutcome.NO_EVENT
 
119
 
 
120
        match = JOURNAL_RE.match(event.data)
 
121
        if not match:
 
122
            return EventOutcome.NO_EVENT
 
123
 
 
124
        self.ctime = int(match.group("ctime"))
 
125
        self.id = match.group("id")
 
126
        self.sequence = int(match.group("sequence"))
 
127
        self.size = int(match.group("size"))
 
128
        self.num_events = int(match.group("events"))
 
129
        self.file_offset = int(match.group("offset"))
 
130
        self.event_offset = int(match.group("event_offset"))
 
131
        self._valid = True
 
132
 
 
133
        return EventOutcome.OK
 
134
 
 
135
 
 
136
class HeaderReader(Header):
 
137
 
 
138
    def read(self, reader):
 
139
        """Read the header from a file.
 
140
 
 
141
        :param reader: Journal reader object.
 
142
        """
 
143
        event = Event()
 
144
        outcome = reader.readEvent(event)
 
145
 
 
146
        if outcome != EventOutcome.OK:
 
147
            return outcome
 
148
 
 
149
        if event.type != EventType.GENERIC:
 
150
            return EventOutcome.NO_EVENT
 
151
 
 
152
        return self.extractEvent(event)
 
153
 
 
154
 
 
155
class HeaderWriter(Header):
 
156
 
 
157
    def write(self, writer, file=None):
 
158
        """Write the header to a file.
 
159
 
 
160
        :param reader: Journal writer object.
 
161
        """
 
162
        event = Event(EventType.GENERIC)
 
163
        if not self.generateEvent(event):
 
164
            return EventOutcome.UNKNOWN_ERROR
 
165
 
 
166
        return writer.writeGlobalEvent(event, file, True)
 
167
 
 
168
    def generateEvent(self, event):
 
169
        """Generate a header event.
 
170
 
 
171
        :param event: Generic event to contain the header data.
 
172
        """
 
173
        event.data = (
 
174
            "Global Journal:"
 
175
            " ctime=%d"
 
176
            " id=%s"
 
177
            " sequence=%d"
 
178
            " size=%d"
 
179
            " events=%d"
 
180
            " offset=%d"
 
181
            " event_offset=%d" % (
 
182
            self.ctime,
 
183
            self.id,
 
184
            self.sequence,
 
185
            self.size,
 
186
            self.num_events,
 
187
            self.file_offset,
 
188
            self.event_offset))
 
189
 
 
190
        return True