image.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. # greaseweazle/image/image.py
  2. #
  3. # Written & released by Keir Fraser <keir.xen@gmail.com>
  4. #
  5. # This is free and unencumbered software released into the public domain.
  6. # See the file COPYING for more details, or visit <http://unlicense.org>.
  7. import os
  8. from greaseweazle import error
  9. class Image:
  10. read_only = False
  11. ## Context manager for image objects created using .to_file()
  12. def __enter__(self):
  13. self.file = open(self.filename, "wb")
  14. return self
  15. def __exit__(self, type, value, tb):
  16. try:
  17. if type is None:
  18. # No error: Normal writeout.
  19. self.file.write(self.get_image())
  20. finally:
  21. # Always close the file.
  22. self.file.close()
  23. if type is not None:
  24. # An error occurred: We remove the target file.
  25. os.remove(self.filename)
  26. ## Default .to_file() constructor
  27. @classmethod
  28. def to_file(cls, name, fmt=None):
  29. error.check(not cls.read_only,
  30. "%s: Cannot create %s image files" % (name, cls.__name__))
  31. obj = cls()
  32. obj.filename = name
  33. obj.fmt = fmt
  34. return obj
  35. # Maximum non-empty cylinder on each head, or -1 if no cylinders exist.
  36. # Returns a list of integers, indexed by head.
  37. def max_cylinder(self):
  38. r = list()
  39. for h in range(2):
  40. for c in range(100, -2, -1):
  41. if c < 0 or self.get_track(c,h) is not None:
  42. r.append(c)
  43. break
  44. return r
  45. ## Above methods and class variables can be overridden by subclasses.
  46. ## Additionally, subclasses must provide following public interfaces:
  47. ## Read support:
  48. # def from_file(cls, name)
  49. # def get_track(self, cyl, side)
  50. ## Write support (if not cls.read_only):
  51. # def emit_track(self, cyl, side, track)
  52. ## Plus either:
  53. # def get_image(self)
  54. ## Or:
  55. # __enter__ / __exit__
  56. # Local variables:
  57. # python-indent: 4
  58. # End: