diff --git a/CHANGES b/CHANGES index ff21315..ab87d33 100644 --- a/CHANGES +++ b/CHANGES @@ -10,9 +10,8 @@ on nNvV it turns them to signed integers - added . and @ support to pack - added full group support to pack and unpack - - fixed string types to accept numvers and cast them to strings on the fly (ala perl) - - added / template to pack - + - fixed string types to accept numbers and cast them to strings on the fly (ala perl) + - added / template to pack and unpack - added more test cases to cover all the new additions and bug fixes - Setup a git repository at git.mindstab.net/git/cl-pack diff --git a/cl-pack.lisp b/cl-pack.lisp index 7ca206e..ffcc659 100644 --- a/cl-pack.lisp +++ b/cl-pack.lisp @@ -96,9 +96,6 @@ ;;; ************* TODO *************** -;;;@ Null fill or truncate to absolute position, counted from the start of the innermost ()-group. -;;;. Null fill or truncate to absolute position specified by value. -;;; ;;;! MODIFIER, different uses in context ;;; / template @@ -237,7 +234,7 @@ "macro for building string type bodies for case statements in pack()" `(progn (if (numberp item) - (setf item (format nil "~d" item))) + (setf item (write-to-string item))) (handle-string (,repeater ,repeater-star) ,star-body ,count-body ,else-body))) (defmacro unpack-string ((repeater repeater-star) star-body count-body else-body) @@ -545,7 +542,7 @@ (if (member sequence-type '(#\a #\A #\Z #\b #\B #\h #\H)) (let ((item-length (if (numberp item) - (length (format nil "~d" item)) + (length (write-to-string item)) (length item)))) (setf consumed-length (if repeater-star @@ -746,7 +743,23 @@ (apply #'values (remove nil (append - (list + + (if (> /-pos 0) + (progn + (let* ((length-item (subseq form 0 /-pos)) + (sequence-item (subseq form (1+ /-pos) offset)) + (lengths (multiple-value-list (unpack length-item string :consumed 0 :modifiers modifiers))) + (seq-len (if (numberp (first lengths)) + (write-to-string (first lengths)) + (first lengths))) + + (ret (multiple-value-list (unpack (concatenate 'string sequence-item seq-len) (subseq string (second lengths)) :consumed 0 :modifiers modifiers))) + (consumed-len (+ (first (last ret)) (second lengths)))) + (cut-str string consumed-len new-str) + (inc-form) + (nbutlast ret) + )) + (list (case (strhead form) (#\n (unpack-mod!-uint 2 :big)) ; unsigned short 16bit big endian (#\N (unpack-mod!-uint 4 :big)) ; unsigned long 32bit big endian @@ -818,7 +831,7 @@ ) (otherwise nil) - )) + ))) ;; result of recursion diff --git a/tests.lisp b/tests.lisp index c2958db..d7c0878 100644 --- a/tests.lisp +++ b/tests.lisp @@ -82,6 +82,7 @@ (mod-<>) (grouping) (pack-/) + (unpack-/) )) (deftest test-silent () @@ -259,4 +260,12 @@ (string= (pack "n/c*" 65 66 67) (concatenate 'string (string #\null) (string (code-char 3)) "ABC")) ;basic pack into a number with a * (string= (pack "a/a3" "ABC") "3ABC") ;string pack (string= (pack "a/a*" "ABC") "3ABC") ;string pack with * + )) + +(deftest unpack-/ () + (check + (equal (multiple-value-list (unpack "a/c" "3AB")) '(65 66)) + (equal (multiple-value-list (unpack "n/c" (concatenate 'string (string #\null) (string (code-char 3)) "ABC"))) '(65 66 67)) + (equal (multiple-value-list (unpack "a/ac" "2ABC")) '("AB" 67)) + )) \ No newline at end of file