mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2025-01-08 10:29:37 +00:00
Added transaction support to write & delete files.
* if error occurs, disk image returned to state it was before the call
This commit is contained in:
parent
ea92e91865
commit
7151739ad3
@ -377,6 +377,14 @@ class DiskImageBase(object):
|
|||||||
|
|
||||||
# file writing methods
|
# file writing methods
|
||||||
|
|
||||||
|
def begin_transaction(self):
|
||||||
|
state = self.bytes[:], self.style[:]
|
||||||
|
return state
|
||||||
|
|
||||||
|
def rollback_transaction(self, state):
|
||||||
|
self.bytes[:], self.style[:] = state
|
||||||
|
return
|
||||||
|
|
||||||
def write_file(self, filename, filetype, data):
|
def write_file(self, filename, filetype, data):
|
||||||
"""Write data to a file on disk
|
"""Write data to a file on disk
|
||||||
|
|
||||||
@ -384,18 +392,25 @@ class DiskImageBase(object):
|
|||||||
not enough space on disk or a free entry is not available in the
|
not enough space on disk or a free entry is not available in the
|
||||||
catalog.
|
catalog.
|
||||||
"""
|
"""
|
||||||
directory = self.directory_class(self.bytes_per_sector)
|
state = self.begin_transaction()
|
||||||
self.get_directory(directory)
|
try:
|
||||||
dirent = directory.add_dirent(filename, filetype)
|
directory = self.directory_class(self.bytes_per_sector)
|
||||||
data = to_numpy(data)
|
self.get_directory(directory)
|
||||||
sector_list = self.sector_list_class(self.bytes_per_sector, self.payload_bytes_per_sector, data, self.writeable_sector_class)
|
dirent = directory.add_dirent(filename, filetype)
|
||||||
vtoc_segments = self.get_vtoc_segments()
|
data = to_numpy(data)
|
||||||
vtoc = self.vtoc_class(self.bytes_per_sector, vtoc_segments)
|
sector_list = self.sector_list_class(self.bytes_per_sector, self.payload_bytes_per_sector, data, self.writeable_sector_class)
|
||||||
directory.save_dirent(dirent, vtoc, sector_list)
|
vtoc_segments = self.get_vtoc_segments()
|
||||||
self.write_sector_list(sector_list)
|
vtoc = self.vtoc_class(self.bytes_per_sector, vtoc_segments)
|
||||||
self.write_sector_list(vtoc)
|
directory.save_dirent(dirent, vtoc, sector_list)
|
||||||
self.write_sector_list(directory)
|
self.write_sector_list(sector_list)
|
||||||
self.get_metadata()
|
self.write_sector_list(vtoc)
|
||||||
|
self.write_sector_list(directory)
|
||||||
|
self.get_metadata()
|
||||||
|
except AtrError:
|
||||||
|
self.rollback_transaction(state)
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
self.get_metadata()
|
||||||
|
|
||||||
def write_sector_list(self, sector_list):
|
def write_sector_list(self, sector_list):
|
||||||
for sector in sector_list:
|
for sector in sector_list:
|
||||||
@ -404,17 +419,24 @@ class DiskImageBase(object):
|
|||||||
self.bytes[pos:pos + size] = sector.data
|
self.bytes[pos:pos + size] = sector.data
|
||||||
|
|
||||||
def delete_file(self, filename):
|
def delete_file(self, filename):
|
||||||
directory = self.directory_class(self.bytes_per_sector)
|
state = self.begin_transaction()
|
||||||
self.get_directory(directory)
|
try:
|
||||||
dirent = directory.find_dirent(filename)
|
directory = self.directory_class(self.bytes_per_sector)
|
||||||
sector_list = dirent.get_sector_list(self)
|
self.get_directory(directory)
|
||||||
vtoc_segments = self.get_vtoc_segments()
|
dirent = directory.find_dirent(filename)
|
||||||
vtoc = self.vtoc_class(self.bytes_per_sector, vtoc_segments)
|
sector_list = dirent.get_sector_list(self)
|
||||||
directory.remove_dirent(dirent, vtoc, sector_list)
|
vtoc_segments = self.get_vtoc_segments()
|
||||||
self.write_sector_list(sector_list)
|
vtoc = self.vtoc_class(self.bytes_per_sector, vtoc_segments)
|
||||||
self.write_sector_list(vtoc)
|
directory.remove_dirent(dirent, vtoc, sector_list)
|
||||||
self.write_sector_list(directory)
|
self.write_sector_list(sector_list)
|
||||||
self.get_metadata()
|
self.write_sector_list(vtoc)
|
||||||
|
self.write_sector_list(directory)
|
||||||
|
self.get_metadata()
|
||||||
|
except AtrError:
|
||||||
|
self.rollback_transaction(state)
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
self.get_metadata()
|
||||||
|
|
||||||
|
|
||||||
class WriteableSector(object):
|
class WriteableSector(object):
|
||||||
|
Loading…
Reference in New Issue
Block a user