neater and passing tests

This commit is contained in:
Elliot Nunn 2018-10-07 23:47:23 +08:00
parent 58bc5f6430
commit 854e8b987c
3 changed files with 83 additions and 24 deletions

View File

@ -1,14 +1,66 @@
class AbstractFolder(dict):
def paths(self):
import collections
_CASE = list(range(256)) # cheating, fix this!
def _to_lower(orig):
return bytes(_CASE[x] for x in orig)
class AbstractFolder(collections.MutableMapping):
def __init__(self, from_dict=()):
self._prefdict = {} # lowercase to preferred
self._maindict = {} # lowercase to contents
self.update(from_dict)
def __setitem__(self, key, value):
try:
key = key.encode('mac_roman')
except AttributeError:
pass
if len(key) > 31:
raise ValueError('Max filename length = 31')
lower = _to_lower(key)
self._prefdict[lower] = key
self._maindict[lower] = value
def __getitem__(self, key):
try:
key = key.encode('mac_roman')
except AttributeError:
pass
lower = _to_lower(key)
return self._maindict[lower]
def __delitem__(self, key):
try:
value = value.encode('mac_roman')
except AttributeError:
pass
lower = _to_lower(key)
del self._maindict[lower]
del self._prefdict[lower]
def __iter__(self):
return iter(self._prefdict.values())
def __len__(self):
return len(self._maindict)
def iter_paths(self):
for name, child in self.items():
print(name, child)
yield ((name,), child)
try:
childs_children = child.paths()
childs_children = child.iter_paths()
except AttributeError:
pass
else:
for each_path, each_child in childs_children:
yield (name,) + each_path, each_child
def __str__(self):
return 'Folder valence=%d' % len(self)

41
main.py
View File

@ -101,27 +101,27 @@ class Volume(_directory.AbstractFolder):
super().__init__()
self.bootblocks = bytes(1024) # optional; for booting HFS volumes
self.drCrDate = 0 # date and time of volume creation
self.drLsMod = 0 # date and time of last modification
self.drAtrb = 1<<8 # volume attributes (hwlock, swlock, CLEANUNMOUNT, badblocks)
self.drVN = b'Untitled' # volume name Pascal string
self.drVolBkUp = 0 # date and time of last backup
self.drVSeqNum = 0 # volume backup sequence number
self.drFndrInfo = bytes(32) # information used by the Finder
self.crdate = 0 # date and time of volume creation
self.lsmod = 0 # date and time of last modification
self.name = b'Untitled'
def read(self, from_volume):
self._dirtree = {}
self.bootblocks = from_volume[:1024]
drSigWord, self.drCrDate, self.drLsMod, self.drAtrb, drNmFls, \
drSigWord, drCrDate, drLsMod, drAtrb, drNmFls, \
drVBMSt, drAllocPtr, drNmAlBlks, drAlBlkSiz, drClpSiz, drAlBlSt, \
drNxtCNID, drFreeBks, self.drVN, self.drVolBkUp, self.drVSeqNum, \
drNxtCNID, drFreeBks, drVN, drVolBkUp, drVSeqNum, \
drWrCnt, drXTClpSiz, drCTClpSiz, drNmRtDirs, drFilCnt, drDirCnt, \
self.drFndrInfo, drVCSize, drVBMCSize, drCtlCSize, \
drFndrInfo, drVCSize, drVBMCSize, drCtlCSize, \
drXTFlSize, drXTExtRec, \
drCTFlSize, drCTExtRec, \
= struct.unpack_from('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHL12sL12s', from_volume, 1024)
self.crdate = drCrDate
self.lsmod = drLsMod
self.name = drVN
block2offset = lambda block: 512*drAlBlSt + drAlBlkSiz*block
extent2bytes = lambda firstblk, blkcnt: from_volume[block2offset(firstblk):block2offset(firstblk+blkcnt)]
extrec2bytes = lambda extrec: b''.join(extent2bytes(a, b) for (a, b) in _btree.unpack_extent_record(extrec))
@ -248,16 +248,16 @@ class Volume(_directory.AbstractFolder):
# write all the files in the volume
topwrap = _TempWrapper(self)
topwrap.path = (self.drVN,)
topwrap.path = (self.name,)
topwrap.cnid = 2
godwrap = _TempWrapper(None)
godwrap.cnid = 1
path2wrap = {(): godwrap, (self.drVN,): topwrap}
path2wrap = {(): godwrap, (self.name,): topwrap}
drNxtCNID = 16
for path, obj in self.paths():
path = (self.drVN,) + path
for path, obj in self.iter_paths():
path = (self.name,) + path
wrap = _TempWrapper(obj)
path2wrap[path] = wrap
wrap.path = path
@ -363,13 +363,20 @@ class Volume(_directory.AbstractFolder):
drFreeBks = drNmAlBlks - len(blkaccum)
drWrCnt = 0 # ????volume write count
drVCSize = drVBMCSize = drCtlCSize = 0
drAtrb = 1<<8 # volume attributes (hwlock, swlock, CLEANUNMOUNT, badblocks)
drVN = self.name
drVolBkUp = 0 # date and time of last backup
drVSeqNum = 0 # volume backup sequence number
drFndrInfo = bytes(32) # information used by the Finder
drCrDate = self.crdate
drLsMod = self.lsmod
vib = struct.pack('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHLHHxxxxxxxxLHHxxxxxxxx',
drSigWord, self.drCrDate, self.drLsMod, self.drAtrb, drNmFls,
drSigWord, drCrDate, drLsMod, drAtrb, drNmFls,
drVBMSt, drAllocPtr, drNmAlBlks, drAlBlkSiz, drClpSiz, drAlBlSt,
drNxtCNID, drFreeBks, self.drVN, self.drVolBkUp, self.drVSeqNum,
drNxtCNID, drFreeBks, drVN, drVolBkUp, drVSeqNum,
drWrCnt, drXTClpSiz, drCTClpSiz, drNmRtDirs, drFilCnt, drDirCnt,
self.drFndrInfo, drVCSize, drVBMCSize, drCtlCSize,
drFndrInfo, drVCSize, drVBMCSize, drCtlCSize,
drXTFlSize, drXTExtRec_Start, drXTExtRec_Cnt,
drCTFlSize, drCTExtRec_Start, drCTExtRec_Cnt,
)

View File

@ -19,7 +19,7 @@ def test_roundtrip():
def test_macos_mount():
h = Volume()
h.drVN = b'ElmoTest'
h.name = b'ElmoTest'
hf = File()
hf.data = b'12345' * 10
for i in reversed(range(100)):