mirror of
https://github.com/elliotnunn/machfs.git
synced 2025-02-19 11:31:05 +00:00
neater and passing tests
This commit is contained in:
parent
58bc5f6430
commit
854e8b987c
64
directory.py
64
directory.py
@ -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
41
main.py
@ -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,
|
||||
)
|
||||
|
@ -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)):
|
||||
|
Loading…
x
Reference in New Issue
Block a user