changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/lib/net/codec/tlv.lisp

changeset 256: c5f24d22497a
parent: e41c5c04d7f6
child: 099ee89ff63f
author: Richard Westhaver <ellis@rwest.io>
date: Mon, 01 Apr 2024 20:19:11 -0400
permissions: -rw-r--r--
description: serde/tlv
105
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
1
 ;;; lisp/net/codec/tlv.lisp --- TypeLengthValue wire codec
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
2
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
3
 ;;
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
4
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
5
 ;;; Code:
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
6
 (in-package :net/codec/tlv)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
7
 
255
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
8
 (defclass tlv ()
256
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
9
   ((type :initform 0 :initarg :type :type octet :accessor tlv-type)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
10
    (length :initform 0 :initarg :length :type (unsigned-byte 16) :accessor tlv-length)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
11
    (value :initform (make-array 0 :element-type 'octet) :initarg :value :type octet-vector :accessor tlv-value))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
12
   (:documentation "TypeLengthValue object.
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
13
 
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
14
 TLVs are a common packet format in communication protocols. Objects of
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
15
 this type are assumed to have a 1 byte TYPE, a 2 byte LENGTH, and a
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
16
 VALUE which is an OCTET-VECTOR of length LENGTH."))
255
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
17
 
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
18
 (defmethod serialize ((obj tlv) (format (eql :bytes)) &key stream)
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
19
   (declare (ignore format))
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
20
   (with-slots (type length value) obj
256
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
21
     (let ((buf (make-array (+ 3 length) :element-type 'octet)))
255
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
22
       (setf (aref buf 0) type)
256
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
23
       (setf (subseq buf 1 2) (integer-to-octets length 16))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
24
       (unless (= 0 length)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
25
         (setf (subseq buf 4) value))
255
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
26
       (if stream
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
27
           (write buf :stream stream)
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
28
           buf))))
Richard Westhaver <ellis@rwest.io>
parents: 240
diff changeset
29
 
256
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
30
 (defun make-tlv (type length &optional (value #.(make-array 0 :element-type 'octet)))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
31
   (make-instance 'tlv :type type :length length :value value))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
32
 
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
33
 (defmethod serialize ((obj tlv) (format (eql :string)) &key stream (external-format :default))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
34
   (declare (ignore format stream))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
35
   (sb-ext:octets-to-string (serialize obj :bytes) :external-format external-format))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
36
 
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
37
 (defmethod deserialize ((from simple-array) (format (eql :tlv)) &key)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
38
   (declare (ignore format))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
39
   (let ((type (aref from 0))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
40
         (length (octets-to-integer (subseq from 1 3))))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
41
     (if (= 0 length)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
42
         (make-tlv type length)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
43
         (let ((value (subseq from 3 (+ 3 length))))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
44
           (funcall #'make-tlv type length value)))))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
45
 
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
46
 (defmethod deserialize ((from stream) (format (eql :tlv)) &key)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
47
   (let ((type (read-byte from))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
48
         (l (make-array 2 :element-type 'octet :adjustable t)))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
49
     (read-sequence l from)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
50
     (let ((length (octets-to-integer (coerce l 'octet-vector) 2)))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
51
       (if (= 0 length)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
52
           (make-tlv type length nil)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
53
           (let ((value (make-array length :element-type 'octet)))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
54
             (read-sequence value from)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
55
             (make-tlv type length value))))))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
56
 
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
57
 (defmethod serde ((from tlv) (to simple-array))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
58
   (with-slots (type length value) from
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
59
     (setf (aref to 0) type)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
60
     (replace to (integer-to-octets length 16) :start1 1 :start2 2)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
61
     (unless (= 0 length)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
62
       (replace to value :start1 3 :end1 (+ 3 length)))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
63
     to))
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
64
 
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
65
 #+nil
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
66
 (describe
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
67
  (deserialize
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
68
   (serialize (make-instance 'tlv) :bytes)
c5f24d22497a serde/tlv
Richard Westhaver <ellis@rwest.io>
parents: 255
diff changeset
69
   :tlv))