Discussion:
unknown
1970-01-01 00:00:00 UTC
Permalink
#------------------------------------------------------------------------=
-------
class NumericDataItem(DataItem):
_fmts=3D{ # struct pack/unpack formats
True: { # unsigned
True: { # little endian
1: 'B', 2: '<H', 4: '<I' }, # size
False: { # big endian
1: 'B', 2: '>H', 4: '>I' } }, # size
False: { # signed
True: { # little endian
1: 'b', 2: '<h', 4: '<i' }, # size
False: { # big endian
1: 'b', 2: '>h', 4: '>i' } } } # size
=20
def __init__(self, name):
super(NumericDataItem, self).__init__(name, self.numeric_type)
def get(self):
r=3Dsuper(NumericDataItem, self).get()
r.update(
{ 'unsigned': self.unsigned,
'little_endian': self.LE,
'size': self.size })
return r
def set(self, d):
super(NumericDataItem, self).set(d)
if d.get('type', None)!=3Dself.numeric_type:
raise TypeError
self.unsigned=3Dd.get('unsigned', True)
self.LE=3Dd.get('little_endian', True)
self.size=3Dd.get('size', 1)
def encode(self, s, start=3DNone):
fmt=3Dself._fmts[self.unsigned][self.LE][self.size]
self.len=3Dstruct.calcsize(fmt)
if self.offset_type=3D=3Dself.offset_from_start:
self.start=3Dself.offset
else:
if start is None:
raise ValueError
self.start=3Dstart+self.offset
return struct.unpack(fmt, s[self.start:self.start+self.len])[0]

#------------------------------------------------------------------------=
-------
class StringDataItem(DataItem):
def __init__(self, name):
super(StringDataItem, self).__init__(name, self.string_type)
def get(self):
r=3Dsuper(StringDataItem, self).get()
r.update({ 'fixed': self.fixed, 'size': self.size,
'null_terminated': self.null_terminated })
return r
def set(self, d):
super(StringDataItem, self).set(d)
if d.get('type', None)!=3Dself.string_type:
raise TypeError
self.fixed=3Dd.get('fixed', True)
self.size=3Dd.get('size', 0)
self.null_terminated=3Dd.get('null_terminated', False)
def encode(self, s, start=3DNone):
if self.offset_type=3D=3Dself.offset_from_start:
self.start=3Dself.offset
else:
if start is None:
raise ValueError
self.start=3Dstart+self.offset
if self.fixed:
# fixed length string
if self.size=3D=3D-1:
# take all available space
self.len=3Dlen(s)-self.offset
s0=3Ds[self.start:]
else:
# fixed size
s0=3Ds[self.start:self.start+self.size]
self.len=3Dself.size
else:
# pascal style variable string
self.len=3Dord(s[self.start])
s0=3Ds[self.start+1:self.start+1+self.len]
if self.null_terminated:
i=3Ds0.find('\x00')
if i=3D=3D-1:
return s0
else:
self.len=3Di
return s0[:i]
else:
return s0

