1
2
3
4
5
6
7
8
9
10 """
11 Handle data recording stuff
12 """
13
14
15 import cPickle
16 import struct
17 import threading
18 import time
19
20
21
22
23 import common
24 import pubsub
25
26
27 DR_Version=(0, 0, 1, 0)
28 DR_Signature='BitPimDR'
29 DR_Rec_Marker='<-->'
30 DR_Type_All=0xff
31 DR_Type_Note=0x01
32 DR_Type_Write=0x02
33 DR_Type_Read=0x04
34 DR_Type_Read_ATResponse=0x08
35 DR_Type_Read_Some=0x10
36 DR_Type_Read_Until=0x20
37 DR_Type_Data=0x40
38 DR_Type_Name={
39 DR_Type_Note: 'Note',
40 DR_Type_Write: 'Write',
41 DR_Type_Read: 'Read',
42 DR_Type_Read_ATResponse: 'Read ATResponse',
43 DR_Type_Read_Some: 'Read Some',
44 DR_Type_Read_Until: 'Read Until',
45 DR_Type_Data: 'Data',
46 }
47
48
52
53
54 DR_On=False
55 DR_Play=False
56 _the_recorder=None
57 _the_player=None
58
59
60
69
78
87
88 -def register(start_recording=None, start_playback=None, stop=None):
95
96 -def unregister(start_recording=None, start_playback=None, stop=None):
103
110
117
125
126 -def record(dr_type, dr_data, dr_class=None):
132
139
140
142 - def __init__(self, dr_type, dr_data, klass=None):
143 self._type=dr_type
144 self._data=dr_data
145 self._time=time.time()
146 if klass:
147 try:
148 self._class_module=klass.__module__
149 self._class_name=klass.__name__
150 except:
151 klass=klass.__class__
152 self._class_module=klass.__module__
153 self._class_name=klass.__name__
154 else:
155 self._class_module=None
156 self._class_name=None
157
160 - def set(self, data):
163
164
165 t=time.localtime(self._time)
166 _s="%d:%02d:%02d.%03d " % (t[3], t[4], t[5],
167 int((self._time-int(self._time))*1000))
168 if self._type==DR_Type_Note:
169 _s+=self._data
170 else:
171
172 _s+=" %s - %d bytes\n" % (DR_Type_Name.get(self._type, 'Data'),
173 len(self._data))
174 if self._class_module and self._class_name:
175 _s+="<#! %s.%s !#>\n" % (self._class_module, self._class_name)
176 _s+=common.datatohexstring(self._data)
177 _s+='\n'
178 return _s
180
181 global DR_Type_Name
182 t=time.localtime(self._time)
183 _s="%d:%02d:%02d.%03d " % (t[3], t[4], t[5],
184 int((self._time-int(self._time))*1000))
185 if self._type==DR_Type_Note:
186 _s+=self._data
187 else:
188 _s+=DR_Type_Name.get(self._type, '<Unknown>')
189 if len(_s)>80:
190 _s=_s[:75]+'<...>'
191 return _s
192
193
196 self._file_name=file_name
197 self._file=None
198 self._valid=False
199
201
202 try:
203 return file(self._file_name, 'rb').read(len(DR_Signature))==DR_Signature
204 except IOError:
205 return False
206 except:
207 if __debug__:
208 raise
209 return False
210
215
216
218 - def __init__(self, file_name, append=False):
219 super(DR_Rec_File, self).__init__(file_name)
220 self._pause=None
221 if not append:
222 self._file=file(self._file_name, 'wb')
223 self._write_header()
224 self._valid=True
225 else:
226 if self._check_header():
227 self._file=file(self._file_name, 'ab')
228 self._valid=True
229 else:
230 self._valid=False
231
239
241 return bool(self._valid and self._file)
242
243
244 - def record(self, dr_type, dr_data, dr_class=None):
245 if self._pause and (self._pause & dr_type):
246
247 return
248 if self._file:
249 _t=threading.Thread(target=self._write_record,
250 args=(dr_type, dr_data, dr_class))
251 _t.start()
252
257
265
267 global DR_On, _the_recorder
268 if self._file is None and self._file_name:
269 self._file=file(self._file_name, 'ab')
270 self._valid=True
271 DR_On=True
272 _the_recorder=self
273
275 self._pause_type=data_type
278
279
282 super(DR_Read_File, self).__init__(file_name)
283 if self._check_header():
284 self._valid=True
285 self._file=file(self._file_name, 'rb')
286 else:
287 self._valid=False
288 self._data=[]
289 self._read_data()
290 self._start_index=0
291 self._end_index=len(self._data)
292 self._current_index=0
293
295
296 _marker=self._file.read(len(DR_Rec_Marker))
297 if _marker!=DR_Rec_Marker:
298
299 return None
300 try:
301 _slen=self._file.read(struct.calcsize('L'))
302 _data_len=struct.unpack('<L', _slen)[0]
303 _sdata=self._file.read(_data_len)
304 return cPickle.loads(_sdata)
305 except (MemoryError, cPickle.UnpicklingError):
306 return None
307 except:
308 if __debug__:
309 raise
310 return None
311
321
323
324 _s=''
325 for e in self._data:
326 _s+=`e`
327 return _s
329
330 return [x.summary() for x in self._data]
331
333 self._start_index=start_idx
334 self._current_index=start_idx
335
341
346
348
349 if self._current_index>=self._end_index:
350
351 raise DataRecordingError('No more data available for playback')
352 _idx=self._current_index
353 for i,e in enumerate(self._data[_idx:]):
354 if e._type==data_type:
355 self._current_index+=i+1
356 return e.get()
357
358 raise DataRecordingError('Failed to find playback data type')
359