summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpukkamustard <pukkamustard@posteo.net>2021-02-28 13:21:01 +0100
committerpukkamustard <pukkamustard@posteo.net>2021-02-28 13:24:28 +0100
commit7e8d59e07542378e1ffb318dd29a884b9054e9d2 (patch)
tree3f4afb7448b2274b062edd79f6532918645034b4
parent5482ab531b9ae563646bec16a285ab317cef46ff (diff)
(tests cbor): Add examples from CBOR specification
-rw-r--r--README.org15
-rw-r--r--tests/cbor.scm197
2 files changed, 172 insertions, 40 deletions
diff --git a/README.org b/README.org
index 28715ec..3395d15 100644
--- a/README.org
+++ b/README.org
@@ -5,7 +5,6 @@
guile-cbor is a Guile implementation of CBOR (Concise Binary Object Representation) as specified by [[https://www.rfc-editor.org/rfc/rfc8949.html][RFC8949]].
* Usage
-
** Native Scheme Values <-> CBOR data items
| Native Scheme | CBOR | Note |
@@ -22,23 +21,25 @@ guile-cbor is a Guile implementation of CBOR (Concise Binary Object Representati
| real | IEEE 754 Single-Precision Float (major type 7) | CBOR single precision floats are parsed as Scheme real numbers |
| #f | false (major type 7, simple value 20) | |
| #t | true (major type 7, simple value 21) | |
-| #nil | null (major type 7, simple value 22) | |
+| #nil | empty array (major type 4) | This should be encoded to null (major type 7, simple value 22) (FIXME) |
| <cbor-indefinite-length> | Indefinite-Length Arrays and Maps | A Scheme record is used to encode indefinite-length arrays and maps. Arrays or maps of indefinite length are decoded to simple vectors or alists. |
+Note that IEEE 754 Half-Precision Floats can currently not be parsed as there is no native Guile support.
+
* Todos
** TODO Extended Generic Data Models
-Currently not the full "extended generic data model" is supported (only simple values ~#f~, ~#t~ and ~#nil~ are supported).
+Currently not the full "extended generic data model" is supported (only simple values ~#f~, ~#t~ are supported).
It might be nice to support the full extended generic data model (bignums, decimal fractions, bigfloats and date/time tags).
-** TODO Indefinite Length Byte Strings and Text Strings
+** TODO null and undefined
-Currently no support.
+Currentlly guile-cbor can not properly encode null and undefined.
-** TODO Tests
+** TODO Indefinite Length Byte Strings and Text Strings
-Some examples from the specification have been added but not all.
+Currently no support.
** TODO texinfo documentation
diff --git a/tests/cbor.scm b/tests/cbor.scm
index da3e062..4180245 100644
--- a/tests/cbor.scm
+++ b/tests/cbor.scm
@@ -5,59 +5,190 @@
(define-module (tests cbor)
#:use-module (cbor)
#:use-module (cbor indefinite-length)
+ #:use-module (cbor tag)
#:use-module (rnrs bytevectors)
- #:use-module (srfi srfi-64))
+ #:use-module (srfi srfi-64)
+ #:use-module (srfi srfi-171))
+
+(define (hex->bytevector hex-string)
+ "Decode hex encoded values as bytevectors"
+ (u8-list->bytevector
+ (string-transduce (compose
+ ;; drop the first two characters ("0x")
+ (tdrop 2)
+ ;; take 2 characters at a time
+ (tsegment 2)
+ ;; convert to integer
+ (tmap (lambda (cs)
+ (string->number (apply string cs) 16))))
+ rcons hex-string)))
(define specification-examples
- '((0 . (#x00))
- (1 . (#x01))
- (10 . (#x0a))
- (23 . (#x17))
- (24 . (#x18 #x18))
- (25 . (#x18 #x19))
- (100 . (#x18 #x64))
- (1000 . (#x19 #x03 #xe8))
- (1000000 . (#x1a #x00 #x0f #x42 #x40))
- (1000000000000 . (#x1b #x00 #x00 #x00 #xe8 #xd4 #xa5 #x10 #x00))
- (18446744073709551615 . (#x1b #xff #xff #xff #xff #xff #xff #xff #xff))
+ `((0 . "0x00")
+ (1 . "0x01")
+ (10 . "0x0a")
+ (23 . "0x17")
+ (24 . "0x1818")
+ (25 . "0x1819")
+ (100 . "0x1864")
+ (1000 . "0x1903e8")
+ (1000000 . "0x1a000f4240")
+ (1000000000000 . "0x1b000000e8d4a51000")
+ (18446744073709551615 . "0x1bffffffffffffffff")
;; requires bignums
- ;; (18446744073709551616 . (#xc2 #x49 #x01 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00))
- (-18446744073709551616 . (#x3b #xff #xff #xff #xff #xff #xff #xff #xff))
+ ;; (18446744073709551616 . "0xc249010000000000000000")
+ (-18446744073709551616 . "0x3bffffffffffffffff")
;; requires bignums
- ;; (-18446744073709551617 . (#xc3 #x49 #x01 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00))
- (-1 . (#x20))
- (-10 . (#x29))
- (-100 . (#x38 #x63))
+ ;; (-18446744073709551617 . "0xc349010000000000000000")
+
+ (-1 . "0x20")
+ (-10 . "0x29")
+ (-100 . "0x3863")
+ (-1000 . "0x3903e7")
+
;; requires support for IEE 754 half precission
- ;; (0.0 . (#xf9 #x00 #x00))
- ;; (-0.0 . (#xf9 #x80 #x00))
- ;; (1.0 . (#xf9 #x3c #x00))
- (1.1 . (#xfb #x3f #xf1 #x99 #x99 #x99 #x99 #x99 #x9a))
+ ;; (0.0 . "0xf90000")
+ ;; (-0.0 . "0xf98000")
+ ;; (1.0 . "0xf93c00")
+ ;; (1.1 . "0xfb3ff199999999999a")
+ ;; (1.5 . "0xf93e00")
+ ;; (65504.0 . "0xf97bff")
+ ;; (100000.0 . "0xfa47c35000")
+ ;; (3.4028234663852886e+38 . "0xfa7f7fffff")
+
+ (1.0e+300 . "0xfb7e37e43c8800759c")
+
+ ;; requires support for IEE 754 half precission
+ ;; (5.960464477539063e-8 . "0xf90001")
+ ;; (0.00006103515625 . "0xf90400")
+ ;; (-4.0 . "0xf9c400")
+
+ (-4.1 . "0xfbc010666666666666")
+
;; requires support for IEE 754 half precission
- ;; (1.5 . (#xf9 #x3e #x00))
+ ;; (,(inf) . "0xf97c00")
+ ;; (,(nan) . "0xf97e00")
+ ;; (,(- 0 (inf)) . "0xf9fc00")
+
+ ;; guile-cbor per defaults encodes ad double precission float (this can be decoded but not encoded)
+ ;; (,(inf) . "0xfa7f800000")
+ ;; (,(nan) . "0xfa7fc00000")
+ ;; (,(- 0 (inf)) . "0xfaff800000")
+
+ (,(inf) . "0xfb7ff0000000000000")
+ (,(nan) . "0xfb7ff8000000000000")
+ (,(- 0 (inf)) . "0xfbfff0000000000000")
+
+ (#f . "0xf4")
+ (#t . "0xf5")
+
+ ;; TODO how to encode null? It is indistinguishable from '()
+ ;; (#nil . "0xf6")
+
+ ;; TODO how to encode undefined?
+ ;; ('() . "0xf7")" "
+
+ ;; TODO add ability to encode simple values
+ ;; ('() . "0xf0")
+ ;; ('() . "0xf8ff")
+
+ (,(make-cbor-tag 0 "2013-03-21T20:04:00Z") . "0xc074323031332d30332d32315432303a30343a30305a")
+ (,(make-cbor-tag 1 1363896240) . "0xc11a514b67b0")
+ (,(make-cbor-tag 1 1363896240.5) . "0xc1fb41d452d9ec200000")
+
+ ;; NOTE we re-use the hex->bytevector helper for "h'" encoded values
+ (,(make-cbor-tag 23 (hex->bytevector "0x01020304")) .
+ "0xd74401020304")
+ (,(make-cbor-tag 24 (hex->bytevector "0x6449455446")) .
+ "0xd818456449455446")
+
+ (,(make-cbor-tag 32 "http://www.example.com") .
+ "0xd82076687474703a2f2f7777772e6578616d706c652e636f6d")
+
+ (,(make-bytevector 0) . "0x40")
+ (,(hex->bytevector "0x01020304") . "0x4401020304")
+
+ ("" . "0x60")
+ ("a" . "0x6161")
+ ("IETF" . "0x6449455446")
+ ("\"\\" . "0x62225c")
+ ("\u00fc" . "0x62c3bc")
+ ("\u6c34" . "0x63e6b0b4")
+ ;; ;; a round-about way of encoding U+10151 (GREEK ACROPHONIC ATTIC FIFTY STATERS)
+ (,(string (integer->char #x10151)) . "0x64f0908591")
+
+ (,(vector) . "0x80")
+ (,(vector 1 2 3) . "0x83010203")
+ (,(vector 1 (vector 2 3) (vector 4 5)) . "0x8301820203820405")
+ (,(vector 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25) .
+ "0x98190102030405060708090a0b0c0d0e0f101112131415161718181819")
+
+ (() . "0xa0")
+ (((1 . 2) (3 . 4)) . "0xa201020304")
+ ((("a" . 1) ("b" . ,(vector 2 3))) . "0xa26161016162820203")
+ ((("a" . "A") ("b" . "B") ("c" . "C") ("d" . "D") ("e" . "E")) .
+ "0xa56161614161626142616361436164614461656145")
+
+ ;; TODO add support for indefinte lenght byte strings and text
+ ;; (() . "0x5f42010243030405ff")
+ ;; (() . "0x7f657374726561646d696e67ff")
+
+ (,(make-cbor-indefinite-length (vector)) . "0x9fff")
+
+ ;; TODO fix testing procedure to not expect nested <cbor-indefinite-length> when deconding
+ ;; (,(make-cbor-indefinite-length
+ ;; (vector 1
+ ;; (vector 2 3)
+ ;; (make-cbor-indefinite-length
+ ;; (vector 4 5)))) .
+ ;; "0x9f018202039f0405ffff")
+ ;;
+
+ (,(make-cbor-indefinite-length
+ (vector 1
+ (vector 2 3)
+ (vector 4 5))) .
+ "0x9f01820203820405ff")
+
+ ;; TODO fix testing procedure to not expect nested <cbor-indefinite-length> when deconding
+ ;; (,(vector 1
+ ;; (vector 2 3)
+ ;; (make-cbor-indefinite-length
+ ;; (vector 4 5))) .
+ ;; "0x83018202039f0405ff")
+ ;; (,(vector 1
+ ;; (make-cbor-indefinite-length (vector 2 3))
+ ;; (vector 4 5)) .
+ ;; "0x83019f0203ff820405")
- )
- )
+ (,(make-cbor-indefinite-length
+ (vector 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)) .
+ "0x9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff")
-;; (scm->cbor 1.1)
+ ;; TODO fix testing procedure to not expect nested <cbor-indefinite-length> when deconding
+ ;; two tests missing
-;; (scm->cbor 18446744073709551616)
+ (,(make-cbor-indefinite-length
+ '(("Fun" . #t) ("Amt" . -2))) .
+ "0xbf6346756ef563416d7421ff")))
-;; (cbor->scm (scm->cbor (make-cbor-indefinite-length #(1 "Hello"))))
+(cbor->scm
+ (scm->cbor #nil))
-;; (cbor->scm
-;; (scm->cbor (make-cbor-indefinite-length '(("a" . 1)))))
+(hex->bytevector "0xf6")
-;; (scm->cbor "a")
(test-begin "Examples from specification")
(for-each
(lambda (example)
(let* ((native (car example))
- (encoded (u8-list->bytevector (cdr example))))
+ (encoded (hex->bytevector (cdr example))))
(test-assert (bytevector=? (scm->cbor native) encoded))
- (test-equal (cbor->scm encoded) native)))
+ ;; indefinite lenght values are decoded just as values.
+ (if (cbor-indefinite-length? native)
+ (test-equal (cbor->scm encoded) (cbor-indefinite-length-value native))
+ (test-equal (cbor->scm encoded) native))))
specification-examples)
(test-end "Examples from specification")