#------------------------------------------------------------------------=
-------
class GeneralInfoSizer(wx.FlexGridSizer):
def __init__(self, parent):
super(GeneralInfoSizer, self).__init__(-1, 2, 5, 5)
self.AddGrowableCol(1)
self.Add(wx.StaticText(parent, -1, 'Struct Name:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._struct_name=3Dwx.TextCtrl(parent, -1, '')
self.Add(self._struct_name, 0, wx.EXPAND|wx.ALL, 5)
self.Add(wx.StaticText(parent, -1, 'Field Name:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._name=3Dwx.TextCtrl(parent, -1, '')
self.Add(self._name, 0, wx.EXPAND|wx.ALL, 5)
self.Add(wx.StaticText(parent, -1, 'Type:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._type=3Dwx.ComboBox(parent, wx.NewId(),
choices=3D[DataItem.numeric_type,
DataItem.string_type],
value=3DDataItem.numeric_type,
style=3Dwx.CB_DROPDOWN|wx.CB_READONLY)
self.Add(self._type, 0, wx.EXPAND|wx.ALL, 5)
self.Add(wx.StaticText(parent, -1, 'Offset Type:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._offset_type=3Dwx.ComboBox(parent, -1,
=
value=3DDataItem.offset_from_start,
=
choices=3D[DataItem.offset_from_start,
=
DataItem.offset_from_prev],
=
style=3Dwx.CB_DROPDOWN|wx.CB_READONLY)
self.Add(self._offset_type, 0, wx.EXPAND|wx.ALL, 5)
self.Add(wx.StaticText(parent, -1, 'Offset Value:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._offset=3Dmasked.NumCtrl(parent, wx.NewId(),
allowNegative=3DFalse,
min=3D0)
self.Add(self._offset, 0, wx.ALL, 5)
self._fields_group=3D(self._name, self._type, self._offset_type,
self._offset)
def set(self, data):
if isinstance(data, DataStruct):
self._struct_name.SetValue(data.name)
elif isinstance(data, DataItem):
self._name.SetValue(data.name)
self._type.SetValue(data.type)
self._offset_type.SetValue(data.offset_type)
self._offset.SetValue(data.offset)
def get(self, data):
data.name=3Dself._name.GetValue()
data.type=3Dself._type.GetValue()
data.offset_type=3Dself._offset_type.GetValue()
data.offset=3Dint(self._offset.GetValue())
return data
def show(self, show_struct=3DFalse, show_field=3DFalse):
self._struct_name.Enable(show_struct)
for w in self._fields_group:
w.Enable(show_field)
def _get_struct_name(self):
return self._struct_name.GetValue()
struct_name=3Dproperty(fget=3D_get_struct_name)
def _get_type(self):
return self._type.GetValue()
type=3Dproperty(fget=3D_get_type)
def _get_type_id(self):
return self._type.GetId()
type_id=3Dproperty(fget=3D_get_type_id)
=20
#------------------------------------------------------------------------=
-------
class NumericInfoSizer(wx.FlexGridSizer):
_sign_choices=3D['Unsigned', 'Signed']
_endian_choices=3D['Little Endian', 'Big Endian']
_size_choices=3D['1', '2', '4']
def __init__(self, parent):
super(NumericInfoSizer, self).__init__(-1, 2, 5, 5)
self.AddGrowableCol(1)
self.Add(wx.StaticText(parent, -1, 'Signed:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._sign=3Dwx.ComboBox(parent, -1, =
value=3Dself._sign_choices[0],
choices=3Dself._sign_choices,
style=3Dwx.CB_DROPDOWN|wx.CB_READONLY)
self.Add(self._sign, 0, wx.EXPAND|wx.ALL, 5)
self.Add(wx.StaticText(parent, -1, 'Endian:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._endian=3Dwx.ComboBox(parent, -1, =
value=3Dself._endian_choices[0],
choices=3Dself._endian_choices,
style=3Dwx.CB_DROPDOWN|wx.CB_READONLY)
self.Add(self._endian, 0, wx.EXPAND|wx.ALL, 5)
self.Add(wx.StaticText(parent, -1, 'Size:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._size=3Dwx.ComboBox(parent, -1, =
value=3Dself._size_choices[0],
choices=3Dself._size_choices,
style=3Dwx.CB_DROPDOWN|wx.CB_READONLY)
self.Add(self._size, 0, wx.EXPAND|wx.ALL, 5)
def set(self, data):
if data.unsigned:
self._sign.SetValue(self._sign_choices[0])
else:
self._sign.SetValue(self._sign_choices[1])
if data.LE:
self._endian.SetValue(self._endian_choices[0])
else:
self._endian.SetValue(self._endian_choices[1])
self._size.SetValue(`data.size`)
def get(self, data):
data.unsigned=3Dself._sign.GetValue()=3D=3Dself._sign_choices[0]
data.LE=3Dself._endian.GetValue()=3D=3Dself._endian_choices[0]
data.size=3Dint(self._size.GetValue())
return data

#------------------------------------------------------------------------=
-------
class StringInfoSizer(wx.FlexGridSizer):
_fixed_choices=3D['Fixed', 'Pascal']
def __init__(self, parent):
super(StringInfoSizer, self).__init__(-1, 2, 5, 5)
self.AddGrowableCol(1)
self.Add(wx.StaticText(parent, -1, 'Fixed/Pascal:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._fixed=3Dwx.ComboBox(parent, -1, =
value=3Dself._fixed_choices[0],
choices=3Dself._fixed_choices,
style=3Dwx.CB_DROPDOWN|wx.CB_READONLY)
self.Add(self._fixed, 0, wx.EXPAND|wx.ALL, 5)
self.Add(wx.StaticText(parent, -1, 'Max Length:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._max_len=3Dmasked.NumCtrl(parent, -1, value=3D1, min=3D-1)
self.Add(self._max_len, 0, wx.EXPAND|wx.ALL, 5)
self.Add(wx.StaticText(parent, -1, 'Null Terminated:'), 0, =
wx.EXPAND|wx.ALL, 5)
self._null_terminated=3Dwx.CheckBox(parent, -1)
self.Add(self._null_terminated, 0, wx.EXPAND|wx.ALL, 5)
def set(self, data):
if data.fixed:
self._fixed.SetValue(self._fixed_choices[0])
else:
self._fixed.SetValue(self._fixed_choices[1])
self._max_len.SetValue(`data.size`)
self._null_terminated.SetValue(data.null_terminated)
def get(self, data):
data.fixed=3Dself._fixed.GetValue()=3D=3Dself._fixed_choices[0]
data.size=3Dint(self._max_len.GetValue())
data.null_terminated=3Dself._null_terminated.GetValue()
return data
=20
#------------------------------------------------------------------------=
-------
class TemplateDialog(wx.Dialog):
_type_choices=3D['Numeric', 'String']
_struct_type=3D'struct'
_field_type=3D'field'
def __init__(self, parent):
super(TemplateDialog, self).__init__(parent, -1,
'Hex Template Editor',
=
style=3Dwx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
self._data=3D[]
self._item_tree=3Dself._numeric_bs=3Dself._string_bs=3DNone
self._general_bs=3DNone
self._tree_root=3DNone
self._field_info=3Dself._field_info_hbs=3DNone
self._info_sizer=3D{ NumericDataItem.numeric_type: =
self._numeric_bs,
StringDataItem.string_type: self._string_bs }
main_vbs=3Dwx.BoxSizer(wx.VERTICAL)
hbs1=3Dwx.BoxSizer(wx.HORIZONTAL)
hbs1.Add(self._create_tree_pane(), 1, wx.EXPAND|wx.ALL, 5)
hbs1.Add(self._create_info_pane(), 2, wx.EXPAND|wx.ALL, 5)
main_vbs.Add(hbs1, 1, wx.EXPAND|wx.ALL, 5)
main_vbs.Add(wx.StaticLine(self, -1, style=3Dwx.LI_HORIZONTAL), =
0, wx.EXPAND|wx.ALL, 5)
main_vbs.Add(self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.HELP), 0, =
wx.ALIGN_CENTRE|wx.ALL, 5)
self.SetSizer(main_vbs)
self.SetAutoLayout(True)
main_vbs.Fit(self)

def _create_tree_pane(self):
vbs=3Dwx.BoxSizer(wx.VERTICAL)
sw=3Dscrolled.ScrolledPanel(self, -1)
self._item_tree=3Dwx.TreeCtrl(sw, wx.NewId(),
=
style=3Dwx.TR_DEFAULT_STYLE|wx.TR_HAS_BUTTONS)
wx.EVT_TREE_SEL_CHANGED(self, self._item_tree.GetId(),
self._OnTreeSel)
self._tree_root=3Dself._item_tree.AddRoot('Data Templates')
sw_bs=3Dwx.BoxSizer(wx.VERTICAL)
sw_bs.Add(self._item_tree, 1, wx.EXPAND|wx.ALL, 0)
sw.SetSizer(sw_bs)
sw.SetAutoLayout(True)
sw_bs.Fit(sw)
sw.SetupScrolling()
vbs.Add(sw, 1, wx.EXPAND|wx.ALL, 5)
hbs=3Dwx.BoxSizer(wx.HORIZONTAL)
hbs.Add(wx.Button(self, wx.ID_ADD, 'Add'), 0, wx.EXPAND|wx.ALL, =
5)
hbs.Add(wx.Button(self, wx.ID_DELETE, 'Delete'), 0, =
wx.EXPAND|wx.ALL, 5)
wx.EVT_BUTTON(self, wx.ID_ADD, self._OnAdd)
wx.EVT_BUTTON(self, wx.ID_DELETE, self._OnDelete)
vbs.Add(hbs, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5)
return vbs
def _create_info_pane(self):
# main boxsize
vbs=3Dwx.BoxSizer(wx.VERTICAL)
hbs=3Dwx.BoxSizer(wx.HORIZONTAL)
# Type & offset
static_bs=3Dwx.StaticBoxSizer(wx.StaticBox(self, -1, 'Field =
Type'),
wx.VERTICAL)
self._general_bs=3DGeneralInfoSizer(self)
wx.EVT_COMBOBOX(self, self._general_bs.type_id, =
self._OnTypeChanged)
static_bs.Add(self._general_bs, 0, wx.EXPAND|wx.ALL, 5)
hbs.Add(static_bs, 0, wx.ALL, 5)
# all info
self._field_info=3Dwx.StaticBoxSizer(wx.StaticBox(self, -1, =
'Field Info'),
wx.VERTICAL)
# numeric info box
self._numeric_bs=3DNumericInfoSizer(self)
self._field_info.Add(self._numeric_bs, 0, wx.EXPAND|wx.ALL, 5)
self._string_bs=3DStringInfoSizer(self)
self._field_info.Add(self._string_bs, 0, wx.EXPAND|wx.ALL, 5)
hbs.Add(self._field_info, 0, wx.ALL, 5)
vbs.Add(hbs, 1, wx.EXPAND|wx.ALL, 5)
hbs1=3Dwx.BoxSizer(wx.HORIZONTAL)
hbs1.Add(wx.Button(self, wx.ID_SAVE, 'Set'), 0, =
wx.EXPAND|wx.ALL, 5)
hbs1.Add(wx.Button(self, wx.ID_REVERT, 'Revert'), 0, =
wx.EXPAND|wx.ALL, 5)
wx.EVT_BUTTON(self, wx.ID_SAVE, self._OnSave)
wx.EVT_BUTTON(self, wx.ID_REVERT, self._OnRevert)
vbs.Add(hbs1, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
self._field_info_hbs=3Dhbs
return vbs
def _show_field_info(self, _struct=3DFalse, field=3DFalse,
numeric_field=3DFalse, string_field=3DFalse):
# show/hide individual fields
self._general_bs.show(_struct, field)
self._field_info.Show(self._numeric_bs, numeric_field)
self._field_info.Show(self._string_bs, string_field)
self._field_info.Layout()
self._field_info_hbs.Layout()
def _populate(self):
# clear the tree and repopulate
self._item_tree.DeleteChildren(self._tree_root)
for i,e in enumerate(self._data):
item=3Dself._item_tree.AppendItem(self._tree_root, e.name)
self._item_tree.SetPyData(item, { 'type': self._struct_type,
'index': i })
for i1,e1 in enumerate(e.fields):
field_item=3Dself._item_tree.AppendItem(item, e1.name)
self._item_tree.SetPyData(field_item, { 'type': =
self._field_type,
'index': i,
'field_index': =
i1 })
self.expand()
def _populate_struct(self, _item_index):
self._general_bs.set(self._data[_item_index])
self._show_field_info(True)
def _populate_each(self, _struct_index, _item_index):
_struct=3Dself._data[_struct_index]
_item=3D_struct.fields[_item_index]
self._general_bs.set(_item)
if _item.type=3D=3DDataItem.numeric_type:
self._show_field_info(True, True, True)
self._numeric_bs.set(_item)
else:
self._show_field_info(True, True, False, True)
self._string_bs.set(_item)
def _OnTypeChanged(self, _):
new_type=3Dself._general_bs.type
self._show_field_info(True, True, =
new_type=3D=3DDataItem.numeric_type,
new_type=3D=3DDataItem.string_type)
def _OnAdd(self, _):
sel_idx=3Dself._item_tree.GetSelection()
if not sel_idx.IsOk():
return
if sel_idx=3D=3Dself._tree_root:
# add a new structure
struct_item=3DDataStruct('New Struct')
self._data.append(struct_item)
else:
# add a new field to the existing structure
data_item=3Dself._item_tree.GetPyData(sel_idx)
item=3DNumericDataItem('New Field')
self._data[data_item['index']].fields.append(item)
self._populate()
def _OnDelete(self, _):
sel_idx=3Dself._item_tree.GetSelection()
if not sel_idx.IsOk():
return
node_data=3Dself._item_tree.GetPyData(sel_idx)
if node_data is None:
return
if node_data['type']=3D=3Dself._field_type:
# del this field
del =
self._data[node_data['index']].fields[node_data['field_index']]
else:
# del this struct and its fields
del self._data[node_data['index']]
# and re-populate the tree
self._populate()
def _OnSave(self, _):
sel_idx=3Dself._item_tree.GetSelection()
if not sel_idx.IsOk():
return
node_data=3Dself._item_tree.GetPyData(sel_idx)
if node_data is None:
return
# update the struct name
=
self._data[node_data['index']].name=3Dself._general_bs.struct_name
if node_data['type']=3D=3Dself._field_type:
data_item=3Dself._data[node_data['index']].\
fields[node_data['field_index']]
data_item=3Dself._general_bs.get(data_item)
if data_item.type=3D=3DDataItem.numeric_type:
data_item=3Dself._numeric_bs.get(data_item)
else:
data_item=3Dself._string_bs.get(data_item)
=
self._data[node_data['index']].fields[node_data['field_index']]=3Ddata_it=
em
=
self._item_tree.SetItemText(self._item_tree.GetItemParent(sel_idx),
=
self._data[node_data['index']].name)
self._item_tree.SetItemText(sel_idx, data_item.name)
else:
self._item_tree.SetItemText(sel_idx, =
self._data[node_data['index']].name)
=20
def _OnRevert(self, _):
sel_idx=3Dself._item_tree.GetSelection()
if not sel_idx.IsOk():
return
node_data=3Dself._item_tree.GetPyData(sel_idx)
if node_data is None:
self._show_field_info()
else:
self._populate_struct(node_data['index'])
if node_data['type']=3D=3Dself._field_type:
self._populate_each(node_data['index'], =
node_data['field_index'])

def _OnTreeSel(self, evt):
sel_idx=3Devt.GetItem()
if not sel_idx.IsOk():
# invalid selection
return
item_data=3Dself._item_tree.GetPyData(sel_idx)
if item_data is None:
self._show_field_info()
else:
self._populate_struct(item_data['index'])
if item_data['type']=3D=3Dself._field_type:
self._populate_each(item_data['index'], =
item_data['field_index'])
def expand(self):
# expand the tree
self._item_tree.Expand(self._tree_root)
(id, cookie)=3Dself._item_tree.GetFirstChild(self._tree_root)
while id.IsOk():
self._item_tree.Expand(id)
(id, cookie)=3Dself._item_tree.GetNextChild(self._tree_root, =
cookie)
def set(self, l):
self._data=3Dl
self._populate()
def get(self):
return self._data
=20
#------------------------------------------------------------------------=
-------
class HexEditor(wx.ScrolledWindow):

_addr_range=3Dxrange(8)
_hex_range_start=3D10
_hex_range_start2=3D33
_hex_range=3Dxrange(_hex_range_start, 58)
_ascii_range_start=3D60
_ascii_range=3Dxrange(60, 76)

def __init__(self, parent, id=3D-1, style=3Dwx.WANTS_CHARS,
_set_pos=3DNone, _set_sel=3DNone, _set_val=3DNone):
wx.ScrolledWindow.__init__(self, parent, id, style=3Dstyle)
self.parent=3Dparent
self.data=3D""
self.title=3D""
self.buffer=3DNone
self.hasfocus=3DFalse
self.dragging=3DFalse
self.current_ofs=3DNone
self._module=3DNone
self._templates=3D[]
self._search_string=3DNone
# ways of displaying status
self.set_pos=3D_set_pos or self._set_pos
self.set_val=3D_set_val or self._set_val
self.set_sel=3D_set_sel or self._set_sel
# some GUI setup
self.SetBackgroundColour("WHITE")
self.SetCursor(wx.StockCursor(wx.CURSOR_IBEAM))
self.sethighlight(wx.NamedColour("BLACK"), =
wx.NamedColour("YELLOW"))
self.setnormal(wx.NamedColour("BLACK"), wx.NamedColour("WHITE"))
self.setfont(wx.TheFontList.FindOrCreateFont(10, wx.MODERN, =
wx.NORMAL, wx.NORMAL))
self.OnSize(None)
self.highlightrange(None, None)
# other stuff
self._create_context_menu()
self._map_events()

def _map_events(self):
wx.EVT_SCROLLWIN(self, self.OnScrollWin)
wx.EVT_PAINT(self, self.OnPaint)
wx.EVT_SIZE(self, self.OnSize)
wx.EVT_ERASE_BACKGROUND(self, self.OnEraseBackground)
wx.EVT_SET_FOCUS(self, self.OnGainFocus)
wx.EVT_KILL_FOCUS(self, self.OnLoseFocus)
wx.EVT_LEFT_DOWN(self, self.OnStartSelection)
wx.EVT_LEFT_UP(self, self.OnEndSelection)
wx.EVT_MOTION(self, self.OnMakeSelection)
wx.EVT_RIGHT_UP(self, self.OnRightClick)

def _create_context_menu(self):
self._reload_menu_id=3Dself._apply_menu_id=3DNone
menu_items=3D(
('File', (('Load', self.OnLoadFile),
('Save As', self.OnSaveAs),
('Save Selection As', self.OnSaveSelection),
('Save Hexdump As', self.OnSaveHexdumpAs))),
('Set Selection', (('Start', self.OnStartSelMenu),
('End', self.OnEndSelMenu))),
('Value', self.OnViewValue),
('Search', (('Search', self.OnSearch),
('Search Again', self.OnSearchAgain))),
('Import Python Module', self.OnImportModule),
('Reload Python Module', self.OnReloadModule, =
'_reload_menu_id'),
('Apply Python Func', self.OnApplyFunc, '_apply_menu_id'),
('Template', (('Load', self.OnTemplateLoad),
('Save As', self.OnTemplateSaveAs),
('Edit', self.OnTemplateEdit),
('Apply', self.OnTemplateApply)))
)
self._bgmenu=3Dwx.Menu()
for menu_item in menu_items:
if isinstance(menu_item[1], tuple):
# submenu
sub_menu=3Dwx.Menu()
for submenu_item in menu_item[1]:
id=3Dwx.NewId()
sub_menu.Append(id, submenu_item[0])
wx.EVT_MENU(self, id, submenu_item[1])
self._bgmenu.AppendMenu(wx.NewId(), menu_item[0], =
sub_menu)
else:
# regular menu item
id=3Dwx.NewId()
self._bgmenu.Append(id, menu_item[0])
wx.EVT_MENU(self, id, menu_item[1])
if len(menu_item)>2:
# need to save menu ID
setattr(self, menu_item[2], id)

def SetData(self, data):
self.data=3Ddata
self.needsupdate=3DTrue
self.updatescrollbars()
self.Refresh()

def SetTitle(self, title):
self.title=3Dtitle

def SetStatusDisplay(self, _set_pos=3DNone, _set_sel=3DNone, =
_set_val=3DNone):
self.set_pos=3D_set_pos or self._set_pos
self.set_sel=3D_set_sel or self._set_sel
self.set_val=3D_set_val or self._set_val

def OnEraseBackground(self, _):
pass
def _set_pos(self, pos):
pass
def _set_sel(self, sel_start, sel_end):
pass
def _set_val(self, v):
pass

def _to_char_line(self, x, y):
"""Convert an x,y point to (char, line)
"""
return x/self.charwidth, y/self.charheight
def _to_xy(self, char, line):
return char*self.charwidth, line*self.charheight
def _to_buffer_offset(self, char, line):
if char in self._hex_range:
if char>self._hex_range_start2:
char-=3D1
if ((char-self._hex_range_start)%3)<2:
return line*16+(char-self._hex_range_start)/3
elif char in self._ascii_range:
return line*16+char-self._ascii_range_start
def _set_and_move(self, evt):
c,l=3Dself._to_char_line(evt.GetX(), evt.GetY())
self.GetCaret().Move(self._to_xy(c, l))
x0, y0=3Dself.GetViewStart()
char_x=3Dc+x0
line_y=3Dl+y0
return self._to_buffer_offset(char_x, line_y)
_value_formats=3D(
('unsigned char', 'B', struct.calcsize('B')),
('signed char', 'b', struct.calcsize('b')),
('LE unsigned short', '<H', struct.calcsize('<H')),
('LE signed short', '<h', struct.calcsize('<h')),
('BE unsigned short', '>H', struct.calcsize('>H')),
('BE signed short', '>h', struct.calcsize('>h')),
('LE unsigned int', '<I', struct.calcsize('<I')),
('LE signed int', '<i', struct.calcsize('<i')),
('BE unsigned int', '>I', struct.calcsize('>I')),
('BE signed int', '>i', struct.calcsize('>i')),
)
def _gen_values(self, _data, _ofs):
""" Generate the values of various number formats starting at =
the
current offset.
"""
n=3D_data[_ofs:]
len_n=3Dlen(n)
s=3D'0x%X=3D%d'%(_ofs, _ofs)
res=3D[{ 'Data Offset': s}, {'':''} ]
for i,e in enumerate(self._value_formats):
if len_n<e[2]:
continue
v=3Dstruct.unpack(e[1], n[:e[2]])[0]
if i%2:
s=3D'%d'%v
else:
fmt=3D'0x%0'+str(e[2]*2)+'X=3D%d'
s=3Dfmt%(v,v)
res.append({ e[0]: s })
return res

def _apply_template(self, template_name):
# if user specifies a block, encode that,
if self.highlightstart is None or self.highlightstart=3D=3D-1 or =
\
self.highlightend is None or self.highlightend=3D=3D-1:
# no selection
_data=3Dself.data[self.current_ofs:]
_ofs=3Dself.current_ofs
else:
_data=3Dself.data[self.highlightstart:self.highlightend]
_ofs=3Dself.highlightstart
for f in self._templates:
if f.name=3D=3Dtemplate_name:
l=3D[{ 'Template': f.name },
{ 'Data Offset': '0x%04X=3D%d'%(_ofs, _ofs) }]
return l+f.encode(_data, _ofs)
return []

def _display_result(self, result):
""" Display the results from applying a Python routine over the =
data
"""
s=3D''
for d in result:
for k,e in d.items():
s+=3Dk+':\t'+e+'\n'
dlg=3Dwx.MessageDialog(self, s, 'Results', style=3Dwx.OK)
dlg.ShowModal()
dlg.Destroy()

def OnLoadFile(self, _):
dlg=3Dwx.FileDialog(self, 'Select a file to load',
style=3Dwx.OPEN|wx.FILE_MUST_EXIST)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
self.SetData(file(dlg.GetPath(), 'rb').read())
dlg.Destroy()
def OnSaveAs(self, _):
dlg=3Dwx.FileDialog(self, 'Select a file to save',
style=3Dwx.SAVE|wx.OVERWRITE_PROMPT)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
file(dlg.GetPath(), 'wb').write(self.data)
dlg.Destroy()
def hexdumpdata(self):
res=3D""
l=3Dlen(self.data)
if self.title:
res +=3D self.title+": "+`l`+" bytes\n"
res +=3D "<#! !#>\n"
pos=3D0
while pos<l:
text=3D"%08X "%(pos)
line=3Dself.data[pos:pos+16]
for i in range(len(line)):
text+=3D"%02X "%(ord(line[i]))
text+=3D" "*(16-len(line))
text+=3D" "
for i in range(len(line)):
c=3Dline[i]
if (ord(c)>=3D32 and string.printable.find(c)>=3D0):
text+=3Dc
else:
text+=3D'.'
res+=3Dtext+"\n"
pos+=3D16
return res
=20
def OnSaveHexdumpAs(self, _):
dlg=3Dwx.FileDialog(self, 'Select a file to save',
style=3Dwx.SAVE|wx.OVERWRITE_PROMPT)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
file(dlg.GetPath(), 'wb').write(self.hexdumpdata())
dlg.Destroy()
def OnSaveSelection(self, _):
if self.highlightstart is None or self.highlightstart=3D=3D-1 or =
\
self.highlightend is None or self.highlightend=3D=3D-1:
# no selection
return
dlg=3Dwx.FileDialog(self, 'Select a file to save',
style=3Dwx.SAVE|wx.OVERWRITE_PROMPT)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
file(dlg.GetPath(), 'wb').write(
self.data[self.highlightstart:self.highlightend])
dlg.Destroy()

def OnReloadModule(self, _):
try:
reload(self._module)
except:
self._module=3DNone
w=3Dwx.MessageDialog(self, 'Failed to reload module',
'Reload Module Error',
style=3Dwx.OK|wx.ICON_ERROR)
w.ShowModal()
w.Destroy()
def OnApplyFunc(self, _):
choices=3D[x for x in dir(self._module) \
if callable(getattr(self._module, x))]
dlg=3Dwx.SingleChoiceDialog(self, 'Select a function to apply:',
'Apply Python Func',
choices)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
try:
res=3Dgetattr(self._module, dlg.GetStringSelection())(
self, self.data, self.current_ofs)
self._display_result(res)
except:
w=3Dwx.MessageDialog(self, 'Apply Func raised an =
exception',
'Apply Func Error',
style=3Dwx.OK|wx.ICON_ERROR)
w.ShowModal()
w.Destroy()
dlg.Destroy()
def OnImportModule(self, _):
dlg=3Dwx.TextEntryDialog(self, 'Enter the name of a Python =
Module:',
'Module Import')
if dlg.ShowModal()=3D=3Dwx.ID_OK:
try:
self._module=3D__import__(dlg.GetValue())
except ImportError:
self._module=3DNone
w=3Dwx.MessageDialog(self, 'Failed to import module: =
'+dlg.GetValue(),
'Module Import Error',
style=3Dwx.OK|wx.ICON_ERROR)
w.ShowModal()
w.Destroy()
dlg.Destroy()

def OnStartSelMenu(self, evt):
ofs=3Dself.current_ofs
if ofs is not None:
self.highlightstart=3Dofs
self.needsupdate=3DTrue
self.Refresh()
self.set_sel(self.highlightstart, self.highlightend)
=20
def OnEndSelMenu(self, _):
ofs=3Dself.current_ofs
if ofs is not None:
self.highlightend=3Dofs+1
self.needsupdate=3DTrue
self.Refresh()
self.set_sel(self.highlightstart, self.highlightend)

def OnViewValue(self, _):
ofs=3Dself.current_ofs
if ofs is not None:
self._display_result(self._gen_values(self.data, ofs))

def OnStartSelection(self, evt):
self.highlightstart=3Dself.highlightend=3DNone
ofs=3Dself._set_and_move(evt)
if ofs is not None:
self.highlightstart=3Dofs
self.dragging=3DTrue
self.set_val(self.data[ofs:])
else:
self.set_val(None)
self.needsupdate=3DTrue
self.Refresh()
self.set_pos(ofs)
self.set_sel(self.highlightstart, self.highlightend)
=20
def OnMakeSelection(self, evt):
if not self.dragging:
return
ofs=3Dself._set_and_move(evt)
if ofs is not None:
self.highlightend=3Dofs+1
self.needsupdate=3DTrue
self.Refresh()
self.set_pos(ofs)
self.set_sel(self.highlightstart, self.highlightend)
def OnEndSelection(self, evt):
self.dragging=3DFalse
ofs=3Dself._set_and_move(evt)
self.set_pos(ofs)
self.set_sel(self.highlightstart, self.highlightend)

def OnRightClick(self, evt):
self.current_ofs=3Dself._set_and_move(evt)
if self.current_ofs is None:
self.set_val(None)
else:
self.set_val(self.data[self.current_ofs:])
self.set_pos(self.current_ofs)
self._bgmenu.Enable(self._apply_menu_id, self._module is not =
None)
self._bgmenu.Enable(self._reload_menu_id, self._module is not =
None)
self.PopupMenu(self._bgmenu, evt.GetPosition())

def OnTemplateLoad(self, _):
dlg=3Dwx.FileDialog(self, 'Select a file to load',
wildcard=3D'*.tmpl',
style=3Dwx.OPEN|wx.FILE_MUST_EXIST)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
result=3D{}
try:
execfile(dlg.GetPath())
except UnicodeError:
common.unicode_execfile(dlg.GetPath())
exist_keys=3D{}
for i,e in enumerate(self._templates):
exist_keys[e.name]=3Di
for d in result['templates']:
data_struct=3DDataStruct('new struct')
data_struct.set(d)
if exist_keys.has_key(data_struct.name):
=
self._templates[exist_keys[data_struct.name]]=3Ddata_struct
else:
self._templates.append(data_struct)
dlg.Destroy()
def OnTemplateSaveAs(self, _):
dlg=3Dwx.FileDialog(self, 'Select a file to save',
wildcard=3D'*.tmpl',
style=3Dwx.SAVE|wx.OVERWRITE_PROMPT)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
r=3D[x.get() for x in self._templates]
common.writeversionindexfile(dlg.GetPath(),
{ 'templates': r }, 1)
dlg.Destroy()
def OnTemplateApply(self, _):
if not self._templates:
# no templates to apply
return
choices=3D[x.name for x in self._templates]
dlg=3Dwx.SingleChoiceDialog(self, 'Select a template to apply:',
'Apply Data Template',
choices)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
try:
res=3Dself._apply_template(dlg.GetStringSelection())
self._display_result(res)
except:
raise
w=3Dwx.MessageDialog(self, 'Apply Template raised an =
exception',
'Apply Template Error',
style=3Dwx.OK|wx.ICON_ERROR)
w.ShowModal()
w.Destroy()
dlg.Destroy()
def OnTemplateEdit(self, _):
dlg=3DTemplateDialog(self)
dlg.set(self._templates)
if dlg.ShowModal()=3D=3Dwx.ID_OK:
self._templates=3Ddlg.get()
dlg.Destroy()

def OnSearch(self, evt):
dlg=3Dwx.TextEntryDialog(self, 'Enter data to search (1 0x23 045 =
...):',
'Search Data')
if dlg.ShowModal()=3D=3Dwx.ID_OK:
l=3Ddlg.GetValue().split(' ')
s=3D''
for e in l:
if e[0:2]=3D=3D'0x':
s+=3Dchr(int(e, 16))
elif e[0]=3D=3D'0':
s+=3Dchr(int(e, 8))
else:
s+=3Dchr(int(e))
i=3Dself.data[self.current_ofs:].find(s)
if i!=3D-1:
self._search_string=3Ds
self.highlightstart=3Di+self.current_ofs
self.highlightend=3Dself.highlightstart+len(s)
self.needsupdate=3DTrue
self.Refresh()
self.set_sel(self.highlightstart, self.highlightend)
else:
self._search_string=3DNone
def OnSearchAgain(self, evt):
if self._search_string is not None:
i=3Dself.data[self.current_ofs:].find(self._search_string)
if i=3D=3D-1:
return
self.highlightstart=3Di+self.current_ofs
=
self.highlightend=3Dself.highlightstart+len(self._search_string)
self.needsupdate=3DTrue
self.Refresh()
self.set_sel(self.highlightstart, self.highlightend)

def OnSize(self, evt):
# uncomment these lines to prevent going wider than is needed
# if self.width>self.widthinchars*self.charwidth:
# self.SetClientSize( (self.widthinchars*self.charwidth, =
self.height) )
if evt is None:
self.width=3D(self.widthinchars+3)*self.charwidth
self.height=3Dself.charheight*20
self.SetClientSize((self.width, self.height))
self.SetCaret(wx.Caret(self, (self.charwidth, =
self.charheight)))
self.GetCaret().Show(True)
else:
self.width,self.height=3Dself.GetClientSizeTuple()
self.needsupdate=3DTrue

def OnGainFocus(self,_):
self.hasfocus=3DTrue
self.needsupdate=3DTrue
self.Refresh()

def OnLoseFocus(self,_):
self.hasfocus=3DFalse
self.needsupdate=3DTrue
self.Refresh()

def highlightrange(self, start, end):
self.needsupdate=3DTrue
self.highlightstart=3Dstart
self.highlightend=3Dend
self.Refresh()
self.set_pos(None)
self.set_sel(self.highlightstart, self.highlightend)
self.set_val(None)

def _ishighlighted(self, pos):
return pos>=3Dself.highlightstart and pos<self.highlightend

def sethighlight(self, foreground, background):
self.highlight=3Dforeground,background

def setnormal(self, foreground, background):
self.normal=3Dforeground,background

def setfont(self, font):
dc=3Dwx.ClientDC(self)
dc.SetFont(font)
self.charwidth, self.charheight=3Ddc.GetTextExtent("M")
self.font=3Dfont
self.updatescrollbars()

def updatescrollbars(self):
# how many lines are we?
lines=3Dlen(self.data)/16
if lines=3D=3D0 or len(self.data)%16:
lines+=3D1
self.datalines=3Dlines
## lines+=3D1 # status line
# fixed width
self.widthinchars=3D8+2+3*16+1+2+16
self.SetScrollbars(self.charwidth, self.charheight, =
self.widthinchars, lines, self.GetViewStart()[0], =
self.GetViewStart()[1])

def _setnormal(self,dc):
dc.SetTextForeground(self.normal[0])
dc.SetTextBackground(self.normal[1])

def _sethighlight(self,dc):
dc.SetTextForeground(self.highlight[0])
dc.SetTextBackground(self.highlight[1]) =20

def _setstatus(self,dc):
dc.SetTextForeground(self.normal[1])
dc.SetTextBackground(self.normal[0])
dc.SetBrush(wx.BLACK_BRUSH)
=20

def OnDraw(self, dc):
xd,yd=3Dself.GetViewStart()
st=3D0 # 0=3Dnormal, 1=3Dhighlight
dc.BeginDrawing()
dc.SetBackgroundMode(wx.SOLID)
dc.SetFont(self.font)
for line in range(yd, min(self.datalines, =
yd+self.height/self.charheight+1)):
# address
self._setnormal(dc)
st=3D0
dc.DrawText("%08X" % (line*16), 0, line*self.charheight)
# bytes
for i in range(16):
pos=3Dline*16+i
if pos>=3Dlen(self.data):
break
hl=3Dself._ishighlighted(pos)
if hl!=3Dst:
if hl:
st=3D1
self._sethighlight(dc)
else:
st=3D0
self._setnormal(dc)
if hl:
space=3D""
if i<15:
if self._ishighlighted(pos+1):
space=3D" "
if i=3D=3D7:
space=3D" "
else:
space=3D""
c=3Dself.data[pos]
dc.DrawText("%02X%s" % (ord(c),space), =
(10+(3*i)+(i>=3D8))*self.charwidth, line*self.charheight)
if not (ord(c)>=3D32 and string.printable.find(c)>=3D0):
c=3D'.'
dc.DrawText(c, (10+(3*16)+2+i)*self.charwidth, =
line*self.charheight)

## if self.hasfocus:
## self._setstatus(dc)
## w,h=3Dself.GetClientSizeTuple()
## =
dc.DrawRectangle(0,h-self.charheight+yd*self.charheight,self.widthinchars=
*self.charwidth,self.charheight)
## dc.DrawText("A test of stuff "+`yd`, 0, =
h-self.charheight+yd*self.charheight)
=20
dc.EndDrawing()

def updatebuffer(self):
if self.buffer is None or \
self.buffer.GetWidth()!=3Dself.width or \
self.buffer.GetHeight()!=3Dself.height:
if self.buffer is not None:
del self.buffer
self.buffer=3Dwx.EmptyBitmap(self.width, self.height)

mdc=3Dwx.MemoryDC()
mdc.SelectObject(self.buffer)
=
mdc.SetBackground(wx.TheBrushList.FindOrCreateBrush(self.GetBackgroundCol=
our(), wx.SOLID))
mdc.Clear()
self.PrepareDC(mdc)
self.OnDraw(mdc)
mdc.SelectObject(wx.NullBitmap)
del mdc

def OnPaint(self, event):
if self.needsupdate:
self.needsupdate=3DFalse
self.updatebuffer()
dc=3Dwx.PaintDC(self)
dc.BeginDrawing()
dc.DrawBitmap(self.buffer, 0, 0, False)
dc.EndDrawing()

def OnScrollWin(self, event):
self.needsupdate=3DTrue
self.Refresh() # clear whole widget
event.Skip() # default event handlers now do scrolling etc

class HexEditorDialog(wx.Dialog):
_pane_widths=3D[-2, -3, -4]
_pos_pane_index=3D0
_sel_pane_index=3D1
_val_pane_index=3D2
def __init__(self, parent, data=3D'', title=3D'BitPim Hex Editor', =
helpd_id=3D-1):
super(HexEditorDialog, self).__init__(parent, -1, title,
size=3D(500, 500),
=
style=3Dwx.DEFAULT_DIALOG_STYLE|\
wx.RESIZE_BORDER)
self._status_bar=3Dwx.StatusBar(self, -1)
self._status_bar.SetFieldsCount(len(self._pane_widths))
self._status_bar.SetStatusWidths(self._pane_widths)
vbs=3Dwx.BoxSizer(wx.VERTICAL)
self._hex_editor=3DHexEditor(self, _set_pos=3Dself.set_pos,
_set_val=3Dself.set_val,
_set_sel=3Dself.set_sel)
self._hex_editor.SetData(data)
self._hex_editor.SetTitle(title)
vbs.Add(self._hex_editor, 1, wx.EXPAND|wx.ALL, 5)
vbs.Add(wx.StaticLine(self), 0, wx.EXPAND|wx.ALL, 5)
ok_btn=3Dwx.Button(self, wx.ID_OK, 'OK')
vbs.Add(ok_btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
vbs.Add(self._status_bar, 0, wx.EXPAND|wx.ALL, 0)
self.SetSizer(vbs)
self.SetAutoLayout(True)
vbs.Fit(self)
def set_pos(self, pos):
"""Display the current buffer offset in the format of
Pos: 0x12=3D18
"""
if pos is None:
s=3D''
else:
s=3D'Pos: 0x%X=3D%d'%(pos, pos)
self._status_bar.SetStatusText(s, self._pos_pane_index)
def set_sel(self, sel_start, sel_end):
if sel_start is None or sel_start=3D=3D-1 or\
sel_end is None or sel_end =3D=3D-1:
s=3D''
else:
sel_len=3Dsel_end-sel_start
sel_end-=3D1
s=3D'Sel: 0x%X=3D%d to 0x%X=3D%d (0x%X=3D%d bytes)'%(
sel_start, sel_start, sel_end, sel_end,
sel_len, sel_len)
self._status_bar.SetStatusText(s, self._sel_pane_index)
def set_val(self, v):
if v:
# char
s=3D'Val: 0x%02X=3D%d'%(ord(v[0]), ord(v[0]))
if len(v)>1:
# short
u_s=3Dstruct.unpack('<H', v[:struct.calcsize('<H')])[0]
s+=3D' 0x%04X=3D%d'%(u_s, u_s)
if len(v)>3:
# int/long
u_i=3Dstruct.unpack('<I', v[:struct.calcsize('<I')])[0]
s+=3D' 0x%08X=3D%d'%(u_i, u_i)
else:
s=3D''
self._status_bar.SetStatusText(s, self._val_pane_index)

def set(self, data):
self._hex_editor.SetData(data)

=20
if __name__=3D=3D'__main__':
import sys

if len(sys.argv)!=3D2:
print 'Usage:',sys.argv[0],'<File Name>'
sys.exit(1)
app=3Dwx.PySimpleApp()
dlg=3DHexEditorDialog(None, file(sys.argv[1], 'rb').read(),
sys.argv[1])
if True:
dlg.ShowModal()
else:
import hotshot
f=3Dhotshot.Profile("hexeprof",1)
f.runcall(dlg.ShowModal)
f.close()
import hotshot.stats
stats=3Dhotshot.stats.load("hexeprof")
stats.strip_dirs()
# stats.sort_stats("cumulative")
stats.sort_stats("time", "calls")
stats.print_stats(30)

dlg.Destroy()
sys.exit(0)

------=_NextPart_000_0009_01C5CC00.B216EB80
Content-Type: application/octet-stream;
name="hexeditor.py.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="hexeditor.py.diff"

Index: hexeditor.py
===================================================================
RCS file: /cvsroot/bitpim/bitpim/hexeditor.py,v
retrieving revision 1.15
diff -u -r1.15 hexeditor.py
--- hexeditor.py 15 Jun 2005 02:52:21 -0000 1.15
+++ hexeditor.py 8 Oct 2005 18:40:22 -0000
@@ -886,7 +886,10 @@
style=wx.OPEN|wx.FILE_MUST_EXIST)
if dlg.ShowModal()==wx.ID_OK:
result={}
- execfile(dlg.GetPath())
+ try:
+ execfile(dlg.GetPath())
+ except UnicodeError:
+ common.unicode_execfile(dlg.GetPath())
exist_keys={}
for i,e in enumerate(self._templates):
exist_keys[e.name]=i

------=_NextPart_000_0009_01C5CC00.B216EB80
Content-Type: text/plain;
name="makedist.py"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="makedist.py"

#!/usr/bin/env python
### BITPIM
###
### Copyright (C) 2003-2005 Roger Binns <***@rogerbinns.com>
### Copyright (C) 2003-2004 Steven Palm <***@n9yty.com>
###
### This program is free software; you can redistribute it and/or modify
### it under the terms of the BitPim license as detailed in the LICENSE =
file.
###
### $Id: makedist.py,v 1.94 2005/07/19 06:39:06 rogerb Exp $


# Runs on Linux, Windows and Mac

"""Builds a binary distribution of BitPim

This code runs on Windows, Linux and Mac, and will create binary =
distributions
suitable for mass use"""

import os
import shutil
import sys
import glob
import re
import version

def rmrf(path):
"""Delete directory tree like rm -rf does"""
entries=3Dos.listdir(path)
for e in entries:
fullname=3Dos.path.join(path,e)
if os.path.isdir(fullname):
rmrf(fullname)
else:
os.remove(fullname)
os.rmdir(path)

def run(*args):
"""Execute the command.

The path is searched"""
print `args`
sl=3Dos.spawnl
if sys.platform!=3D'win32':
sl=3Dos.spawnlp
ret=3Dapply(sl, (os.P_WAIT,args[0])+args)
else:
# win98 was fine with above code, winxp just chokes
# so we call system() instead
str=3D""
for a in args:
if a.find(' ')>=3D0:
str+=3D' "'+a+'"'
else:
str+=3D" "+a
str=3Dstr[1:] # remove first space
# If you ever wanted proof how idiotic windows is, here it is
# if there is a value enclosed in double quotes, it is
# taken as the window title, even if it comes after all
# the switches, so i have to supply one, otherwise it mistakes
# the command to run as the window title
ret=3Dos.system('start /b /wait "%s" %s' % (args[0], str))
print "returned", ret
if ret!=3D0: raise Exception("The command failed")

def sanitycheck():
"Check everything is ok"
print "=3D=3D=3D Sanity check =3D=3D=3D"

print "python version",
if sys.version_info<(2,3):
raise Exception("Should be at least Python 2,3 - this is =
"+sys.version)
print " OK"

print "wxPython version",
import wx
if wx.VERSION[:4]!=3D(2,6,1,0):
raise Exception("Should be wxPython 2.6.1.0. This is =
"+`wx.VERSION`)
print " OK"

print "wxPython is unicode build",
if not wx.USE_UNICODE:
raise Exception("You need a unicode build of wxPython")
print " OK"
=20
print "native.usb",
import native.usb
print " OK"

print "pycrypto version",
expect=3D'2.0.1'
import Crypto
if Crypto.__version__!=3Dexpect:
raise Exception("Should be %s version of pycrypto - you have %s" =
% (expect, Crypto.__version__))
print " OK"

print "paramiko version",
expect=3D'1.4 (oddish)'
import paramiko
if paramiko.__version__!=3Dexpect:
raise Exception("Should be %s version of paramiko - you have %s" =
% (expect, paramiko.__version__))
print " OK"
=20
print "bitfling",
import bitfling
print " OK"

print "pyserial",
import serial
print " OK"

print "apsw",
import apsw
ver=3D"3.2.7-r1"
if apsw.apswversion()!=3Dver:
raise Exception("Should be apsw version %s - you have %s" % =
(ver, apsw.apswversion()))
print " OK"

print "sqlite",
ver=3D"3.2.7"
if apsw.sqlitelibversion()!=3Dver:
raise Exception("Should be sqlite version %s - you have %s" % =
(ver, apsw.sqlitelibversion()))
print " OK"

=20
print "jaro/winkler string matcher",
import native.strings.jarow
print " OK"

# bsddb (Linux only, for evolution)
if sys.platform=3D=3D"linux2":
print "bsddb ",
import bsddb
print " OK"

print "=3D=3D=3D All checks out =3D=3D=3D"
=20

def clean():
"""Remove temporary directories created by various packaging =
tools"""
if os.path.isdir("dist"):
rmrf("dist")
if os.path.isdir("build"):
rmrf("build")
for file in ['setup.cfg']:
if os.path.isfile(file):
os.remove(file)

def resources():
"""Get a list of the resources (images, executables, sounds etc) we =
ship

@rtype: dict
@return: The key for each entry in the dict is a directory name, and =
the value
is a list of files within that directory"""
tbl=3D{}
# list of files
exts=3D[ '*.xy', '*.png', '*.ttf', '*.wav', '*.jpg', '*.css', =
'*.pdc', '*.ids']
if sys.platform=3D=3D'win32':
# on windows we also want the chm help file and the manifest =
needed to get Xp style widgets
exts=3Dexts+['*.chm', '*.manifest']
exts=3Dexts+['helpers/*.exe','helpers/*.dll']
if sys.platform=3D=3D'linux2':
exts=3Dexts+['helpers/*.lbin', '*.htb']
if sys.platform=3D=3D'darwin':
exts=3Dexts+['helpers/*.mbin', '*.htb']
# list of directories to look in
dirs=3D[ os.path.join('.', 'resources'), '.' ]
# don't ship list
dontship=3D["group.png"] # group is not used as is vx4400 =
specific anyway
dontship.append("pvconv.exe") # Qualcomm won't answer if I can ship =
this
for wildcard in exts:
for dir in dirs:
for file in glob.glob(os.path.join(dir, wildcard)):
if os.path.basename(file).lower() in dontship: continue=20
d=3Dos.path.dirname(file)
if not tbl.has_key(d):
tbl[d]=3D[]
tbl[d].append(file)

files=3D[]
for i in tbl.keys():
files.append( (i, tbl[i]) )

return files

def getallencodings():
"Return the list of encodings modules"
# bring in every codec in existence
import encodings
=20
res=3D[]
for f in glob.glob(os.path.join(os.path.dirname(encodings.__file__), =
"*.py")):
v=3D"encodings."+os.path.basename(f)[:-3]
if v.endswith("__init__"): continue
if v not in res:
try:
__import__(v)
res.append(v)
except: # many codecs exist, but fail on import with all =
sorts of random exceptions
pass
return res

def isofficialbuild():
"Work out if this is an official build"
import socket
h=3Dsocket.gethostname().lower()
# not built by rogerb (or stevep/n9yty) are unofficial
return h in ('rh9bitpim.rogerbinns.com', "roger-sqyvr14d3",
"smpbook.n9yty.com", "smpbook.local.", =
"rogerbmac.rogerbinns.com", "rogerbmac.local")

def ensureofficial():
"""If this is not an official build then ensure that version.vendor =
doesn't say it is"""
if not isofficialbuild():
if version.vendor=3D=3D"official":
# it isn't official, so modify file
f=3Dopen("version.py", "rt").read()
newf=3Df.replace('vendor=3D"official"', =
'vendor=3D"unofficial"')
assert newf!=3Df
open("version.py", "wt").write(newf)

def copyresources(dest):
"""Copies the resources to the specified destination directory.

The directory structure is preserved in the copy"""
for dir,files in resources():
if not os.path.exists(os.path.join(dest,dir)):
os.makedirs(os.path.join(dest,dir))
for file in files:
print file
shutil.copy(file, os.path.join(dest, file))

def getsubs():
"""Gets the list of substitutions to be performed on the template =
files

A partial current list is:
- VERSION: The full version number of the product
- OUTFILE: The filename of resulting installer (Windows =
specific)
- NAME: The product name (in lower case)
- RELEASE: The release is an increment if multiple releases are
made of the same version. This corresponds to the =
last
part of the filename for RPM packages

@rtype: dict
"""
# Get version info
import version
=20
verstr=3Dversion.version
if version.testver:
verstr+=3D"-test"+`version.testver`

if not isofficialbuild():
verstr+=3D"-unofficial"

filename=3D"bitpim-"+verstr+"-setup"

if sys.platform=3D=3D'linux2':
# linux needs all the dash bits as underscores
verstr=3Dre.sub("-", "_", verstr)
=20


res=3D{}
res['VERSION']=3Dverstr
res['OUTFILE']=3Dfilename
res['NAME']=3Dversion.name.lower()
res['RELEASE']=3D`version.release`
res['COPYRIGHT']=3Dversion.copyright
res['DQVERSION']=3D".".join([`i` for i in version.dqver])
res['DESCRIPTION']=3Dversion.description
res['COPYRIGHT']=3Dversion.copyright
res['URL']=3Dversion.url
return res

def dosubs(infile, outfile, subs):
"""Performs substitutions on a template file

@param infile: filename to read
@param outfile: filename to write resutl to
@type subs: dict
@param subs: the substitutions to make
"""
stuff=3Dopen(infile, "rt").read()

for k in subs:
stuff=3Dre.sub("%%"+k+"%%", subs[k], stuff)

open(outfile, "w").write(stuff)


def windowsbuild():
"""Do all the steps necessary to make a Windows installer"""
# check libusb
import win32api
try:
win32api.FreeLibrary(win32api.LoadLibrary("libusb0.dll"))
except:
raise Exception("You need libusb0.dll to be available to do a =
build. You only need the dll, not the rest of libusb-win32. (It =
doesn't have to be available on the end user system, but does need to be =
present to do a correct build")
=20
# clean up
clean()
# need setup.cfg with version info in it
v=3Dgetsubs()
# Build python and stuff
coms=3D[f[:-3] for f in glob.glob("com_*.py")]
run( "c:\\python23\python", "p2econfig.py", "py2exe", "-O2", "-i", =
",".join(coms+getallencodings()))
# Rename to correct thing
os.rename("dist\\bp.exe", "dist\\bitpim.exe")
# Remove files I don't want - py2exe did this correctly once
for f in ("libusb0.dll", "w9xpopen.exe"):
ff=3Dos.path.join("dist", f)
if os.path.isfile(ff):
os.remove(ff)

v=3Dgetsubs()
dosubs("bitpim.iss", "bitpim-out.iss", v)
filename=3Dv['OUTFILE']

# Run innosetup
run("c:\\program files\\inno setup 5\\compil32.exe", "/cc", =
"bitpim-out.iss")

# copy to S: drive
if os.path.isdir("s:\\"):
shutil.copyfile("dist\\"+filename+".exe", =
"s:\\bprel\\"+filename+".exe")

def linuxbuild():
"""Do all the steps necessary to make a Linux RPM"""
try:
rmrf("i386")
except:
pass
clean()
os.mkdir("dist")
coms=3D[f[:-3] for f in glob.glob("com_*.py")]
cxfreezedir=3D'/opt/cx_Freeze-3.0.1'
j=3Dos.path.join
run("env", "PYTHONOPTIMIZE=3D2", "PATH=3D%s:%s" % (cxfreezedir, =
os.environ["PATH"]), "FreezePython",=20
"--install-dir=3D"+os.path.abspath("dist"), "--base-name", =
j(cxfreezedir,"bases","Console"),=20
"--init-script", =
j(cxfreezedir,"initscripts","ConsoleSetLibPath.py"), =
"--include-modules",=20
",".join(coms+getallencodings()), "bp.py")
copyresources("dist")
v=3Dgetsubs()
instdir=3D"/usr/lib/%s-%s" % (v['NAME'], v['VERSION'])
run("sh", "-e", "-c", "cd dist ; ../unixpkg/getallwxlibs")
run("sh", "-e", "-c", "cd dist ; ../unixpkg/rpathfixup")
run("sh", "-e", "-c", "cd dist ; strip *.so")
run("sh", "-e", "-c", "cd dist ; tar cvf ../dist.tar *")
clean()
os.mkdir("dist")
for f in glob.glob("unixpkg/*"):
if os.path.isfile(f):
shutil.copy(f, "dist")

dosubs("unixpkg/bitpim.spec", "dist/bitpim.spec", v)
shutil.copy("dist.tar", "dist")
os.remove("dist.tar")

n=3D"%s-%s" % (v['NAME'], v['VERSION'])
try:
rmrf(n)
except:
pass
=20
os.rename("dist", n)
run("tar", "cvfz", n+".tar.gz", n)
rmrf(n)
run("rpmbuild", "-ta", '--define=3D_rpmdir %s' % (os.getcwd(),), =
"--target", "i386-linux", n+".tar.gz")
os.remove(n+".tar.gz")
=20
def macbuild():
"""Do all the steps necessary to make a Mac dimg
=20
Now using the py2app stuff from Bob Ippolito <***@redivi.com>,
the replacement for the crufty `bundlebuilder` stuff previously
used for MacOS X executables. This will be the new standard for
PythonMac bundling.
=20
It can be found for now at:
=20
http://undefined.org/python/#py2app
=20
"""
try:
rmrf("dist")
except:
pass
clean()
os.mkdir("dist")
from distutils.core import setup
import py2app
import string
name =3D "BitPim"
iconfile =3D "bitpim.icns"
v=3Dgetsubs()
data_files=3D[]
includePackages=3D[]
verstr =3D "%s-%s" % (v['NAME'], version.versionstring)

includes=3D[f[:-3] for f in glob.glob("com_*.py")]
=20
plist =3D dict(
CFBundleIconFile =3D iconfile,
CFBundleName =3D name,
CFBundleShortVersionString =3D verstr,
CFBundleGetInfoString =3D verstr,
CFBundleExecutable =3D name,
CFBundleIdentifier =3D 'org.bitpim.bitpim',
)
opts =3D dict(py2app=3Ddict(
compressed=3D1,
iconfile=3Diconfile,
plist=3Dplist,
includes=3Dincludes,
optimize=3D2
))
app =3D [ dict(
script=3D"bp.py",
),]
setup( data_files =3D resources(), options =3D opts, app =3D app, =
script_args =3D ("py2app",) )

os.system("find dist -name '*.so' -print0 | xargs -0 strip -x")

#
if (os.uname()[2] >=3D "7.0.0"):
ret=3Dos.system('hdiutil create -srcfolder dist -volname BitPim =
-nouuid -noanyowners dist/PANTHER-%s.dmg' % verstr)
print "image creation returned", ret
else:
# print "Create disk image with dist folder as the source in =
DiskCopy with name:\n -> JAGUAR-%s.dmg <-." % verstr
ret=3Dos.system('/usr/local/bin/buildDMG.pl -buildDir=3Ddist =
-compressionLevel=3D9 -volName=3DBitPim -dmgName=3DJAGUAR-%s.dmg =
dist/BitPim.app' % verstr)
print "image creation returned", ret

if __name__=3D=3D'__main__':
# do a sanity check first
sanitycheck()
# ensure only official builds are marked as such
ensureofficial()
if sys.platform=3D=3D'win32':
windowsbuild()
elif sys.platform=3D=3D'linux2':
linuxbuild()
elif sys.platform=3D=3D'darwin':
macbuild()
else:
print "Unknown platform", sys.platform

------=_NextPart_000_0009_01C5CC00.B216EB80
Content-Type: application/octet-stream;
name="makedist.py.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="makedist.py.diff"

Index: makedist.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/bitpim/bitpim/makedist.py,v
retrieving revision 1.94
diff -u -r1.94 makedist.py
--- makedist.py 19 Jul 2005 06:39:06 -0000 1.94
+++ makedist.py 8 Oct 2005 18:36:20 -0000
@@ -111,13 +111,13 @@
=20
print "apsw",
import apsw
- ver=3D"3.2.2-r1"
+ ver=3D"3.2.7-r1"
if apsw.apswversion()!=3Dver:
raise Exception("Should be apsw version %s - you have %s" % =
(ver, apsw.apswversion()))
print " OK"
=20
print "sqlite",
- ver=3D"3.2.2"
+ ver=3D"3.2.7"
if apsw.sqlitelibversion()!=3Dver:
raise Exception("Should be sqlite version %s - you have %s" % =
(ver, apsw.sqlitelibversion()))
print " OK"

------=_NextPart_000_0009_01C5CC00.B216EB80
Content-Type: application/octet-stream;
name="common.py.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="common.py.diff"

Index: common.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/bitpim/bitpim/common.py,v
retrieving revision 1.50
diff -u -r1.50 common.py
--- common.py 17 May 2005 08:39:48 -0000 1.50
+++ common.py 8 Oct 2005 18:17:44 -0000
@@ -202,9 +202,28 @@
print formatexception()
raise
=20
+def unicode_execfile(filename, dict1=3D0, dict2=3D0):
+ # this version allows the path portion of the filename to=20
+ # contain non-acsii characters, the filename itself cannot contain
+ # ascii characters, execfile does not work if the filename =
contains
+ # non-ascii characters
+ curdir=3Dos.getcwdu()
+ filepath, file=3Dos.path.split(filename)
+ os.chdir(filepath)
+ if dict1=3D=3D0:
+ execfile(file)
+ elif dict2=3D=3D0:
+ execfile(file, dict1)
+ else:
+ execfile(file, dict1, dict2)
+ os.chdir(curdir)
+
def readversionedindexfile(filename, dict, versionhandlerfunc, =
currentversion):
assert currentversion>0
- execfile(filename, dict, dict)
+ try:
+ execfile(filename, dict, dict)
+ except UnicodeError:
+ unicode_execfile(filename, dict, dict)
if not dict.has_key('FILEVERSION'):
version=3D0
else:

------=_NextPart_000_0009_01C5CC00.B216EB80
Content-Type: text/plain;
name="common.py"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="common.py"

### BITPIM
###
### Copyright (C) 2003-2005 Roger Binns <***@rogerbinns.com>
###
### This program is free software; you can redistribute it and/or modify
### it under the terms of the BitPim license as detailed in the LICENSE =
file.
###
### $Id: common.py,v 1.50 2005/05/17 08:39:48 rogerb Exp $


# Documentation
"""Various classes and functions that are used by GUI and command line =
versions of BitPim"""

# standard modules
import string
import cStringIO
import StringIO
import sys
import traceback
import tempfile
import random
import os

class FeatureNotAvailable(Exception):
"""The device doesn't support the feature"""
def __init__(self, device, message=3D"The device doesn't support =
the feature"):
Exception.__init__(self, "%s: %s" % (device, message))
self.device=3Ddevice
self.message=3Dmessage

class IntegrityCheckFailed(Exception):
def __init__(self, device, message):
Exception.__init__(self, "%s: %s" % (device, message))
self.device=3Ddevice
self.message=3Dmessage

class PhoneBookBusyException(Exception):
"The phonebook is busy on the phone"
pass
=20
class HelperBinaryNotFound(Exception):
def __init__(self, basename, fullname, paths):
Exception.__init__(self, "Helper binary %s not found. It =
should be in one of %s" % (fullname, ", ".join(paths)))
self.basename=3Dbasename
self.fullname=3Dfullname
self.paths=3Dpaths

class CommandExecutionFailed(Exception):
def __init__(self, retcode, args):
Exception.__init__(self, "Command execution failed with code =
%d: %s" % (retcode, " ".join(args)))
self.retcode=3Dretcode
self.args=3Dargs
=20
class ConversionNotSupported(Exception):
def __init__(self, msg):
Exception.__init__(self, msg)
self.msg=3Dmsg

class InSafeModeException(Exception):
def __init__(self):
Exception.__init__(self, "BitPim is in safe mode - this =
operation has been blocked")

# generic comms exception and then various specialisations
class CommsException(Exception):
"""Generic commmunications exception"""
def __init__(self, message, device=3D"<>"):
Exception.__init__(self, "%s: %s" % (device, message))
self.device=3Ddevice
self.message=3Dmessage

class CommsNeedConfiguring(CommsException):
"""The communication settings need to be configured"""
pass

class CommsDeviceNeedsAttention(CommsException):
"""The communication port or device attached to it needs some
manual intervention"""
pass

class CommsDataCorruption(CommsException):
"""There was some form of data corruption"""
pass

class CommsTimeout(CommsException):
"""Timeout while reading or writing the commport"""
pass

class CommsOpenFailure(CommsException):
"""Failed to open the communications port/device"""
pass

class CommsWrongPort(CommsException):
"""The wrong port has been selected, typically the modem port on an =
LG composite device"""
pass

class AutoPortsFailure(CommsException):
"""Failed to auto detect a useful port"""
def __init__(self, portstried):
self.device=3D"auto"
self.message=3D"Failed to auto-detect the port to use. "
if portstried is not None and len(portstried):
self.message+=3D"I tried "+", ".join(portstried)
else:
self.message+=3D"I couldn't detect any candidate ports"
CommsException.__init__(self, self.message, self.device)

def datatohexstring(data):
"""Returns a pretty printed hexdump of the data

@rtype: string"""
res=3DcStringIO.StringIO()
lchar=3D""
lhex=3D"00000000 "
for count in range(0, len(data)):
b=3Dord(data[count])
lhex=3Dlhex+"%02x " % (b,)
if b>=3D32 and string.printable.find(chr(b))>=3D0:
lchar=3Dlchar+chr(b)
else:
lchar=3Dlchar+'.'

if (count+1)%16=3D=3D0:
res.write(lhex+" "+lchar+"\n")
lhex=3D"%08x " % (count+1,)
lchar=3D""
if len(data):
while (count+1)%16!=3D0:
count=3Dcount+1
lhex=3Dlhex+" "
res.write(lhex+" "+lchar+"\n")
return res.getvalue()

def hexify(data):
"Turns binary data into a hex string (like the output of MD5/SHA =
hexdigest)"
return "".join(["%02x" % (ord(x),) for x in data])

def prettyprintdict(dictionary, indent=3D0):
"""Returns a pretty printed version of the dictionary

The elements are sorted into alphabetical order, and printed
one per line. Dictionaries within the values are also pretty
printed suitably indented.

@rtype: string"""

res=3DcStringIO.StringIO()

# the indent string
istr=3D" "

# opening brace
res.write("%s{\n" % (istr*indent,))
indent+=3D1

# sort the keys
keys=3Ddictionary.keys()
keys.sort()

# print each key
for k in keys:
v=3Ddictionary[k]
# is it a dict
if isinstance(v, dict):
res.write("%s%s:\n%s\n" % (istr*indent, `k`, =
prettyprintdict(v, indent+1)))
else:
# is it a list of dicts?
if isinstance(v, list):
dicts=3D0
for item in v:
if isinstance(item, dict):
dicts+=3D1
if dicts and dicts=3D=3Dlen(v):
res.write("%s%s:\n%s[\n" % =
(istr*indent,`k`,istr*(indent+1)))
for item in v:
res.write(prettyprintdict(item, indent+2))
res.write("%s],\n" % (istr*(indent+1)))
continue
res.write("%s%s: %s,\n" % (istr*indent, `k`, `v`))

# closing brace
indent-=3D1
if indent>0:
comma=3D","
else:
comma=3D""
res.write("%s}%s\n" % (istr*indent,comma))

return res.getvalue()

=20
class exceptionwrap:
"""A debugging assist class that helps in tracking down functions =
returning exceptions"""
def __init__(self, callable):
self.callable=3Dcallable
=20
def __call__(self, *args, **kwargs):
try:

return self.callable(*args, **kwargs)
except:
print "in exception wrapped call", `self.callable`
print formatexception()
raise

def unicode_execfile(filename, dict1=3D0, dict2=3D0):
# this version allows the path portion of the filename to=20
# contain non-acsii characters, the filename itself cannot contain
# ascii characters, execfile does not work if the filename contains
# non-ascii characters
curdir=3Dos.getcwdu()
filepath, file=3Dos.path.split(filename)
os.chdir(filepath)
if dict1=3D=3D0:
execfile(file)
elif dict2=3D=3D0:
execfile(file, dict1)
else:
execfile(file, dict1, dict2)
os.chdir(curdir)

def readversionedindexfile(filename, dict, versionhandlerfunc, =
currentversion):
assert currentversion>0
try:
execfile(filename, dict, dict)
except UnicodeError:
unicode_execfile(filename, dict, dict)
if not dict.has_key('FILEVERSION'):
version=3D0
else:
version=3Ddict['FILEVERSION']
del dict['FILEVERSION']
if version<currentversion:
versionhandlerfunc(dict, version)

def writeversionindexfile(filename, dict, currentversion):
assert currentversion>0
f=3Dopen(filename, "w")
for key in dict:
v=3Ddict[key]
if isinstance(v, type({})):
f.write("result['%s']=3D%s\n" % (key, =
prettyprintdict(dict[key])))
else:
f.write("result['%s']=3D%s\n" % (key, `v`))
f.write("FILEVERSION=3D%d\n" % (currentversion,))
f.close()

def formatexceptioneh(*excinfo):
print formatexception(excinfo)

def formatexception(excinfo=3DNone, lastframes=3D8):
"""Pretty print exception, including local variable information.

See Python Cookbook, recipe 14.4.

@param excinfo: tuple of information returned from sys.exc_info =
when
the exception occurred. If you don't supply this then
information about the current exception being handled
is used
@param lastframes: local variables are shown for these number of
frames
@return: A pretty printed string
"""
if excinfo is None:
excinfo=3Dsys.exc_info()

s=3DStringIO.StringIO()
traceback.print_exception(*excinfo, **{'file': s})
tb=3Dexcinfo[2]

while True:
if not tb.tb_next:
break
tb=3Dtb.tb_next
stack=3D[]
f=3Dtb.tb_frame
while f:
stack.append(f)
f=3Df.f_back
stack.reverse()
if len(stack)>lastframes:
stack=3Dstack[-lastframes:]
print >>s, "\nVariables by last %d frames, innermost last" % =
(lastframes,)
for frame in stack:
print >>s, ""
print >>s, "Frame %s in %s at line %s" % =
(frame.f_code.co_name,
=
frame.f_code.co_filename,
frame.f_lineno)
for key,value in frame.f_locals.items():
# filter out modules
if type(value)=3D=3Dtype(sys):
continue
print >>s,"%15s =3D " % (key,),
try:
if type(value)=3D=3Dtype({}):
kk=3Dvalue.keys()
kk.sort()
print >>s, "Keys",kk
print >>s, "%15s " % ("",) ,
print >>s,`value`[:80]
except:
print >>s,"(Exception occurred printing value)"
return s.getvalue()
=20
def gettempfilename(extension):
"Returns a filename to be used for a temporary file"
# safest Python 2.3 method
x=3Dtempfile.NamedTemporaryFile(suffix=3D"."+extension)
n=3Dx.name
x.close()
del x
return n

def getfullname(name):
"""Returns the object corresponding to name.
Imports will be done as necessary to resolve
every part of the name"""
mods=3Dname.split('.')
dict=3D{}
for i in range(len(mods)):
# import everything
try:
exec "import %s" % (".".join(mods[:i])) in dict, dict
except:
pass
# ok, we should have the name now
return eval(name, dict, dict)

def list_union(*lists):
res=3D[]
for l in lists:
for item in l:
if item not in res:
res.append(item)
return res

def getkv(dict, key, updates=3DNone):
"Gets a key and value from a dict, returning as a dict potentially =
applying updates"
d=3D{key: dict[key].copy()}=20
if updates:=20
d[key].update(updates)
return d=20

# some obfuscation
# obfuscate pwd
_magic=3D[ord(x) for x in "IamAhaPp12&s]"]

# the oldies are the best
def obfus_encode(str):
res=3D[]
for i in range(len(str)):
res.append(ord(str[i])^_magic[i%len(_magic)])
return "".join(["%02x" % (x,) for x in res])

def obfus_decode(str):
res=3D[]
for i in range(0, len(str), 2):
res.append(int(str[i:i+2], 16))
x=3D""
for i in range(len(res)):
x+=3Dchr(res[i]^_magic[i%len(_magic)])
return x

# unicode byte order markers to codecs
# this really should be part of the standard library

# we try to import the encoding first. that has the side
# effect of ensuring that the freeze tools pick up the
# right bits of code as well
import codecs

_boms=3D[]
# 64 bit=20
try:
import encodings.utf_64
_boms.append( (codecs.BOM64_BE, "utf_64") )
_boms.append( (codecs.BOM64_LE, "utf_64") )
except: pass

# 32 bit
try:
import encodings.utf_32
_boms.append( (codecs.BOM_UTF32, "utf_32") )
_boms.append( (codecs.BOM_UTF32_BE, "utf_32") )
_boms.append( (codecs.BOM_UTF32_LE, "utf_32") )
except: pass

# 16 bit
try:
import encodings.utf_16
_boms.append( (codecs.BOM_UTF16, "utf_16") )
_boms.append( (codecs.BOM_UTF16_BE, "utf_16") )
_boms.append( (codecs.BOM_UTF16_LE, "utf_16") )
except: pass

# 8 bit
try:
import encodings.utf_8
_boms.append( (codecs.BOM_UTF8, "utf_8") )
except: pass

# NB: the 32 bit and 64 bit versions have the BOM constants defined in =
Py 2.3
# but no corresponding encodings module. They are here for =
completeness.
# The order of above also matters since the first ones have longer
# boms than the latter ones, and we need to be unambiguous

_maxbomlen=3Dmax([len(bom) for bom,codec in _boms])

def opentextfile(name):
"""This function detects unicode byte order markers and if present
uses the codecs module instead to open the file instead with
appropriate unicode decoding, else returns the file using standard
open function"""
f=3Dopen(name, "rb")
start=3Df.read(_maxbomlen)
for bom,codec in _boms:
if start.startswith(bom):
f.close()
# some codecs don't do readline, so we have to vector via =
stringio
# many postings also claim that the BOM is returned as =
the first
# character but that hasn't been the case in my testing
return StringIO.StringIO(codecs.open(name, "r", =
codec).read())
f.close()
return open(name, "rtU")


# don't you just love i18n

# the following function is actually defined in guihelper and
# inserted into this module. the intention is to ensure this
# module doesn't have to import wx. The guihelper version
# checks if wx is in unicode mode

#def strorunicode(s):
# if isinstance(s, unicode): return s
# return str(s)

def forceascii(s):
if s is None: return s
try:
return str(s)
except UnicodeEncodeError:
return s.encode("ascii", 'replace')

# The CRC and escaping mechanisms are the same as used in PPP, HDLC and
# various other standards.

pppterminator=3D"\x7e"

def pppescape(data):
return data.replace("\x7d", "\x7d\x5d") \
.replace("\x7e", "\x7d\x5e")

def pppunescape(d):
if d.find("\x7d")<0: return d
res=3Dlist(d)
try:
start=3D0
while True:
p=3Dres.index("\x7d", start)
res[p:p+2]=3Dchr(ord(res[p+1])^0x20)
start=3Dp+1
except ValueError:
return "".join(res)

# See http://www.repairfaq.org/filipg/LINK/F_crc_v35.html for more info
# on CRC
_crctable=3D(
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, # =
0 - 7
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, # =
8 - 15
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, # =
16 - 23
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, # =
24 - 31
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, # =
32 - 39
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, # =
40 - 47
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, # =
48 - 55
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, # =
56 - 63
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, # =
64 - 71
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, # =
72 - 79
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, # =
80 - 87
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, # =
88 - 95
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, # =
96 - 103
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, # =
104 - 111
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, # =
112 - 119
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, # =
120 - 127
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, # =
128 - 135
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, # =
136 - 143
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, # =
144 - 151
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, # =
152 - 159
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, # =
160 - 167
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, # =
168 - 175
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, # =
176 - 183
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, # =
184 - 191
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, # =
192 - 199
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, # =
200 - 207
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, # =
208 - 215
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, # =
216 - 223
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, # =
224 - 231
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, # =
232 - 239
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, # =
240 - 247
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78, # =
248 - 255
)

def crc(data, initial=3D0xffff):
"CRC calculation - returns 16 bit integer"
res=3Dinitial
for byte in data:
curres=3Dres
res=3Dres>>8 # zero extended
val=3D(ord(byte)^curres) & 0xff
val=3D_crctable[val]
res=3Dres^val

res=3D(~res)&0xffff
return res

def crcs(data, initial=3D0xffff):
"CRC calculation - returns 2 byte string LSB"
r=3Dcrc(data, initial)
return "%c%c" % ( r& 0xff, (r>>8)&0xff)



###
### Pathname processing (independent of host OS)
###

def basename(name):
if name.rfind('\\')>=3D0 or name.rfind('/')>=3D0:
pos=3Dmax(name.rfind('\\'), name.rfind('/'))
name=3Dname[pos+1:]
return name

def stripext(name):
if name.rfind('.')>=3D0:
name=3Dname[:name.rfind('.')]
return name

def getext(name):
if name.rfind('.')>=3D0:
return name[name.rfind('.')+1:]
return ''

#------------------------------------------------------------------------=
-------
# number <-> string conversion routines

def LSBUint16(v):
if len(v)<2:
return None
return ord(v[0])+(ord(v[1])<<8)

def LSBUint32(v):
if len(v)<4:
return None
return ord(v[0])+(ord(v[1])<<8)+(ord(v[2])<<16)+(ord(v[3])<<24)
=20
def MSBUint16(v):
if len(v)<2:
return None
return ord(v[1])+(ord(v[0])<<8)

def MSBUint32(v):
if len(v)<4:
return None
return ord(v[3])+(ord(v[2])<<8)+(ord(v[1])<<16)+(ord(v[0])<<24)

def LSBstr16(v):
return chr(v&0xff)+chr((v>>8)&0xff)

def LSBstr32(v):
return =
chr(v&0xff)+chr((v>>8)&0xff)+chr((v>>16)&0xff)+chr((v>>24)&0xff)

def MSBstr16(v):
return chr((v>>8)&0xff)+chr(v&0xff)

def MSBstr32(v):
return =
chr((v>>24)&0xff)+chr((v>>16)&0xff)+chr((v>>8)&0xff)+chr(v&0xff)


###
### Binary handling
###

nibbles=3D("0000", "0001", "0010", "0011", "0100", "0101", "0110", =
"0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111")

def tobinary(v):
return nibbles[v>>4]+nibbles[v&0x0f]

def frombinary(v):
res=3D0
for i in v:
res*=3D2
res+=3Dbool(i=3D=3D"1")
return res

# This could be done more efficiently through clever combinations of
# masks and shifts but it is harder to write and debug (I tried :-)
# and isn't any more effective on the short strings we work with
def decodecharacterbits(bytes, bitsperchar, charconv=3Dchr, =
terminator=3DNone):
"""Decodes the characters out of a string of bytes where each
character takes a fixed number of bits (eg 7)

@param bytes: atring containing the raw bytes
@param bitsperchar: number of bits making up each character
@param charconv: the function used to convert the integer value
into a character
@param terminator: if this character is seen then it and the =
remaining bits are ignored"""
bits=3D"".join([tobinary(ord(c)) for c in bytes])
value=3D[]
while len(bits):
c=3Dcharconv(frombinary(bits[:bitsperchar]))
if c=3D=3Dterminator:
break
value.append(c)
bits=3Dbits[bitsperchar:]
return "".join(value)
=20
###
### Cache information against a file
###

def statinfo(filename):
"""Returns a simplified version of os.stat results that can be used =
to tell if a file
has changed. The normal structure returned also has things like =
last access time
which should not be used to tell if a file has changed."""
try:
s=3Dos.stat(filename)
return (s.st_mode, s.st_ino, s.st_dev, s.st_uid, s.st_gid, =
s.st_size, s.st_mtime,
s.st_ctime)
except:
return None

class FileCache:

def __init__(self, lowwater=3D100, hiwater=3D140):
self.items=3D{}
self.hiwater=3Dhiwater
self.lowwater=3Dlowwater

def get(self, filename):
v=3Dself.items.get(filename, None)
if v is None: return None
si,value=3Dv
# check freshness
if si=3D=3Dstatinfo(filename):
return value
return None

def set(self, filename, value):
# we deliberately return value make this easy to use in return =
statement
if len(self.items)>=3Dself.hiwater:
while len(self.items)>self.lowwater:
del self.items[random.choice(self.items.keys())]
# yes there is a race condition with statinfo changing after =
program
# has calculated value but before calling this function
self.items[filename]=3Dstatinfo(filename),value
return value
=20

------=_NextPart_000_0009_01C5CC00.B216EB80--

Loading...