Module prototypeslg
[hide private]
[frames] | no frames]

Source Code for Module prototypeslg

  1  ### BITPIM 
  2  ### 
  3  ### Copyright (C) 2003-2005 Roger Binns <rogerb@rogerbinns.com> 
  4  ### 
  5  ### This program is free software; you can redistribute it and/or modify 
  6  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  7  ### 
  8  ### $Id: prototypeslg.py 4715 2008-10-21 01:51:40Z djpham $ 
  9   
 10  import bpcalendar 
 11   
 12  import calendar 
 13  import prototypes 
 14  import re 
 15  import time 
16 17 -class LGCALDATE(prototypes.UINTlsb):
18 - def __init__(self, *args, **kwargs):
19 """A date/time as used in the LG calendar""" 20 super(LGCALDATE,self).__init__(*args, **kwargs) 21 self._valuedate=(0,0,0,0,0) # year month day hour minute 22 23 dict={'sizeinbytes': 4} 24 dict.update(kwargs) 25 26 if self._ismostderived(LGCALDATE): 27 self._update(args, dict)
28
29 - def _update(self, args, kwargs):
30 for k in 'constant', 'default', 'value': 31 if kwargs.has_key(k): 32 kwargs[k]=self._converttoint(kwargs[k]) 33 if len(args)==0: 34 pass 35 elif len(args)==1: 36 args=(self._converttoint(args[0]),) 37 else: 38 raise TypeError("expected (year,month,day,hour,minute) as arg") 39 40 super(LGCALDATE,self)._update(args, kwargs) # we want the args 41 self._complainaboutunusedargs(LGCALDATE,kwargs) 42 assert self._sizeinbytes==4
43
44 - def getvalue(self):
45 """Unpack 32 bit value into date/time 46 47 @rtype: tuple 48 @return: (year, month, day, hour, minute) 49 """ 50 val=super(LGCALDATE,self).getvalue() 51 min=val&0x3f # 6 bits 52 val>>=6 53 hour=val&0x1f # 5 bits (uses 24 hour clock) 54 val>>=5 55 day=val&0x1f # 5 bits 56 val>>=5 57 month=val&0xf # 4 bits 58 val>>=4 59 year=val&0xfff # 12 bits 60 return (year, month, day, hour, min)
61
62 - def _converttoint(self, date):
63 assert len(date)==5 64 year,month,day,hour,min=date 65 if year>4095: 66 year=4095 67 val=year 68 val<<=4 69 val|=month 70 val<<=5 71 val|=day 72 val<<=5 73 val|=hour 74 val<<=6 75 val|=min 76 return val
77
78 -class LGCALREPEAT(prototypes.UINTlsb):
79 - def __init__(self, *args, **kwargs):
80 """A 32-bit bitmapped value used to store repeat info for events in the LG calendar""" 81 super(LGCALREPEAT,self).__init__(*args, **kwargs) 82 83 # The meaning of the bits in this field 84 # MSB LSB 85 # 3 2 1 86 # 10987654321098765432109876543210 87 # 210 repeat_type 88 # 0 exceptions, set to 1 if there are exceptions 89 # 6543210 dow_weekly (weekly repeat type) 90 # 210 dow (monthly repeat type) 91 # 543210 interval 92 # 3210 month_index 93 # 543210 day_index 94 95 # repeat_type: 0=none, 1=daily, 2=weekly, 3=monthly, 4=yearly, 5=weekdays, 6=XthDayEachMonth(e.g. 3rd Friday each month) 96 # dow_weekly: Weekly repeat type only. Identical to bpcalender dow bits, multiple selections allowed(Bit0=sun,Bit1=mon,Bit2=tue,Bit3=wed,Bit4=thur,Bit5=fri,Bit6=sat) 97 # dow_monthly: Monthly repeat type 6 only. (0=sun,1=mon,2=tue,3=wed,4=thur,5=fri,6=sat) 98 # interval: repeat interval, eg. every 1 week, 2 weeks 4 weeks etc. Also be used for months, but bp does not support this. 99 # month_index: For type 4 this is the month the event starts in 100 # day_index: For type 6 this represents the number of the day that is the repeat, e.g. "2"nd tuesday 101 # For type 3&4 this is the day of the month that the repeat occurs, usually the same as the start date. 102 # bp does not support this not being the support date 103 104 dict={'sizeinbytes': 4} 105 dict.update(kwargs) 106 107 if self._ismostderived(LGCALREPEAT): 108 self._update(args, dict)
109
110 - def _update(self, args, kwargs):
111 for k in 'constant', 'default', 'value': 112 if kwargs.has_key(k): 113 kwargs[k]=self._converttoint(kwargs[k]) 114 if len(args)==0: 115 pass 116 elif len(args)==1: 117 args=(self._converttoint(args[0]),) 118 else: 119 raise TypeError("expected (type, dow, interval) as arg") 120 121 super(LGCALREPEAT,self)._update(args, kwargs) # we want the args 122 self._complainaboutunusedargs(LGCALDATE,kwargs) 123 assert self._sizeinbytes==4
124
125 - def getvalue(self):
126 val=super(LGCALREPEAT,self).getvalue() 127 type=val&0x7 # 3 bits 128 val>>=4 129 exceptions=val&0x1 130 val>>=1 131 #get day of week, only valid for some repeat types 132 #format of data is also different for different repeat types 133 interval2=(val>>9)&0x3f 134 if type==6: # for monthly repeats 135 dow=self._to_bp_dow[val&7] #day of month, valid for monthly repeat types, need to convert to bitpim format 136 elif type==2: #weekly 137 dow=val&0x7f # 7 bits, already matched bpcalender format 138 else: 139 dow=0 140 # get interval 141 if type==6: 142 val>>=20 143 interval=val&0x1f # day_index 144 else: 145 val>>=9 146 interval=val&0x3f 147 return (type, dow, interval, interval2, exceptions)
148 149 _caldomvalues={ 150 0x01: 0x0, #sun 151 0x02: 0x1, #mon 152 0x04: 0x2, #tue 153 0x08: 0x3, #wed 154 0x10: 0x4, #thur 155 0x20: 0x5, #fri 156 0x40: 0x6 #sat 157 } 158 _to_bp_dow={ 159 0: 0x01, # Sun 160 1: 0x02, # Mon 161 2: 0x04, # Tue 162 3: 0x08, # Wed 163 4: 0x10, # Thu 164 5: 0x20, # Fri 165 6: 0x40, # Sat 166 } 167
168 - def _converttoint(self, repeat):
169 if not isinstance(repeat, (tuple, list)): 170 if __debug__: 171 raise TypeError 172 else: 173 return 0 174 if len(repeat)!=5: 175 if __debug__: 176 raise ValueError 177 else: 178 return 0 179 type,dow,interval,interval2,exceptions=repeat 180 val=0 181 # construct bitmapped value for repeat 182 # look for weekday type 183 val=interval 184 if type==6 or type==3: 185 val<<=11 186 val|=interval2 187 if type==4: #yearly 188 val<<=11 189 val|=dow 190 val<<=9 191 if type==2: 192 val|=dow 193 elif type==6: 194 if self._caldomvalues.has_key(dow): 195 val|=self._caldomvalues[dow] 196 else: 197 # invalid day-of-week for monthly type, just bail 198 return 0 199 val<<=1 200 val|=exceptions 201 val<<=4 202 val|=type 203 return val
204
205 -class GPSDATE(prototypes.UINTlsb):
206 _time_t_ofs=calendar.timegm((1980, 1, 6, 0, 0, 0)) 207 _counter=0
208 - def __init__(self, *args, **kwargs):
209 """A date/time as used in the LG call history files, 210 @keyword unique: (True/False, Optional) Ensure that each GSPDATE instance 211 is unique. 212 @keyword raiseonbadvalue: (default False) raise L{ValueError} if the 213 GPSDATE value is bad. 214 """ 215 super(GPSDATE, self).__init__(*args, **kwargs) 216 self._unique=False 217 self._raiseonbadvalue=False 218 dict={'sizeinbytes': 4} 219 dict.update(kwargs) 220 221 if self._ismostderived(GPSDATE): 222 self._update(args, dict)
223
224 - def _update(self, args, kwargs):
225 self._consumekw(kwargs, ('unique', 'raiseonbadvalue')) 226 for k in 'constant', 'default', 'value': 227 if kwargs.has_key(k): 228 kwargs[k]=self._converttoint(kwargs[k]) 229 230 if len(args)==0: 231 pass 232 elif len(args)==1: 233 args=(self._converttoint(args[0]),) 234 else: 235 raise TypeError("expected (year,month,day,hour,minute,sec) as arg") 236 237 super(GPSDATE, self)._update(args, kwargs) # we want the args 238 self._complainaboutunusedargs(GPSDATE,kwargs) 239 assert self._sizeinbytes==4
240
241 - def getvalue(self):
242 """Convert 32 bit value into date/time 243 244 @rtype: tuple 245 @return: (year, month, day, hour, minute, sec) 246 """ 247 try: 248 return time.gmtime(self._time_t_ofs+super(GPSDATE, self).getvalue())[:6] 249 except ValueError: 250 if self._raiseonbadvalue: 251 raise 252 return (1980, 1, 6, 0, 0, 0)
253
254 - def _converttoint(self, date):
255 assert len(date)==6 256 _val=calendar.timegm(date)-self._time_t_ofs 257 if self._unique: 258 _val+=GPSDATE._counter 259 GPSDATE._counter+=1 260 if GPSDATE._counter==0xffff: 261 GPSDATE._counter=0 262 return _val
263 @classmethod
264 - def now(_):
265 return time.gmtime()[:6]
266
267 -class GSMCALDATE(prototypes.CSVSTRING):
268 """ Represent date string with format "YYMMDD*" 269 This format is being used in LG GSM Calendar Evetns 270 """
271 - def __init__(self, *args, **kwargs):
272 super(GSMCALDATE, self).__init__(*args, **kwargs) 273 self._data=None 274 self._readmode=True 275 if self._ismostderived(GSMCALDATE): 276 self._update(args, kwargs)
277
278 - def _set_data(self, v=None):
279 if v: 280 self._data=v[:3] 281 else: 282 self._data=(2000+int(self._value[:2]), int(self._value[2:4]), 283 int(self._value[4:6]))
284 - def _set_value(self):
285 self._value='%02d%02d%02d'%(self._data[0]-2000, self._data[1], 286 self._data[2])
287
288 - def _update(self, args, kwargs):
289 self._consumekw(kwargs, ('readmode',)) 290 if len(args)==1: 291 if isinstance(args[0], (list, tuple)): 292 super(GSMCALDATE, self)._update((), kwargs) 293 self._set_data(args[0]) 294 self._set_value() 295 elif isinstance(args[0], (str, unicode)): 296 super(GSMCALDATE, self)._update(args, kwargs) 297 self._set_data() 298 else: 299 raise TypeError 300 elif len(args)==0: 301 super(GSMCALDATE, self)._update(args, kwargs) 302 else: 303 raise TypeError 304 self._complainaboutunusedargs(GSMCALDATE, kwargs)
305
306 - def readfrombuffer(self, buf):
307 super(GSMCALDATE, self).readfrombuffer(buf) 308 if self._value: 309 self._set_data() 310 else: 311 self._data=None
312
313 - def getvalue(self):
314 """Returns the tuple of (year, month, day)""" 315 if self._data is None: 316 if self._value is None: 317 raise prototypes.ValueNotSetException() 318 self._set_data() 319 if self._readmode: 320 return self._data 321 else: 322 if self._quotechar: 323 _quote=chr(self._quotechar) 324 else: 325 _quote='' 326 return _quote+self._value+_quote
327
328 -class GSMCALTIME(GSMCALDATE):
329 """ Represent date time with format "hhm" 330 This format is being used in LG GSM Calendar Evetns 331 """ 332
333 - def __init__(self, *args, **kwargs):
334 super(GSMCALTIME, self).__init__(*args, **kwargs) 335 if self._ismostderived(GSMCALTIME): 336 self._update(args, kwargs)
337
338 - def _set_data(self, v=None):
339 if v: 340 self._data=v[:2] 341 else: 342 self._data=(int(self._value[:2]), int(self._value[2:4]))
343
344 - def _set_value(self):
345 self._value='%02d%02d'%self._data
346
347 -class SMSDATETIME(prototypes.CSVSTRING):
348 """ Represent date time with the format 'yy/MM/dd,hh:mm:ss+-zz' used 349 by GSM SMS messages. 350 Currently works only 1 way: SMS Date Time -> ISO String 351 """ 352 _re_pattern='^\d\d/\d\d/\d\d,\d\d:\d\d:\d\d[+\-]\d\d$' 353 _re_compiled_pattern=None
354 - def __init__(self, *args, **kwargs):
355 if SMSDATETIME._re_compiled_pattern is None: 356 SMSDATETIME._re_compiled_pattern=re.compile(SMSDATETIME._re_pattern) 357 super(SMSDATETIME, self).__init__(*args, **kwargs) 358 if self._ismostderived(SMSDATETIME): 359 self._update(args, kwargs)
360
361 - def _update(self, args, kwargs):
362 super(SMSDATETIME, self)._update(args, kwargs) 363 if self._value and \ 364 not re.match(SMSDATETIME._re_compiled_pattern, self._value): 365 raise ValueError('COrrect Format: yy/MM/dd,hh:mm:ss+-zz')
366
367 - def getvalue(self):
368 """Returns the ISO Format 'YYYMMDDTHHMMSS+-mmss'""" 369 if self._value: 370 _s=self._value.split(',') 371 return '20%sT%s00'%(_s[0].replace('/', ''), 372 _s[1].replace(':', ''))
373
374 -class TELUSLGCALREPEAT(prototypes.UINTlsb):
375 - def __init__(self, *args, **kwargs):
376 """A 32-bit bitmapped value used to store repeat info for events in the LG calendar""" 377 super(TELUSLGCALREPEAT,self).__init__(*args, **kwargs) 378 379 # The meaning of the bits in this field 380 # MSB LSB 381 # 3 2 1 382 # 10987654321098765432109876543210 383 # 210 repeat_type 384 # 0 exceptions, set to 1 if there are exceptions 385 # 6543210 dow_weekly (weekly repeat type) 386 # 210 dow (monthly repeat type) 387 # 543210 interval 388 # 3210 month_index 389 # 6543210 day_index 390 391 # repeat_type: 0=none, 1=daily, 2=weekdays, 3=weekly, 4=Month Nth Xday, 5=monthly on date, 6=yearly Nth Xday in month, 7=yearly on date 392 # dow_weekly: Weekly repeat type only. Identical to bpcalender dow bits, multiple selections allowed(Bit0=sun,Bit1=mon,Bit2=tue,Bit3=wed,Bit4=thur,Bit5=fri,Bit6=sat) 393 # dow_monthly: Monthly repeat type 6 only. (0=sun,1=mon,2=tue,3=wed,4=thur,5=fri,6=sat) 394 # interval: repeat interval, eg. every 1 week, 2 weeks 4 weeks etc. Also be used for months, but bp does not support this. 395 # month_index: For type 4 this is the month the event starts in 396 # day_index: For type 6 this represents the number of the day that is the repeat, e.g. "2"nd tuesday 397 # For type 3&4 this is the day of the month that the repeat occurs, usually the same as the start date. 398 # For type 0&2 set to 0x7F 399 # For type 1&3 set to 0 400 401 dict={'sizeinbytes': 4} 402 dict.update(kwargs) 403 404 if self._ismostderived(TELUSLGCALREPEAT): 405 self._update(args, dict)
406
407 - def _update(self, args, kwargs):
408 for k in 'constant', 'default', 'value': 409 if kwargs.has_key(k): 410 kwargs[k]=self._converttoint(kwargs[k]) 411 if len(args)==0: 412 pass 413 elif len(args)==1: 414 args=(self._converttoint(args[0]),) 415 else: 416 raise TypeError("expected (type, dow, interval) as arg") 417 418 super(TELUSLGCALREPEAT,self)._update(args, kwargs) # we want the args 419 self._complainaboutunusedargs(TELUSLGCALREPEAT,kwargs) 420 assert self._sizeinbytes==4
421
422 - def getvalue(self):
423 val=super(TELUSLGCALREPEAT,self).getvalue() 424 type=val&0x7 # 3 bits 425 val>>=4 426 exceptions=val&0x1 427 val>>=1 428 #get day of week, only valid for some repeat types 429 #format of data is also different for different repeat types 430 interval2=(val>>9)&0x3f 431 if type==4: # for monthly repeats 432 dow=self._to_bp_dow[val&7] #day of month, valid for monthly repeat types, need to convert to bitpim format 433 elif type==3: #weekly 434 dow=val&0x7f # 7 bits, already matched bpcalender format 435 else: 436 dow=0 437 # get interval 438 if type==4: 439 val>>=20 440 interval=val&0x1f # day_index 441 else: 442 val>>=9 443 interval=val&0x3f 444 return (type, dow, interval, interval2, exceptions)
445 446 _caldomvalues={ 447 0x01: 0x0, #sun 448 0x02: 0x1, #mon 449 0x04: 0x2, #tue 450 0x08: 0x3, #wed 451 0x10: 0x4, #thur 452 0x20: 0x5, #fri 453 0x40: 0x6 #sat 454 } 455 _to_bp_dow={ 456 0: 0x01, # Sun 457 1: 0x02, # Mon 458 2: 0x04, # Tue 459 3: 0x08, # Wed 460 4: 0x10, # Thu 461 5: 0x20, # Fri 462 6: 0x40, # Sat 463 } 464
465 - def _converttoint(self, repeat):
466 if not isinstance(repeat, (tuple, list)): 467 if __debug__: 468 raise TypeError 469 else: 470 return 0 471 if len(repeat)!=5: 472 if __debug__: 473 raise ValueError 474 else: 475 return 0 476 type,dow,interval,interval2,exceptions=repeat 477 val=0 478 # construct bitmapped value for repeat 479 val=interval 480 if type==0 or type==2: 481 val=0x7F 482 val<<=11 483 val|=interval 484 if type==4 or type==5: 485 val<<=11 486 val|=interval2 487 if type==7: #yearly 488 val<<=11 489 val|=dow 490 val<<=9 491 if type==2: 492 val|=dow 493 elif type==4: 494 val|=self._caldomvalues[dow] 495 val<<=1 496 val|=exceptions 497 val<<=4 498 val|=type 499 return val
500
501 #------------------------------------------------------------------------------- 502 -class T9USERDBBLOCK(prototypes.BaseProtogenClass):
503 """ 504 Special class to handle data blocks within the LG T9 User Database file. 505 Perhaps, the prototypes syntax should be enhanced to more gracefully 506 handle cases like this! 507 """ 508 509 # known types of this block 510 FreeBlock_Type='Free Block' 511 A0_Type='A0 Block' 512 WordsList_Type='Words List' 513 C_Type='C' 514 Garbage_Type='Garbage' 515
516 - def __init__(self, *args, **kwargs):
517 super(T9USERDBBLOCK, self).__init__(*args, **kwargs) 518 self._value=None 519 self._type=None 520 if self._ismostderived(T9USERDBBLOCK): 521 self._update(args, kwargs)
522
523 - def _update(self, args, kwargs):
524 super(T9USERDBBLOCK, self)._update(args, kwargs) 525 # we have no special keywords to process so complain away 526 self._complainaboutunusedargs(T9USERDBBLOCK, kwargs) 527 # Set our value if one was specified 528 if len(args)==0: 529 pass 530 elif len(args)==1: 531 self._set_value(args[0]) 532 else: 533 raise TypeError("Unexpected arguments "+`args`)
534
535 - def _set_value(self, v):
536 # set the value of this block 537 # the value must be a dict having 2 keys: 'type' and 'value' 538 if not isinstance(v, dict): 539 raise TypeError('Value must be a dict') 540 if not v.has_key('type') or not v.has_key('value'): 541 raise ValueError('Missing type or value keyword') 542 _type=v['type'] 543 _value=v['value'] 544 if _type==self.FreeBlock_Type: 545 # this is a free block, the value is an integer specifying 546 # the length of this free block 547 if not isinstance(_value, int): 548 raise TypeError('Value must be an int') 549 elif _type==self.WordsList_Type: 550 # this is a list of words, the value is a list of dicts, 551 # each dict should have 2 keys: 'word', 'weight'. 552 # value['word'] is a string 553 # value['weight'] is an int, default to 0xA000 554 if not isinstance(_value, list): 555 raise TypeError('Value must be a list of dicts') 556 elif _type==self.A0_Type: 557 _value=0xA0 558 else: 559 raise ValueError('Invalid type: '+_type) 560 self._type=_type 561 self._value=_value
562
563 - def _extract_words_list(self, buf):
564 # read and construct a word list 565 _res=[] 566 _size=buf.peeknextbyte() 567 while _size<0x80: 568 _size=buf.getnextbyte() 569 _weight=buf.getnextbyte()|(buf.getnextbyte()<<8) 570 _res.append({ 'word': buf.getnextbytes(_size), 571 'weight': _weight }) 572 _size=buf.peeknextbyte() 573 return _res
574 - def readfrombuffer(self, buf):
575 try: 576 self._bufferstartoffset=buf.getcurrentoffset() 577 _ch=buf.peeknextbyte() 578 if _ch&0xF0==0xC0: 579 self._type=self.C_Type 580 self._value='' 581 while True: 582 b=buf.getnextbytes(1) 583 self._value+=b 584 if b=='\x09': 585 self._value+=buf.getnextbytes(1) 586 break 587 elif _ch&0xF0==0xA0: 588 self._type=self.A0_Type 589 self._value=buf.getnextbyte() 590 elif _ch&0xF0==0x80: 591 self._type=self.FreeBlock_Type 592 self._value=((buf.getnextbyte()&0x0F)<<8)|buf.getnextbyte() 593 buf.getnextbytes(self._value-2) 594 elif _ch<0x80: 595 self._type=self.WordsList_Type 596 self._value=self._extract_words_list(buf) 597 else: 598 raise ValueError('Unknown block type: 0x%02X'%_ch) 599 except IndexError: 600 # ignore garbage at the end 601 self._type=self.Garbage_Type 602 self._value=0 603 ## print 'type:',self._type 604 ## print 'value:',self._value 605 self._bufferendoffset=buf.getcurrentoffset()
606
607 - def getvalue(self):
608 if self._value is None or self._type is None: 609 raise ValueNotSetException() 610 return { 'type': self._type, 611 'value': self._value }
612
613 - def packetsize(self):
614 # return the size of this packet 615 if self._value is None or self._type is None: 616 raise ValueNotSetException() 617 if self._type==self.C_Type or \ 618 self._type==self.A0_Type: 619 return len(self._value) 620 if self._type==self.FreeBlock_Type: 621 return self._value 622 if self._type==self.WordsList_Type: 623 _size=0 624 for _entry in self._value: 625 _size+=len(_entry['word'])+3 626 return _size
627
628 - def writetobuffer(self, buf):
629 if self._value is None or self._type is None: 630 raise ValueNotSetException() 631 self._bufferstartoffset=buf.getcurrentoffset() 632 if self._type==self.C_Type: 633 buf.appendbytes(self._value) 634 elif self._type==self.A0_Type: 635 buf.appendbyte(0xA0) 636 elif self._type==self.FreeBlock_Type: 637 buf.appendbyte(0x80|((self._value&0xF00)>>8)) 638 buf.appendbyte(self._value&0xff) 639 for _ in range(self._value-2): 640 buf.appendbyte(0) 641 elif self._type==self.WordsList_Type: 642 for _entry in self._value: 643 buf.appendbyte(len(_entry['word'])) 644 _weight=_entry.get('weight', 0xA000) 645 buf.appendbyte(_weight&0xff) 646 buf.appendbyte((_weight&0xFF00)>>8) 647 buf.appendbytes(_entry['word']) 648 self._bufferendoffset=buf.getcurrentoffset()
649
650 -class LGHEXPN(prototypes.DATA):
651 """ Phone numbers stored as hex. i.e. 0x5555551212f0 == 555-555-1212 652 """
653 - def __init__(self, *args, **kwargs):
654 """A date/time as used in the LG calendar""" 655 super(LGHEXPN,self).__init__(*args, **kwargs) 656 self._update(args, kwargs)
657
658 - def _update (self, args, kwargs):
659 for k in 'constant', 'default', 'value': 660 if kwargs.has_key(k): 661 kwargs[k]=self._string_to_lghexpn (kwargs[k]) 662 if len(args)==0: 663 pass 664 elif len(args)==1: 665 args = (self._string_to_lghexpn (args[0]),) 666 else: 667 raise TypeError("Expected phone number string as arg") 668 669 super(LGHEXPN,self)._update(args, kwargs)
670
671 - def _digit_to_char (self, digit):
672 if digit <= 0x09: 673 return chr (digit + ord('0')) 674 elif digit == 0x0A: 675 return '*' 676 elif digit == 0x0B: 677 return '#' 678 elif digit == 0x0C: 679 return 'W' 680 elif digit == 0x0D: 681 return 'P' 682 else: 683 # 0x0f is not an error 684 raise
685
686 - def _char_to_digit (self, char):
687 if char >= '0' and char <= '9': 688 return ord(char) - ord('0') 689 elif char == '*': 690 return 0x0A 691 elif char == '#': 692 return 0x0B 693 elif char == 'W': 694 return 0x0C 695 elif char == 'P': 696 return 0x0D 697 else: 698 raise ValueError
699
700 - def _string_to_lghexpn (self, pn):
701 val = '' 702 703 byte = 0xf0 704 for i in range(0, len (pn)): 705 digit = self._char_to_digit (pn[i]) 706 if i % 2: 707 val += chr(byte & (0xf0 | digit)) 708 byte = 0xf0 709 else: 710 byte = (digit << 4) | 0x0f 711 # write terminating byte 712 val += chr(byte) 713 714 return val
715
716 - def getvalue(self):
717 """Unpack hex phone number 718 719 @rtype: string 720 @return: phone number 721 """ 722 val=super(LGHEXPN,self).getvalue() 723 pn = '' 724 for byte in val: 725 fd = ord(byte) >> 4 726 sd = ord(byte) & 0x0f 727 728 try: 729 pn += self._digit_to_char(fd) 730 pn += self._digit_to_char(sd) 731 except: 732 # end of packed number, not an error 733 break 734 return pn
735
736 -class PBDateTime(prototypes.BaseProtogenClass):
737 "Handle six 2-byte UINTs: y, m, d, h, m, s" 738
739 - def __init__(self, *args, **kwargs):
740 """ 741 Class to handle the date/time format of 6 2-byte UINTs: y, m, d, h, m, s 742 @keyword default: (Optional) Our default value 743 @keyword defaulttocurrenttime: (Optional) Default to the current date/time 744 """ 745 super(PBDateTime, self).__init__(*args, **kwargs) 746 self._default=None 747 self._defaulttocurrenttime=False 748 self._value=None 749 750 if self._ismostderived(PBDateTime): 751 self._update(args, kwargs)
752
753 - def _update(self, args, kwargs):
754 super(PBDateTime, self)._update(args, kwargs) 755 self._consumekw(kwargs, ("default", "defaulttocurrenttime", "value")) 756 self._complainaboutunusedargs(PBDateTime, kwargs) 757 758 if len(args)==0: 759 pass 760 elif len(args)==1: 761 self._value=args[0] 762 else: 763 raise TypeError("Unexpected arguments "+`args`) 764 765 if self._value is None: 766 # value not specified, check for either default or default to 767 # current time 768 if self._default: 769 self._value=self._default 770 elif self._defaulttocurrenttime: 771 self._value=time.localtime()[:6]
772
773 - def readfrombuffer(self, buf):
774 self._bufferstartoffset=buf.getcurrentoffset() 775 776 _res=[] 777 for i in range(6): 778 _res.append(buf.getnextbyte()|(buf.getnextbyte()<<8)) 779 self._value=_res 780 781 self._bufferendoffset=buf.getcurrentoffset()
782
783 - def writetobuffer(self, buf):
784 if self._value is None: 785 raise ValueNotSetException() 786 if not isinstance(self._value, (list, tuple)): 787 raise TypeError('value needs to be a list/tuple') 788 if len(self._value)!=6: 789 raise TypeError('len of value needs to be 6') 790 791 self._bufferstartoffset=buf.getcurrentoffset() 792 for _num in self._value: 793 buf.appendbyte(_num&0xff) 794 buf.appendbyte((_num>>8)&0xff) 795 self._bufferendoffset=buf.getcurrentoffset()
796
797 - def packetsize(self):
798 """Size in bytes""" 799 return 12
800
801 - def getvalue(self):
802 if self._value is None: 803 raise ValueNotSetException() 804 return self._value
805