Mercurial > core / 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 |
1 ;;; lisp/net/codec/tlv.lisp --- TypeLengthValue wire codec 6 (in-package :net/codec/tlv) 9 ((type :initform 0 :initarg :type :type octet :accessor tlv-type) 10 (length :initform 0 :initarg :length :type (unsigned-byte 16) :accessor tlv-length) 11 (value :initform (make-array 0 :element-type 'octet) :initarg :value :type octet-vector :accessor tlv-value)) 12 (:documentation "TypeLengthValue object. 14 TLVs are a common packet format in communication protocols. Objects of 15 this type are assumed to have a 1 byte TYPE, a 2 byte LENGTH, and a 16 VALUE which is an OCTET-VECTOR of length LENGTH.")) 18 (defmethod serialize ((obj tlv) (format (eql :bytes)) &key stream) 19 (declare (ignore format)) 20 (with-slots (type length value) obj 21 (let ((buf (make-array (+ 3 length) :element-type 'octet))) 22 (setf (aref buf 0) type) 23 (setf (subseq buf 1 2) (integer-to-octets length 16)) 25 (setf (subseq buf 4) value)) 27 (write buf :stream stream) 30 (defun make-tlv (type length &optional (value #.(make-array 0 :element-type 'octet))) 31 (make-instance 'tlv :type type :length length :value value)) 33 (defmethod serialize ((obj tlv) (format (eql :string)) &key stream (external-format :default)) 34 (declare (ignore format stream)) 35 (sb-ext:octets-to-string (serialize obj :bytes) :external-format external-format)) 37 (defmethod deserialize ((from simple-array) (format (eql :tlv)) &key) 38 (declare (ignore format)) 39 (let ((type (aref from 0)) 40 (length (octets-to-integer (subseq from 1 3)))) 42 (make-tlv type length) 43 (let ((value (subseq from 3 (+ 3 length)))) 44 (funcall #'make-tlv type length value))))) 46 (defmethod deserialize ((from stream) (format (eql :tlv)) &key) 47 (let ((type (read-byte from)) 48 (l (make-array 2 :element-type 'octet :adjustable t))) 49 (read-sequence l from) 50 (let ((length (octets-to-integer (coerce l 'octet-vector) 2))) 52 (make-tlv type length nil) 53 (let ((value (make-array length :element-type 'octet))) 54 (read-sequence value from) 55 (make-tlv type length value)))))) 57 (defmethod serde ((from tlv) (to simple-array)) 58 (with-slots (type length value) from 59 (setf (aref to 0) type) 60 (replace to (integer-to-octets length 16) :start1 1 :start2 2) 62 (replace to value :start1 3 :end1 (+ 3 length))) 68 (serialize (make-instance 'tlv) :bytes)