M src/bare.lisp => src/bare.lisp +63 -9
@@ 149,6 149,7 @@ Set this dynamically in the function calling the DATA defbinary.")
;;; Aggregate types
+
(defun read-optional-type (type stream)
(when (read-byte stream)
(read-binary type stream)))
@@ 160,24 161,23 @@ Set this dynamically in the function calling the DATA defbinary.")
(write-byte 1 stream)
(write-binary object stream))))
+
(defun read-array (type stream)
- (let ((size (read-binary 'uint stream))
+ (let ((size (slot-value
+ (read-binary 'uint stream)
+ 'value))
res)
- (with-slots (value) size
- (dotimes (i value)
- (push (read-binary type stream) res)))
+ (dotimes (i size)
+ (push (read-binary type stream) res))
(nreverse res)))
(defun write-array (objects stream)
(let ((size (length objects)))
- (write-binary (read-binary
- 'uint
- (flex:make-in-memory-input-stream
- (vector size)))
- stream)
+ (write-binary (make-uint :value size) stream)
(dotimes (i size)
(write-binary (nth i objects) stream))))
+
(defun read-array-fixed (type length stream)
(let (res)
(dotimes (i length)
@@ 187,3 187,57 @@ Set this dynamically in the function calling the DATA defbinary.")
(defun write-array-fixed (objects stream)
(dolist (object objects)
(write-binary object stream)))
+
+
+(defparameter *constructors*
+ #.(let ((ht (make-hash-table)))
+ (loop for (key . value) in
+ '((uint . make-uint)
+ (u8 . make-u8)
+ (u16 . make-u16)
+ (u32 . make-u32)
+ (u64 . make-u64)
+
+ (int . make-int)
+ (i8 . make-i8)
+ (i16 . make-i16)
+ (i32 . make-i32)
+ (i64 . make-i64)
+
+ (f32 . make-f32)
+ (f64 . make-f64)
+
+ (bool . make-bool)
+ (enum . make-enum)
+ (str . make-str)
+ (data . make-data)
+ (data-fixed . make-data-fixed)
+ (void . make-void))
+ do (setf (gethash key ht) value))
+ ht))
+
+(defun read-map (key-type obj-type stream)
+ (let* ((size (slot-value
+ (read-binary 'uint stream)
+ 'value))
+ (res (make-hash-table :size size :test 'equalp)))
+ (dotimes (i size)
+ (let ((key (slot-value
+ (read-binary key-type stream)
+ 'value))
+ (object (slot-value
+ (read-binary obj-type stream)
+ 'value)))
+ (setf (gethash key res) object)))
+ res))
+
+(defun write-map (key-type obj-type hashmap stream)
+ (write-binary (make-uint :value (hash-table-count hashmap)) stream)
+ (maphash (lambda (k v)
+ (write-binary (funcall
+ (gethash key-type *constructors*)
+ :value k) stream)
+ (write-binary (funcall
+ (gethash obj-type *constructors*)
+ :value v) stream))
+ hashmap))
M src/package.lisp => src/package.lisp +2 -0
@@ 26,4 26,6 @@
:write-array
:read-array-fixed
:write-array-fixed
+ :read-map
+ :write-map
:value))
M tests/bare-tests.lisp => tests/bare-tests.lisp +17 -0
@@ 224,3 224,20 @@
(ok (= value 51)))
(with-slots (value) (fourth objects)
(ok (= value 68)))))))
+
+(deftest map-test
+ (testing "reading and writing maps"
+ (with-input-from-sequence
+ (in
+ (with-output-to-sequence (out)
+ (write-map 'u8 'u8
+ (read-map 'u8 'u8 (buf #(#x03
+ #x01 #x11
+ #x02 #x22
+ #x03 #x33)))
+ out)))
+ (let ((objects (read-map 'u8 'u8 in)))
+ (ok (= 3 (hash-table-count objects)))
+ (ok (= (gethash 1 objects) #x11))
+ (ok (= (gethash 2 objects) #x22))
+ (ok (= (gethash 3 objects) #x33))))))