test-translator.lisp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. (defpackage :test-translator
  2. (:use :cl :hurd-common :mach
  3. :hurd :hurd-translator
  4. :hurd-tree-translator))
  5. (in-package :test-translator)
  6. (defconstant +file+ (first ext:*args*))
  7. (defun %create-data-array (size contents)
  8. (make-array size
  9. :initial-contents contents
  10. :adjustable t
  11. :fill-pointer t
  12. :element-type '(unsigned-byte 8)))
  13. (defclass test-translator (tree-translator)
  14. ((file-stat :initarg :file-stat
  15. :initform nil
  16. :accessor file-stat)
  17. (dir-stat :initarg :dir-stat
  18. :initform nil
  19. :accessor dir-stat)))
  20. (defclass test-entry (entry)
  21. ((contents :initarg :data
  22. :initform (%create-data-array 0 nil)
  23. :accessor data)))
  24. (define-callback read-file test-translator
  25. (node user start amount stream)
  26. (when (has-access-p node user :read)
  27. (let* ((size (stat-get (stat node) 'st-size))
  28. (size-res (- size start)))
  29. (unless (plusp size-res)
  30. (return-from read-file t))
  31. (let* ((total (min size-res amount))
  32. (end (+ start total)))
  33. (write-sequence (subseq (data node) start end)
  34. stream)
  35. t))))
  36. (defun %read-sequence (stream amount)
  37. (let ((arr (make-array amount
  38. :element-type '(unsigned-byte 8))))
  39. (read-sequence arr stream)
  40. arr))
  41. (define-callback write-file test-translator
  42. (node user offset stream amount)
  43. (unless (has-access-p node user :write)
  44. (return-from write-file nil))
  45. (when (is-dir-p (stat node))
  46. (return-from write-file :is-a-directory))
  47. (let* ((size (stat-get (stat node) 'st-size))
  48. (arr (%read-sequence stream amount))
  49. (final-size (max (+ amount offset) size)))
  50. (unless (= final-size size)
  51. (adjust-array (data node)
  52. final-size
  53. :fill-pointer t))
  54. (replace (data node) arr :start1 offset)
  55. ; Update stat size.
  56. (setf (stat-get (stat node) 'st-size) final-size)
  57. t))
  58. (define-callback file-change-size test-translator
  59. (node user new-size)
  60. (when (is-dir-p (stat node))
  61. (return-from file-change-size :is-a-directory))
  62. (when (has-access-p node user :write)
  63. (adjust-array (data node) new-size :fill-pointer t)
  64. (setf (stat-get (stat node) 'st-size) new-size)
  65. t))
  66. (define-callback create-file test-translator
  67. (node user filename mode)
  68. (unless (has-access-p node user :write)
  69. (return-from create-file nil))
  70. (let ((entry (make-instance 'test-entry
  71. :stat (make-stat (stat node)
  72. :mode mode
  73. :size 0)
  74. :parent node)))
  75. (add-entry node entry filename)
  76. entry))
  77. (define-callback create-anonymous-file test-translator
  78. (node user mode)
  79. (when (can-modify-dir-p node user)
  80. (make-instance 'test-entry
  81. :stat (make-stat (stat node)
  82. :mode mode)
  83. :parent node)))
  84. (defun %read-file-data (str)
  85. (%create-data-array (length str)
  86. (loop for char across str
  87. collect (char-code char))))
  88. (defun %fill-node (translator ls node)
  89. (let ((type (first ls))
  90. (name (second ls))
  91. (args (rest (rest ls))))
  92. (case type
  93. (:dir
  94. (let ((dir (make-instance 'dir-entry
  95. :stat (make-stat (dir-stat translator))
  96. :parent node)))
  97. (add-entry node dir name)
  98. (loop for item in args
  99. do (%fill-node translator item dir))))
  100. (:file
  101. (let* ((data (first args))
  102. (file (make-instance 'test-entry
  103. :stat (make-stat
  104. (file-stat translator)
  105. :size (length data))
  106. :parent node
  107. :data (%read-file-data data))))
  108. (add-entry node file name)))
  109. (:link
  110. (let ((target (first args))
  111. (new (make-instance 'entry
  112. :stat (make-stat
  113. (file-stat translator)
  114. :type :lnk)
  115. :parent node)))
  116. (setf (link new) target)
  117. (add-entry node new name))))))
  118. (define-callback fill-root-node test-translator
  119. ((node dir-entry))
  120. (setf (file-stat translator)
  121. (make-stat (stat node)
  122. :mode (make-mode :perms '((:owner :read)
  123. (:group :read)))
  124. :type :reg)
  125. (dir-stat translator)
  126. (make-stat (stat node)
  127. :mode (make-mode :perms '((:owner :read :exec)
  128. (:group :read :exec)))
  129. :type :dir))
  130. (%fill-node translator (with-open-file (s +file+) (read s)) node))
  131. (defun main ()
  132. (let ((translator
  133. (make-instance 'test-translator
  134. :name "test-translator"
  135. :version (list 1 2 3))))
  136. (run-translator translator)))
  137. (main)