mirror of
https://github.com/brouhaha/sosar.git
synced 2024-06-11 19:29:29 +00:00
Use memoryview for blocks and other disk structures. More work on mkfs subcommand.
This commit is contained in:
parent
fa13855396
commit
1e41af7b87
102
sosdisk.py
102
sosdisk.py
|
@ -238,8 +238,8 @@ class SOSVolumeDirectoryHeader(SOSDirectoryEntry):
|
||||||
assert self.storage_type == StorageType.volume_directory_header
|
assert self.storage_type == StorageType.volume_directory_header
|
||||||
assert self.version == 0
|
assert self.version == 0
|
||||||
assert self.min_version == 0
|
assert self.min_version == 0
|
||||||
assert self.entry_length == 0x27
|
assert self.entry_length == 39 # XXX compare to SOSDirectory entry_length instead
|
||||||
assert self.entries_per_block == 0x0d
|
assert self.entries_per_block == 13 # XXX compare to SOSDirectory entries_per_block instead
|
||||||
assert self.total_blocks == disk.block_count
|
assert self.total_blocks == disk.block_count
|
||||||
self.creation = u32_to_sos_timestamp(creation_b)
|
self.creation = u32_to_sos_timestamp(creation_b)
|
||||||
|
|
||||||
|
@ -310,43 +310,83 @@ class SOSFileEntry(SOSDirectoryEntry):
|
||||||
|
|
||||||
|
|
||||||
class SOSDirectoryBlock:
|
class SOSDirectoryBlock:
|
||||||
def __init__(self, disk, block_num, first_dir_block = False):
|
def __init__(self,
|
||||||
|
disk,
|
||||||
|
directory, # the directory containing this block
|
||||||
|
block_num,
|
||||||
|
first_dir_block = False,
|
||||||
|
new = False,
|
||||||
|
directory_name = None, # if new
|
||||||
|
prev_block = None): # if new
|
||||||
self.disk = disk
|
self.disk = disk
|
||||||
data = disk.get_blocks(block_num)
|
self.directory = directory
|
||||||
|
self.entries = []
|
||||||
|
self.entry_count = (self.disk.block_size - 4) // self.directory.entry_length
|
||||||
|
if new:
|
||||||
|
self.__create_new(block_num, first_dir_block)
|
||||||
|
else:
|
||||||
|
self.__read_from_image(block_num, first_dir_block)
|
||||||
|
|
||||||
|
def __read_from_image(self, block_num, first_dir_block = False):
|
||||||
|
data = self.disk.get_blocks(block_num)
|
||||||
self.prev_block, self.next_block = struct.unpack('<HH', data[0:4])
|
self.prev_block, self.next_block = struct.unpack('<HH', data[0:4])
|
||||||
#print('prev: %d, next: %d' % (self.prev_block, self.next_block))
|
#print('prev: %d, next: %d' % (self.prev_block, self.next_block))
|
||||||
self.entries = []
|
for i in range(self.entry_count):
|
||||||
entry_length = 39
|
offset = 4 + self.directory.entry_length * i
|
||||||
entry_count = 13
|
entry_data = memoryview(data[offset: offset+self.directory.entry_length])
|
||||||
for i in range(entry_count):
|
|
||||||
offset = 4 + entry_length * i
|
|
||||||
entry_data = data[offset: offset+entry_length]
|
|
||||||
if first_dir_block and i == 0:
|
if first_dir_block and i == 0:
|
||||||
if block_num == 2:
|
if block_num == 2:
|
||||||
self.entries.append(SOSVolumeDirectoryHeader(disk, entry_data))
|
self.entries.append(SOSVolumeDirectoryHeader(self.disk, entry_data))
|
||||||
else:
|
else:
|
||||||
self.entries.append(SOSSubdirectoryHeader(disk, entry_data))
|
self.entries.append(SOSSubdirectoryHeader(self.disk, entry_data))
|
||||||
else:
|
else:
|
||||||
self.entries.append(SOSFileEntry(disk, entry_data))
|
self.entries.append(SOSFileEntry(self.disk, entry_data))
|
||||||
|
|
||||||
|
def __create_new(self, block_num, first_dir_block = False):
|
||||||
|
self.prev_block = prev_block,
|
||||||
|
self.next_block = 0 # will be updated later if needed
|
||||||
|
data = struct.pack('<HH', self.prev_block, self.next_block) + bytearray(disk.block_size - 4)
|
||||||
|
if block_num == 2:
|
||||||
|
self.entries.append(SOSVolumeDirectoryHeader(disk, new = True, directory_name = directory_name))
|
||||||
|
else:
|
||||||
|
self.entries.append(SOSSubdirectoryHeader(disk, new = True, directory_name = directory_name))
|
||||||
|
|
||||||
|
|
||||||
class SOSDirectory:
|
class SOSDirectory:
|
||||||
def __init__(self, disk, first_block = 0, new = False, block_count = 1):
|
def __init__(self,
|
||||||
|
disk,
|
||||||
|
first_block = None,
|
||||||
|
new = False,
|
||||||
|
block_count = 1, # if new
|
||||||
|
directory_name = None): # if new
|
||||||
self.disk = disk
|
self.disk = disk
|
||||||
self.growable = first_block != 2
|
self.growable = first_block != 2
|
||||||
|
self.entry_length = 39
|
||||||
if new:
|
if new:
|
||||||
self.__create_new()
|
self.__create_new(first_block, block_count)
|
||||||
else:
|
else:
|
||||||
|
# block_count not used
|
||||||
self.__read_from_image(first_block)
|
self.__read_from_image(first_block)
|
||||||
|
|
||||||
def __read_from_image(self, first_block):
|
def __read_from_image(self, first_block):
|
||||||
self.directory_blocks = [SOSDirectoryBlock(self.disk, first_block, first_dir_block = True)]
|
self.directory_blocks = [SOSDirectoryBlock(self.disk,
|
||||||
|
self,
|
||||||
|
first_block,
|
||||||
|
first_dir_block = True)]
|
||||||
while self.directory_blocks[-1].next_block != 0:
|
while self.directory_blocks[-1].next_block != 0:
|
||||||
self.directory_blocks.append(SOSDirectoryBlock(self.disk, self.directory_blocks[-1].next_block))
|
self.directory_blocks.append(SOSDirectoryBlock(self.disk,
|
||||||
|
self,
|
||||||
|
self.directory_blocks[-1].next_block))
|
||||||
self.header = self.directory_blocks[0].entries[0]
|
self.header = self.directory_blocks[0].entries[0]
|
||||||
|
|
||||||
def __create_new(self, first_block, block_count):
|
def __create_new(self, first_block = None, block_count = 1):
|
||||||
pass
|
prev_block_num = 0
|
||||||
|
for i in range(block_count):
|
||||||
|
if first_block is None:
|
||||||
|
block_num = disk.alloc_block()
|
||||||
|
else:
|
||||||
|
block_num = first_block + i
|
||||||
|
|
||||||
|
|
||||||
def print(self, prefix,
|
def print(self, prefix,
|
||||||
recursive = False,
|
recursive = False,
|
||||||
|
@ -371,12 +411,13 @@ class SOSDisk:
|
||||||
def __init__(self, f,
|
def __init__(self, f,
|
||||||
fmt = 'po',
|
fmt = 'po',
|
||||||
new = False,
|
new = False,
|
||||||
size = None):
|
volume_block_count = 280, # only for creating new
|
||||||
|
volume_directory_block_count = 4): # only for creating new
|
||||||
self.image_file = f
|
self.image_file = f
|
||||||
self.image_file_fmt = fmt
|
self.image_file_fmt = fmt
|
||||||
self.block_size = 512
|
self.block_size = 512
|
||||||
if new:
|
if new:
|
||||||
self.__create_new(size)
|
self.__create_new(volume_block_count, volume_directory_block_count)
|
||||||
else:
|
else:
|
||||||
self.__read_image_file()
|
self.__read_image_file()
|
||||||
|
|
||||||
|
@ -395,12 +436,18 @@ class SOSDisk:
|
||||||
self.data = reinterleave(self.data, interleave_tables[self.image_file_fmt], interleave_tables['po'])
|
self.data = reinterleave(self.data, interleave_tables[self.image_file_fmt], interleave_tables['po'])
|
||||||
self.mark_used(0, 2) # boot blocks
|
self.mark_used(0, 2) # boot blocks
|
||||||
self.volume_directory = SOSDirectory(self, 2, new = False)
|
self.volume_directory = SOSDirectory(self, 2, new = False)
|
||||||
bitmap_block_count = (self.volume_directory.header.total_blocks + 1) // (self.block_size * 8)
|
self.bitmap_block_count = (self.volume_directory.header.total_blocks + 1) // (self.block_size * 8)
|
||||||
self.mark_used(self.volume_directory.header.bitmap_pointer, bitmap_block_count)
|
self.bitmap_start_block = self.volume_directory.header.bitmap_pointer
|
||||||
|
self.mark_used(self.volume_directory.header.bitmap_pointer, self.bitmap_block_count)
|
||||||
|
|
||||||
def __create_new(size):
|
def __create_new(volume_block_count = 280, volume_directory_block_count = 4):
|
||||||
self.data = bytearray(size * self.block_size)
|
self.data = bytearray(size * self.block_size)
|
||||||
self.volume_directory = SOSDirectory(self, 2, new = True)
|
self.mark_used(0, 2) # boot blocks
|
||||||
|
|
||||||
|
self.bitmap_block_count = (volume_block_count + 1) // (self.block_size * 8)
|
||||||
|
self.bitmap_start_block = 2 + volume_directory_block_count
|
||||||
|
self.mark_used(self.bitmap_start_block, self.bitmap_block_count) # allocation bitmap
|
||||||
|
self.volume_directory = SOSDirectory(self, 2, new = True, block_count = volume_directory_block_count)
|
||||||
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
@ -420,7 +467,10 @@ class SOSDisk:
|
||||||
self.mark_used(first_block, count)
|
self.mark_used(first_block, count)
|
||||||
offset = first_block * 512
|
offset = first_block * 512
|
||||||
length = count * 512
|
length = count * 512
|
||||||
return self.data[offset:offset+length]
|
return memoryview(self.data[offset:offset+length])
|
||||||
|
|
||||||
|
def alloc_block(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def print_directory(self,
|
def print_directory(self,
|
||||||
recursive = False,
|
recursive = False,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user