NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

dumbdbm.py (4009B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\dumbdbm.py
      2 import os as _os
      3 import __builtin__
      4 import UserDict
      5 _open = __builtin__.open
      6 _BLOCKSIZE = 512
      7 error = IOError
      8 
      9 class _Database(UserDict.DictMixin):
     10     _os = _os
     11     _open = _open
     12 
     13     def __init__(self, filebasename, mode):
     14         self._mode = mode
     15         self._dirfile = filebasename + _os.extsep + 'dir'
     16         self._datfile = filebasename + _os.extsep + 'dat'
     17         self._bakfile = filebasename + _os.extsep + 'bak'
     18         self._index = None
     19         try:
     20             f = _open(self._datfile, 'r')
     21         except IOError:
     22             f = _open(self._datfile, 'w')
     23             self._chmod(self._datfile)
     24 
     25         f.close()
     26         self._update()
     27 
     28     def _update(self):
     29         self._index = {}
     30         try:
     31             f = _open(self._dirfile)
     32         except IOError:
     33             pass
     34         else:
     35             for line in f:
     36                 line = line.rstrip()
     37                 key, pos_and_siz_pair = eval(line)
     38                 self._index[key] = pos_and_siz_pair
     39 
     40             f.close()
     41 
     42     def _commit(self):
     43         if self._index is None:
     44             return
     45         try:
     46             self._os.unlink(self._bakfile)
     47         except self._os.error:
     48             pass
     49 
     50         try:
     51             self._os.rename(self._dirfile, self._bakfile)
     52         except self._os.error:
     53             pass
     54 
     55         f = self._open(self._dirfile, 'w')
     56         self._chmod(self._dirfile)
     57         for key, pos_and_siz_pair in self._index.iteritems():
     58             f.write('%r, %r\n' % (key, pos_and_siz_pair))
     59 
     60         f.close()
     61 
     62     sync = _commit
     63 
     64     def __getitem__(self, key):
     65         pos, siz = self._index[key]
     66         f = _open(self._datfile, 'rb')
     67         f.seek(pos)
     68         dat = f.read(siz)
     69         f.close()
     70         return dat
     71 
     72     def _addval(self, val):
     73         f = _open(self._datfile, 'rb+')
     74         f.seek(0, 2)
     75         pos = int(f.tell())
     76         npos = (pos + _BLOCKSIZE - 1) // _BLOCKSIZE * _BLOCKSIZE
     77         f.write('\x00' * (npos - pos))
     78         pos = npos
     79         f.write(val)
     80         f.close()
     81         return (pos, len(val))
     82 
     83     def _setval(self, pos, val):
     84         f = _open(self._datfile, 'rb+')
     85         f.seek(pos)
     86         f.write(val)
     87         f.close()
     88         return (pos, len(val))
     89 
     90     def _addkey(self, key, pos_and_siz_pair):
     91         self._index[key] = pos_and_siz_pair
     92         f = _open(self._dirfile, 'a')
     93         self._chmod(self._dirfile)
     94         f.write('%r, %r\n' % (key, pos_and_siz_pair))
     95         f.close()
     96 
     97     def __setitem__(self, key, val):
     98         if not type(key) == type('') == type(val):
     99             raise TypeError, 'keys and values must be strings'
    100         if key not in self._index:
    101             self._addkey(key, self._addval(val))
    102         else:
    103             pos, siz = self._index[key]
    104             oldblocks = (siz + _BLOCKSIZE - 1) // _BLOCKSIZE
    105             newblocks = (len(val) + _BLOCKSIZE - 1) // _BLOCKSIZE
    106             if newblocks <= oldblocks:
    107                 self._index[key] = self._setval(pos, val)
    108             else:
    109                 self._index[key] = self._addval(val)
    110 
    111     def __delitem__(self, key):
    112         del self._index[key]
    113         self._commit()
    114 
    115     def keys(self):
    116         return self._index.keys()
    117 
    118     def has_key(self, key):
    119         return key in self._index
    120 
    121     def __contains__(self, key):
    122         return key in self._index
    123 
    124     def iterkeys(self):
    125         return self._index.iterkeys()
    126 
    127     __iter__ = iterkeys
    128 
    129     def __len__(self):
    130         return len(self._index)
    131 
    132     def close(self):
    133         self._commit()
    134         self._index = self._datfile = self._dirfile = self._bakfile = None
    135 
    136     __del__ = close
    137 
    138     def _chmod(self, file):
    139         if hasattr(self._os, 'chmod'):
    140             self._os.chmod(file, self._mode)
    141 
    142 
    143 def open(file, flag = None, mode = 438):
    144     try:
    145         um = _os.umask(0)
    146         _os.umask(um)
    147     except AttributeError:
    148         pass
    149     else:
    150         mode = mode & ~um
    151 
    152     return _Database(file, mode)