pyringfs.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import os
  4. import sys
  5. from sharedlibrary import GenericLibrary
  6. from ctypes import *
  7. # forward declaration
  8. class StructRingFSFlashPartition(Structure):
  9. pass
  10. op_sector_erase_t = CFUNCTYPE(c_int, POINTER(StructRingFSFlashPartition), c_int)
  11. op_program_t = CFUNCTYPE(c_ssize_t, POINTER(StructRingFSFlashPartition), c_int, c_void_p, c_size_t)
  12. op_read_t = CFUNCTYPE(c_ssize_t, POINTER(StructRingFSFlashPartition), c_int, c_void_p, c_size_t)
  13. StructRingFSFlashPartition._fields_ = [
  14. ('sector_size', c_int),
  15. ('sector_offset', c_int),
  16. ('sector_count', c_int),
  17. ('sector_erase', op_sector_erase_t),
  18. ('program', op_program_t),
  19. ('read', op_read_t),
  20. ]
  21. class StructRingFSLoc(Structure):
  22. _fields_ = [
  23. ('sector', c_int),
  24. ('slot', c_int),
  25. ]
  26. class StructRingFS(Structure):
  27. _fields_ = [
  28. ('flash', POINTER(StructRingFSFlashPartition)),
  29. ('version', c_uint32),
  30. ('object_size', c_int),
  31. ('slots_per_sector', c_int),
  32. ('read', StructRingFSLoc),
  33. ('write', StructRingFSLoc),
  34. ('cursor', StructRingFSLoc),
  35. ]
  36. class libringfs(GenericLibrary):
  37. dllname = './ringfs.so'
  38. functions = [
  39. ['ringfs_init', [POINTER(StructRingFS), POINTER(StructRingFSFlashPartition), c_uint32, c_int], c_int],
  40. ['ringfs_format', [POINTER(StructRingFS)], c_int],
  41. ['ringfs_scan', [POINTER(StructRingFS)], c_int],
  42. ['ringfs_capacity', [POINTER(StructRingFS)], c_int],
  43. ['ringfs_count_estimate', [POINTER(StructRingFS)], c_int],
  44. ['ringfs_count_exact', [POINTER(StructRingFS)], c_int],
  45. ['ringfs_append', [POINTER(StructRingFS), c_void_p], c_int],
  46. ['ringfs_fetch', [POINTER(StructRingFS), c_void_p], c_int],
  47. ['ringfs_discard', [POINTER(StructRingFS)], c_int],
  48. ['ringfs_rewind', [POINTER(StructRingFS)], c_int],
  49. ['ringfs_dump', [c_void_p, POINTER(StructRingFS)], None],
  50. ]
  51. class RingFSFlashPartition(object):
  52. def __init__(self, sector_size, sector_offset, sector_count, sector_erase, program, read):
  53. def op_sector_erase(flash, address):
  54. sector_erase(flash, address)
  55. return 0
  56. def op_program(flash, address, data, size):
  57. program(flash, address, string_at(data, size))
  58. return size
  59. def op_read(flash, address, buf, size):
  60. data = read(flash, address, size)
  61. memmove(buf, data, size)
  62. return size
  63. self.struct = StructRingFSFlashPartition(sector_size, sector_offset, sector_count,
  64. op_sector_erase_t(op_sector_erase),
  65. op_program_t(op_program),
  66. op_read_t(op_read))
  67. class RingFS(object):
  68. def __init__(self, flash, version, object_size):
  69. self.libringfs = libringfs()
  70. self.ringfs = StructRingFS()
  71. self.flash = flash.struct
  72. self.libringfs.ringfs_init(byref(self.ringfs), byref(self.flash), version, object_size)
  73. self.object_size = object_size
  74. def format(self):
  75. self.libringfs.ringfs_format(byref(self.ringfs))
  76. def scan(self):
  77. return self.libringfs.ringfs_scan(byref(self.ringfs))
  78. def capacity(self):
  79. return self.libringfs.ringfs_capacity(byref(self.ringfs))
  80. def count_estimate(self):
  81. return self.libringfs.ringfs_count_estimate(byref(self.ringfs))
  82. def count_exact(self):
  83. return self.libringfs.ringfs_count_exact(byref(self.ringfs))
  84. def append(self, obj):
  85. self.libringfs.ringfs_append(byref(self.ringfs), obj)
  86. def fetch(self):
  87. obj = create_string_buffer(self.object_size)
  88. self.libringfs.ringfs_append(byref(self.ringfs), obj)
  89. return obj.raw
  90. def discard(self):
  91. self.libringfs.ringfs_discard(byref(self.ringfs))
  92. def rewind(self):
  93. self.libringfs.ringfs_rewind(byref(self.ringfs))
  94. def dump(self):
  95. import ctypes
  96. ctypes.pythonapi.PyFile_AsFile.argtypes= [ ctypes.py_object ]
  97. ctypes.pythonapi.PyFile_AsFile.restype= ctypes.c_void_p
  98. cstdout = ctypes.pythonapi.PyFile_AsFile(sys.stdout)
  99. self.libringfs.ringfs_dump(cstdout, byref(self.ringfs))
  100. __all__ = [
  101. 'StructRingFSFlashPartition',
  102. 'RingFS',
  103. ]