You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

37 lines
1.6 KiB

(in-package :sxcl)
(defun octets-to-lowercase-hex (buf)
"Formats BUF, a vector of octets, as a lowercase hex string and returns it."
(declare (type (vector (unsigned-byte 8)) buf))
(format nil "~(~{~2,'0X~}~)" (coerce buf 'list)))
(defun sha1-octets (buf)
"Returns the SHA1 of BUF, a vector of octets, in lowercase hex."
(octets-to-lowercase-hex (coerce (sha1:sha1-digest buf) '(vector (unsigned-byte 8)))))
(defun sha1-hex (str)
"Returns the SHA1 of STR, a string, in lowercase hex."
(sha1-octets (babel:string-to-octets str)))
(defun child-elements (node)
"Returns the child elements (excluding text nodes) of the CXML DOM node NODE."
(remove-if-not #'dom:element-p (dom:child-nodes node)))
(defmacro with-promise-from-thread (() &body forms)
"Return a promise that executes FORMS in a new thread, resolving the promise with the return value of (PROGN ,@FORMS) or rejecting it if an ERROR condition is thrown (with said condition)."
(let ((resolve (gensym))
(reject (gensym)))
`(with-promise (,resolve ,reject)
(bt:make-thread
(lambda ()
(handler-case
(,resolve (progn ,@forms))
(error (e) (,reject e))))))))
(defun split-at (seq pos &optional (consume-value-at-pos-p t))
"Splits SEQ at POS, returning two values. If CONSUME-VALUE-AT-POS-P is truthy, throws away the element at POS."
(declare (type sequence seq) (type fixnum pos))
(cond
((> pos (length seq)) (error "Position is outside sequence."))
((eql pos (length seq)) (values seq nil))
(t (values (subseq seq 0 pos) (subseq seq (+ pos (if consume-value-at-pos-p 1 0)))))))