M src/bare.lisp => src/bare.lisp +11 -1
@@ 142,7 142,17 @@ Set this dynamically in the function calling the DATA defbinary.")
(unsigned-byte 8)
(*data-length*))))
-
(defbinary void
()
(value nil :type null))
+
+(defun read-optional-type (type stream)
+ (when (read-byte stream)
+ (read-binary type stream)))
+
+(defun write-optional-type (object stream)
+ (when (plusp (slot-value object 'value))
+ (write-byte 1 stream)
+ (write-binary object stream))
+ (when (zerop (slot-value object 'value))
+ (write-byte 0 stream)))
M src/package.lisp => src/package.lisp +2 -1
@@ 20,5 20,6 @@
:data
:data-fixed
:void
-
+ :read-optional-type
+ :write-optional-type
:value))
M tests/bare-tests.lisp => tests/bare-tests.lisp +25 -3
@@ 147,21 147,43 @@
:result (ok (string= "こんにちは、世界!"))
:bytes 28))
-(deftest read-data
+(deftest data-test
(test-binary-type data
:stream (buf #(#x03 #x13 #x37 #x42))
:result (ok #(19 55 66))
:bytes 4))
-(deftest read-data-fixed
+(deftest data-fixed-test
(let ((*data-length* 3))
(test-binary-type data-fixed
:stream (buf #(#x13 #x37 #x42))
:result (ok (equalp #(19 55 66)))
:bytes 3)))
-(deftest read-void
+(deftest void-test
(test-binary-type void
:stream (buf #(#xff))
:result (ok (null))
:bytes 0))
+
+(deftest optional-type-test
+ (testing "reading and writing optional type when not set"
+ (with-input-from-sequence
+ (in
+ (with-output-to-sequence (out)
+ (write-optional-type
+ (read-binary 'u8 (buf #()))
+ out)))
+ (multiple-value-bind (object) (read-optional-type 'u8 in)
+ (with-slots (value) object
+ (ok (equalp value 0))))))
+ (testing "reading and writing optional type when set"
+ (with-input-from-sequence
+ (in
+ (with-output-to-sequence (out)
+ (write-optional-type
+ (read-binary 'u8 (buf #(#x70)))
+ out)))
+ (multiple-value-bind (object) (read-optional-type 'u8 in)
+ (with-slots (value) object
+ (ok (equalp value 112)))))))