bytevectors.test 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. ;;;; bytevectors.test --- R6RS bytevectors. -*- mode: scheme; coding: utf-8; -*-
  2. ;;;;
  3. ;;;; Copyright (C) 2009-2015, 2018, 2021, 2023 Free Software Foundation, Inc.
  4. ;;;;
  5. ;;;; Ludovic Courtès
  6. ;;;;
  7. ;;;; This library is free software; you can redistribute it and/or
  8. ;;;; modify it under the terms of the GNU Lesser General Public
  9. ;;;; License as published by the Free Software Foundation; either
  10. ;;;; version 3 of the License, or (at your option) any later version.
  11. ;;;;
  12. ;;;; This library is distributed in the hope that it will be useful,
  13. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ;;;; Lesser General Public License for more details.
  16. ;;;;
  17. ;;;; You should have received a copy of the GNU Lesser General Public
  18. ;;;; License along with this library; if not, write to the Free Software
  19. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. (define-module (test-bytevector)
  21. #:use-module (test-suite lib)
  22. #:use-module (system base compile)
  23. #:use-module (rnrs bytevectors)
  24. #:use-module (rnrs bytevectors gnu)
  25. #:use-module ((system foreign) #:select (sizeof size_t))
  26. #:use-module (srfi srfi-1)
  27. #:use-module (srfi srfi-4))
  28. (define exception:decoding-error
  29. (cons 'decoding-error "input (locale conversion|decoding) error"))
  30. ;;; Some of the tests in here are examples taken from the R6RS Standard
  31. ;;; Libraries document.
  32. (with-test-prefix/c&e "2.2 General Operations"
  33. (pass-if "native-endianness"
  34. (not (not (memq (native-endianness) '(big little)))))
  35. (pass-if "make-bytevector"
  36. (and (bytevector? (make-bytevector 20))
  37. (bytevector? (make-bytevector 20 3))))
  38. (pass-if "bytevector-length"
  39. (= (bytevector-length (make-bytevector 20)) 20))
  40. (pass-if "bytevector=?"
  41. (and (bytevector=? (make-bytevector 20 7)
  42. (make-bytevector 20 7))
  43. (not (bytevector=? (make-bytevector 20 7)
  44. (make-bytevector 20 0)))))
  45. ;; This failed prior to Guile 2.0.12.
  46. ;; See <http://bugs.gnu.org/19027>.
  47. (pass-if-equal "bytevector-fill! with fill 255"
  48. #vu8(255 255 255 255)
  49. (let ((bv (make-bytevector 4)))
  50. (bytevector-fill! bv 255)
  51. bv))
  52. ;; This is a Guile-specific extension.
  53. (pass-if-equal "bytevector-fill! with fill -128"
  54. #vu8(128 128 128 128)
  55. (let ((bv (make-bytevector 4)))
  56. (bytevector-fill! bv -128)
  57. bv))
  58. ;; This is a Guile-specific extension.
  59. (pass-if-equal "bytevector-fill! range arguments I"
  60. #vu8(0 0 1 1 1)
  61. (let ((bv (make-bytevector 5 0)))
  62. (bytevector-fill! bv 1 2)
  63. bv))
  64. ;; This is a Guile-specific extension.
  65. (pass-if-equal "bytevector-fill! range arguments II"
  66. #vu8(0 0 1 1 0)
  67. (let ((bv (make-bytevector 5 0)))
  68. (bytevector-fill! bv 1 2 4)
  69. bv))
  70. (pass-if "bytevector-copy! overlapping"
  71. ;; See <http://debbugs.gnu.org/10070>.
  72. (let ((b (u8-list->bytevector '(1 2 3 4 5 6 7 8))))
  73. (bytevector-copy! b 0 b 3 4)
  74. (bytevector->u8-list b)
  75. (bytevector=? b #vu8(1 2 3 1 2 3 4 8)))))
  76. (with-test-prefix/c&e "2.3 Operations on Bytes and Octets"
  77. (pass-if "bytevector-{u8,s8}-ref"
  78. (equal? '(-127 129 -1 255)
  79. (let ((b1 (make-bytevector 16 -127))
  80. (b2 (make-bytevector 16 255)))
  81. (list (bytevector-s8-ref b1 0)
  82. (bytevector-u8-ref b1 0)
  83. (bytevector-s8-ref b2 0)
  84. (bytevector-u8-ref b2 0)))))
  85. (pass-if "bytevector-{u8,s8}-set!"
  86. (equal? '(-126 130 -10 246)
  87. (let ((b (make-bytevector 16 -127)))
  88. (bytevector-s8-set! b 0 -126)
  89. (bytevector-u8-set! b 1 246)
  90. (list (bytevector-s8-ref b 0)
  91. (bytevector-u8-ref b 0)
  92. (bytevector-s8-ref b 1)
  93. (bytevector-u8-ref b 1)))))
  94. (pass-if "bytevector->u8-list"
  95. (let ((lst '(1 2 3 128 150 255)))
  96. (equal? lst
  97. (bytevector->u8-list
  98. (let ((b (make-bytevector 6)))
  99. (for-each (lambda (i v)
  100. (bytevector-u8-set! b i v))
  101. (iota 6)
  102. lst)
  103. b)))))
  104. (pass-if "u8-list->bytevector"
  105. (let ((lst '(1 2 3 128 150 255)))
  106. (equal? lst
  107. (bytevector->u8-list (u8-list->bytevector lst)))))
  108. (pass-if-exception "u8-list->bytevector [invalid argument type]"
  109. exception:wrong-type-arg
  110. (u8-list->bytevector 'not-a-list))
  111. (pass-if-exception "u8-list->bytevector [circular list]"
  112. exception:wrong-type-arg
  113. (u8-list->bytevector (circular-list 1 2 3)))
  114. (pass-if "bytevector-uint-{ref,set!} [small]"
  115. (let ((b (make-bytevector 15)))
  116. (bytevector-uint-set! b 0 #x1234
  117. (endianness little) 2)
  118. (equal? (bytevector-uint-ref b 0 (endianness big) 2)
  119. #x3412)))
  120. (pass-if "bytevector-uint-set! [large]"
  121. (let ((b (make-bytevector 16)))
  122. (bytevector-uint-set! b 0 (- (expt 2 128) 3)
  123. (endianness little) 16)
  124. (equal? (bytevector->u8-list b)
  125. '(253 255 255 255 255 255 255 255
  126. 255 255 255 255 255 255 255 255))))
  127. (pass-if "bytevector-uint-{ref,set!} [large]"
  128. (let ((b (make-bytevector 120)))
  129. (bytevector-uint-set! b 0 (- (expt 2 128) 3)
  130. (endianness little) 16)
  131. (equal? (bytevector-uint-ref b 0 (endianness little) 16)
  132. #xfffffffffffffffffffffffffffffffd)))
  133. (pass-if "bytevector-sint-ref [small]"
  134. (let ((b (u8-list->bytevector '(#xff #xf0 #xff))))
  135. (equal? (bytevector-sint-ref b 0 (endianness big) 2)
  136. (bytevector-sint-ref b 1 (endianness little) 2)
  137. -16)))
  138. (pass-if "bytevector-sint-ref [large]"
  139. (let ((b (make-bytevector 50)))
  140. (bytevector-uint-set! b 0 (- (expt 2 128) 3)
  141. (endianness little) 16)
  142. (equal? (bytevector-sint-ref b 0 (endianness little) 16)
  143. -3)))
  144. (pass-if "bytevector-sint-set! [small]"
  145. (let ((b (make-bytevector 3)))
  146. (bytevector-sint-set! b 0 -16 (endianness big) 2)
  147. (bytevector-sint-set! b 1 -16 (endianness little) 2)
  148. (equal? (bytevector->u8-list b)
  149. '(#xff #xf0 #xff))))
  150. (pass-if "equal?"
  151. (let ((bv1 (u8-list->bytevector (iota 123)))
  152. (bv2 (u8-list->bytevector (iota 123))))
  153. (equal? bv1 bv2))))
  154. (with-test-prefix/c&e "2.4 Operations on Integers of Arbitrary Size"
  155. (pass-if "bytevector->sint-list"
  156. (let ((b (u8-list->bytevector '(1 2 3 255 1 2 1 2))))
  157. (equal? (bytevector->sint-list b (endianness little) 2)
  158. '(513 -253 513 513))))
  159. (pass-if "bytevector->uint-list"
  160. (let ((b (u8-list->bytevector '(2 1 255 3 2 1 2 1))))
  161. (equal? (bytevector->uint-list b (endianness big) 2)
  162. '(513 65283 513 513))))
  163. (pass-if "bytevector->uint-list [empty]"
  164. (let ((b (make-bytevector 0)))
  165. (null? (bytevector->uint-list b (endianness big) 2))))
  166. (pass-if-exception "bytevector->sint-list [out-of-range]"
  167. exception:out-of-range
  168. (bytevector->sint-list (make-bytevector 6) (endianness little) -1))
  169. (pass-if-exception "bytevector->uint-list [out-of-range]"
  170. exception:out-of-range
  171. (bytevector->uint-list (make-bytevector 6) (endianness little) 0))
  172. (pass-if-exception "bytevector->uint-list [word size doesn't divide length]"
  173. exception:wrong-type-arg
  174. (bytevector->uint-list (make-bytevector 6) (endianness little) 4))
  175. (pass-if "{sint,uint}-list->bytevector"
  176. (let ((b1 (sint-list->bytevector '(513 -253 513 513)
  177. (endianness little) 2))
  178. (b2 (uint-list->bytevector '(513 65283 513 513)
  179. (endianness little) 2))
  180. (b3 (u8-list->bytevector '(1 2 3 255 1 2 1 2))))
  181. (and (bytevector=? b1 b2)
  182. (bytevector=? b2 b3))))
  183. (pass-if "sint-list->bytevector [limits]"
  184. (bytevector=? (sint-list->bytevector '(-32768 32767)
  185. (endianness big) 2)
  186. (let ((bv (make-bytevector 4)))
  187. (bytevector-u8-set! bv 0 #x80)
  188. (bytevector-u8-set! bv 1 #x00)
  189. (bytevector-u8-set! bv 2 #x7f)
  190. (bytevector-u8-set! bv 3 #xff)
  191. bv)))
  192. (pass-if-exception "sint-list->bytevector [invalid argument type]"
  193. exception:wrong-type-arg
  194. (sint-list->bytevector 'not-a-list (endianness big) 2))
  195. (pass-if-exception "uint-list->bytevector [invalid argument type]"
  196. exception:wrong-type-arg
  197. (uint-list->bytevector 'not-a-list (endianness big) 2))
  198. (pass-if-exception "sint-list->bytevector [circular list]"
  199. exception:wrong-type-arg
  200. (sint-list->bytevector (circular-list 1 2 3) (endianness big)
  201. 2))
  202. (pass-if-exception "uint-list->bytevector [circular list]"
  203. exception:wrong-type-arg
  204. (uint-list->bytevector (circular-list 1 2 3) (endianness big)
  205. 2))
  206. (pass-if-exception "sint-list->bytevector [out-of-range]"
  207. exception:out-of-range
  208. (sint-list->bytevector (list 0 0 (expt 2 16)) (endianness big)
  209. 2))
  210. (pass-if-exception "uint-list->bytevector [out-of-range]"
  211. exception:out-of-range
  212. (uint-list->bytevector '(0 -1) (endianness big) 2)))
  213. (with-test-prefix/c&e "2.5 Operations on 16-Bit Integers"
  214. (pass-if "bytevector-u16-ref"
  215. (let ((b (u8-list->bytevector
  216. '(255 255 255 255 255 255 255 255
  217. 255 255 255 255 255 255 255 253))))
  218. (and (equal? (bytevector-u16-ref b 14 (endianness little))
  219. #xfdff)
  220. (equal? (bytevector-u16-ref b 14 (endianness big))
  221. #xfffd))))
  222. (pass-if "bytevector-s16-ref"
  223. (let ((b (u8-list->bytevector
  224. '(255 255 255 255 255 255 255 255
  225. 255 255 255 255 255 255 255 253))))
  226. (and (equal? (bytevector-s16-ref b 14 (endianness little))
  227. -513)
  228. (equal? (bytevector-s16-ref b 14 (endianness big))
  229. -3))))
  230. (pass-if "bytevector-s16-ref [unaligned]"
  231. (let ((b (u8-list->bytevector '(#xff #xf0 #xff))))
  232. (equal? (bytevector-s16-ref b 1 (endianness little))
  233. -16)))
  234. (pass-if "bytevector-{u16,s16}-ref"
  235. (let ((b (make-bytevector 2)))
  236. (bytevector-u16-set! b 0 44444 (endianness little))
  237. (and (equal? (bytevector-u16-ref b 0 (endianness little))
  238. 44444)
  239. (equal? (bytevector-s16-ref b 0 (endianness little))
  240. (- 44444 65536)))))
  241. (pass-if "bytevector-native-{u16,s16}-{ref,set!}"
  242. (let ((b (make-bytevector 2)))
  243. (bytevector-u16-native-set! b 0 44444)
  244. (and (equal? (bytevector-u16-native-ref b 0)
  245. 44444)
  246. (equal? (bytevector-s16-native-ref b 0)
  247. (- 44444 65536)))))
  248. (pass-if "bytevector-s16-{ref,set!} [unaligned]"
  249. (let ((b (make-bytevector 3)))
  250. (bytevector-s16-set! b 1 -77 (endianness little))
  251. (equal? (bytevector-s16-ref b 1 (endianness little))
  252. -77))))
  253. (with-test-prefix/c&e "2.6 Operations on 32-bit Integers"
  254. (pass-if "bytevector-u32-ref"
  255. (let ((b (u8-list->bytevector
  256. '(255 255 255 255 255 255 255 255
  257. 255 255 255 255 255 255 255 253))))
  258. (and (equal? (bytevector-u32-ref b 12 (endianness little))
  259. #xfdffffff)
  260. (equal? (bytevector-u32-ref b 12 (endianness big))
  261. #xfffffffd))))
  262. (pass-if "bytevector-s32-ref"
  263. (let ((b (u8-list->bytevector
  264. '(255 255 255 255 255 255 255 255
  265. 255 255 255 255 255 255 255 253))))
  266. (and (equal? (bytevector-s32-ref b 12 (endianness little))
  267. -33554433)
  268. (equal? (bytevector-s32-ref b 12 (endianness big))
  269. -3))))
  270. (pass-if "bytevector-{u32,s32}-ref"
  271. (let ((b (make-bytevector 4)))
  272. (bytevector-u32-set! b 0 2222222222 (endianness little))
  273. (and (equal? (bytevector-u32-ref b 0 (endianness little))
  274. 2222222222)
  275. (equal? (bytevector-s32-ref b 0 (endianness little))
  276. (- 2222222222 (expt 2 32))))))
  277. (pass-if "bytevector-{u32,s32}-native-{ref,set!}"
  278. (let ((b (make-bytevector 4)))
  279. (bytevector-u32-native-set! b 0 2222222222)
  280. (and (equal? (bytevector-u32-native-ref b 0)
  281. 2222222222)
  282. (equal? (bytevector-s32-native-ref b 0)
  283. (- 2222222222 (expt 2 32)))))))
  284. (with-test-prefix/c&e "2.7 Operations on 64-bit Integers"
  285. (pass-if "bytevector-u64-ref"
  286. (let ((b (u8-list->bytevector
  287. '(255 255 255 255 255 255 255 255
  288. 255 255 255 255 255 255 255 253))))
  289. (and (equal? (bytevector-u64-ref b 8 (endianness little))
  290. #xfdffffffffffffff)
  291. (equal? (bytevector-u64-ref b 8 (endianness big))
  292. #xfffffffffffffffd))))
  293. (pass-if "bytevector-s64-ref"
  294. (let ((b (u8-list->bytevector
  295. '(255 255 255 255 255 255 255 255
  296. 255 255 255 255 255 255 255 253))))
  297. (and (equal? (bytevector-s64-ref b 8 (endianness little))
  298. -144115188075855873)
  299. (equal? (bytevector-s64-ref b 8 (endianness big))
  300. -3))))
  301. (pass-if "bytevector-{u64,s64}-ref"
  302. (let ((b (make-bytevector 8))
  303. (big 9333333333333333333))
  304. (bytevector-u64-set! b 0 big (endianness little))
  305. (and (equal? (bytevector-u64-ref b 0 (endianness little))
  306. big)
  307. (equal? (bytevector-s64-ref b 0 (endianness little))
  308. (- big (expt 2 64))))))
  309. (pass-if "bytevector-{u64,s64}-native-{ref,set!}"
  310. (let ((b (make-bytevector 8))
  311. (big 9333333333333333333))
  312. (bytevector-u64-native-set! b 0 big)
  313. (and (equal? (bytevector-u64-native-ref b 0)
  314. big)
  315. (equal? (bytevector-s64-native-ref b 0)
  316. (- big (expt 2 64))))))
  317. (pass-if "ref/set! with zero"
  318. (let ((b (make-bytevector 8)))
  319. (bytevector-s64-set! b 0 -1 (endianness big))
  320. (bytevector-u64-set! b 0 0 (endianness big))
  321. (= 0 (bytevector-u64-ref b 0 (endianness big)))))
  322. (pass-if-exception "bignum out of range"
  323. exception:out-of-range
  324. (bytevector-u64-set! (make-bytevector 8) 0 (expt 2 64) (endianness big))))
  325. (with-test-prefix/c&e "2.8 Operations on IEEE-754 Representations"
  326. (pass-if "single, little endian"
  327. ;; http://bugs.gnu.org/11310
  328. (let ((b (make-bytevector 4)))
  329. (bytevector-ieee-single-set! b 0 1.0 (endianness little))
  330. (equal? #vu8(0 0 128 63) b)))
  331. (pass-if "single, big endian"
  332. ;; http://bugs.gnu.org/11310
  333. (let ((b (make-bytevector 4)))
  334. (bytevector-ieee-single-set! b 0 1.0 (endianness big))
  335. (equal? #vu8(63 128 0 0) b)))
  336. (pass-if "bytevector-ieee-single-native-{ref,set!}"
  337. (let ((b (make-bytevector 4))
  338. (number 3.00))
  339. (bytevector-ieee-single-native-set! b 0 number)
  340. (equal? (bytevector-ieee-single-native-ref b 0)
  341. number)))
  342. (pass-if "bytevector-ieee-single-{ref,set!}"
  343. (let ((b (make-bytevector 8))
  344. (number 3.14))
  345. (bytevector-ieee-single-set! b 0 number (endianness little))
  346. (bytevector-ieee-single-set! b 4 number (endianness big))
  347. (equal? (bytevector-ieee-single-ref b 0 (endianness little))
  348. (bytevector-ieee-single-ref b 4 (endianness big)))))
  349. (pass-if "bytevector-ieee-single-{ref,set!} [unaligned]"
  350. (let ((b (make-bytevector 9))
  351. (number 3.14))
  352. (bytevector-ieee-single-set! b 1 number (endianness little))
  353. (bytevector-ieee-single-set! b 5 number (endianness big))
  354. (equal? (bytevector-ieee-single-ref b 1 (endianness little))
  355. (bytevector-ieee-single-ref b 5 (endianness big)))))
  356. (pass-if "double, little endian"
  357. ;; http://bugs.gnu.org/11310
  358. (let ((b (make-bytevector 8)))
  359. (bytevector-ieee-double-set! b 0 1.0 (endianness little))
  360. (equal? #vu8(0 0 0 0 0 0 240 63) b)))
  361. (pass-if "double, big endian"
  362. ;; http://bugs.gnu.org/11310
  363. (let ((b (make-bytevector 8)))
  364. (bytevector-ieee-double-set! b 0 1.0 (endianness big))
  365. (equal? #vu8(63 240 0 0 0 0 0 0) b)))
  366. (pass-if "bytevector-ieee-double-native-{ref,set!}"
  367. (let ((b (make-bytevector 8))
  368. (number 3.14))
  369. (bytevector-ieee-double-native-set! b 0 number)
  370. (equal? (bytevector-ieee-double-native-ref b 0)
  371. number)))
  372. (pass-if "bytevector-ieee-double-{ref,set!}"
  373. (let ((b (make-bytevector 16))
  374. (number 3.14))
  375. (bytevector-ieee-double-set! b 0 number (endianness little))
  376. (bytevector-ieee-double-set! b 8 number (endianness big))
  377. (equal? (bytevector-ieee-double-ref b 0 (endianness little))
  378. (bytevector-ieee-double-ref b 8 (endianness big))))))
  379. ;; Default to the C locale for the following tests.
  380. (when (defined? 'setlocale)
  381. (setlocale LC_ALL "C"))
  382. (with-test-prefix "2.9 Operations on Strings"
  383. (pass-if "string->utf8"
  384. (let* ((str "hello, world")
  385. (utf8 (string->utf8 str)))
  386. (and (bytevector? utf8)
  387. (= (bytevector-length utf8)
  388. (string-length str))
  389. (equal? (string->list str)
  390. (map integer->char (bytevector->u8-list utf8))))))
  391. (pass-if "string->utf8 [latin-1]"
  392. (let* ((str "hé, ça va bien ?")
  393. (utf8 (string->utf8 str)))
  394. (and (bytevector? utf8)
  395. (= (bytevector-length utf8)
  396. (+ 2 (string-length str))))))
  397. (pass-if "string->utf16"
  398. (let* ((str "hello, world")
  399. (utf16 (string->utf16 str)))
  400. (and (bytevector? utf16)
  401. (= (bytevector-length utf16)
  402. (* 2 (string-length str)))
  403. (equal? (string->list str)
  404. (map integer->char
  405. (bytevector->uint-list utf16
  406. (endianness big) 2))))))
  407. (pass-if "string->utf16 [little]"
  408. (let* ((str "hello, world")
  409. (utf16 (string->utf16 str (endianness little))))
  410. (and (bytevector? utf16)
  411. (= (bytevector-length utf16)
  412. (* 2 (string-length str)))
  413. (equal? (string->list str)
  414. (map integer->char
  415. (bytevector->uint-list utf16
  416. (endianness little) 2))))))
  417. (pass-if "string->utf32"
  418. (let* ((str "hello, world")
  419. (utf32 (string->utf32 str)))
  420. (and (bytevector? utf32)
  421. (= (bytevector-length utf32)
  422. (* 4 (string-length str)))
  423. (equal? (string->list str)
  424. (map integer->char
  425. (bytevector->uint-list utf32
  426. (endianness big) 4))))))
  427. (pass-if "string->utf32 [Greek]"
  428. (let* ((str "Ἄνεμοι")
  429. (utf32 (string->utf32 str)))
  430. (and (bytevector? utf32)
  431. (equal? (bytevector->uint-list utf32 (endianness big) 4)
  432. '(#x1f0c #x3bd #x3b5 #x3bc #x3bf #x3b9)))))
  433. (pass-if "string->utf32 [little]"
  434. (let* ((str "hello, world")
  435. (utf32 (string->utf32 str (endianness little))))
  436. (and (bytevector? utf32)
  437. (= (bytevector-length utf32)
  438. (* 4 (string-length str)))
  439. (equal? (string->list str)
  440. (map integer->char
  441. (bytevector->uint-list utf32
  442. (endianness little) 4))))))
  443. (pass-if "utf8->string"
  444. (let* ((utf8 (u8-list->bytevector (map char->integer
  445. (string->list "hello, world"))))
  446. (str (utf8->string utf8)))
  447. (and (string? str)
  448. (= (string-length str)
  449. (bytevector-length utf8))
  450. (equal? (string->list str)
  451. (map integer->char (bytevector->u8-list utf8))))))
  452. (pass-if "utf8->string [latin-1]"
  453. (let* ((utf8 (string->utf8 "hé, ça va bien ?"))
  454. (str (utf8->string utf8)))
  455. (and (string? str)
  456. (= (string-length str)
  457. (- (bytevector-length utf8) 2)))))
  458. (pass-if-equal "utf8->string [replacement character]"
  459. '(104 105 65533)
  460. (map char->integer
  461. (string->list (utf8->string #vu8(104 105 239 191 189)))))
  462. (pass-if-exception "utf8->string [invalid encoding]"
  463. exception:decoding-error
  464. (utf8->string #vu8(104 105 239 191 50)))
  465. (pass-if "utf16->string"
  466. (let* ((utf16 (uint-list->bytevector (map char->integer
  467. (string->list "hello, world"))
  468. (endianness big) 2))
  469. (str (utf16->string utf16)))
  470. (and (string? str)
  471. (= (* 2 (string-length str))
  472. (bytevector-length utf16))
  473. (equal? (string->list str)
  474. (map integer->char
  475. (bytevector->uint-list utf16 (endianness big)
  476. 2))))))
  477. (pass-if "utf16->string [little]"
  478. (let* ((utf16 (uint-list->bytevector (map char->integer
  479. (string->list "hello, world"))
  480. (endianness little) 2))
  481. (str (utf16->string utf16 (endianness little))))
  482. (and (string? str)
  483. (= (* 2 (string-length str))
  484. (bytevector-length utf16))
  485. (equal? (string->list str)
  486. (map integer->char
  487. (bytevector->uint-list utf16 (endianness little)
  488. 2))))))
  489. (pass-if "utf32->string"
  490. (let* ((utf32 (uint-list->bytevector (map char->integer
  491. (string->list "hello, world"))
  492. (endianness big) 4))
  493. (str (utf32->string utf32)))
  494. (and (string? str)
  495. (= (* 4 (string-length str))
  496. (bytevector-length utf32))
  497. (equal? (string->list str)
  498. (map integer->char
  499. (bytevector->uint-list utf32 (endianness big)
  500. 4))))))
  501. (pass-if "utf32->string [little]"
  502. (let* ((utf32 (uint-list->bytevector (map char->integer
  503. (string->list "hello, world"))
  504. (endianness little) 4))
  505. (str (utf32->string utf32 (endianness little))))
  506. (and (string? str)
  507. (= (* 4 (string-length str))
  508. (bytevector-length utf32))
  509. (equal? (string->list str)
  510. (map integer->char
  511. (bytevector->uint-list utf32 (endianness little)
  512. 4)))))))
  513. (with-test-prefix "Datum Syntax"
  514. (pass-if "empty"
  515. (equal? (with-input-from-string "#vu8()" read)
  516. (make-bytevector 0)))
  517. (pass-if "simple"
  518. (equal? (with-input-from-string "#vu8(1 2 3 4 5)" read)
  519. (u8-list->bytevector '(1 2 3 4 5))))
  520. (pass-if ">127"
  521. (equal? (with-input-from-string "#vu8(0 255 127 128)" read)
  522. (u8-list->bytevector '(0 255 127 128))))
  523. (pass-if "self-evaluating?"
  524. (self-evaluating? (make-bytevector 1)))
  525. (pass-if "self-evaluating"
  526. (equal? (eval (with-input-from-string "#vu8(1 2 3 4 5)" read)
  527. (current-module))
  528. (u8-list->bytevector '(1 2 3 4 5))))
  529. (pass-if "quoted"
  530. (equal? (eval (with-input-from-string "'#vu8(1 2 3 4 5)" read)
  531. (current-module))
  532. (u8-list->bytevector '(1 2 3 4 5))))
  533. (pass-if "literal simple"
  534. (equal? #vu8(1 2 3 4 5)
  535. (u8-list->bytevector '(1 2 3 4 5))))
  536. (pass-if "literal >127"
  537. (equal? #vu8(0 255 127 128)
  538. (u8-list->bytevector '(0 255 127 128))))
  539. (pass-if "literal quoted"
  540. (equal? '#vu8(1 2 3 4 5)
  541. (u8-list->bytevector '(1 2 3 4 5))))
  542. (pass-if-exception "incorrect prefix"
  543. exception:read-error
  544. (with-input-from-string "#vi8(1 2 3)" read))
  545. (pass-if-exception "extraneous space"
  546. exception:read-error
  547. (with-input-from-string "#vu8 (1 2 3)" read))
  548. (pass-if-exception "negative integers"
  549. exception:out-of-range
  550. (with-input-from-string "#vu8(-1 -2 -3)" read))
  551. (pass-if-exception "out-of-range integers"
  552. exception:out-of-range
  553. (with-input-from-string "#vu8(0 256)" read)))
  554. (with-test-prefix "bytevector-slice"
  555. (pass-if-exception "wrong size"
  556. exception:out-of-range
  557. (let ((b #vu8(1 2 3)))
  558. (bytevector-slice b 1 3)))
  559. (pass-if-equal "slices"
  560. (list #vu8(1 2) #vu8(2 3)
  561. #vu8(1) #vu8(2) #vu8(3))
  562. (let ((b #vu8(1 2 3)))
  563. (list (bytevector-slice b 0 2)
  564. (bytevector-slice b 1)
  565. (bytevector-slice b 0 1)
  566. (bytevector-slice b 1 1)
  567. (bytevector-slice b 2))))
  568. (pass-if-exception "immutable flag preserved"
  569. exception:wrong-type-arg
  570. (compile '(begin
  571. (use-modules (rnrs bytevectors)
  572. (rnrs bytevectors gnu))
  573. ;; The literal bytevector below is immutable.
  574. (let ((bv #vu8(1 2 3)))
  575. (bytevector-u8-set! (bytevector-slice bv 1) 0 0)))
  576. ;; Disable optimizations to invoke the full-blown
  577. ;; 'scm_bytevector_u8_set_x' procedure, which checks for
  578. ;; the SCM_F_BYTEVECTOR_IMMUTABLE flag.
  579. #:optimization-level 0
  580. #:to 'value))
  581. (pass-if-exception "size + offset overflows"
  582. exception:out-of-range
  583. (let ((size_t-max (expt 2 (* 8 (sizeof size_t)))))
  584. ;; Without overflow checks, this would read arbitrary memory.
  585. (bytevector-slice #vu8(1 2 3) (- size_t-max 10) 10)))
  586. (pass-if-equal "slice of f32vector"
  587. '(8 2)
  588. (let* ((v #f32(1.1 1.2 3.14))
  589. (s (bytevector-slice v 4)))
  590. (and (= (f32vector-ref s 0)
  591. (f32vector-ref v 1))
  592. (list (bytevector-length s)
  593. (f32vector-length s)))))
  594. (pass-if-equal "unaligned offset for f32vector"
  595. 10
  596. (let* ((v #f32(1.1 1.2 3.14))
  597. (s (bytevector-slice v 2)))
  598. (and (not (f32vector? s))
  599. (bytevector-length s))))
  600. (pass-if-equal "unaligned size for f32vector"
  601. 1
  602. (let* ((v #f32(1.1 1.2 3.14))
  603. (s (bytevector-slice v 0 1)))
  604. (and (not (f32vector? s))
  605. (bytevector-length s)))))
  606. (with-test-prefix "Arrays"
  607. (pass-if "array?"
  608. (array? #vu8(1 2 3)))
  609. (pass-if "array-length"
  610. (equal? (iota 16)
  611. (map array-length
  612. (map make-bytevector (iota 16)))))
  613. (pass-if "array-ref"
  614. (let ((bv #vu8(255 127)))
  615. (and (= 255 (array-ref bv 0))
  616. (= 127 (array-ref bv 1)))))
  617. (pass-if-exception "array-ref [index out-of-range]"
  618. exception:out-of-range
  619. (let ((bv #vu8(1 2)))
  620. (array-ref bv 2)))
  621. (pass-if "array-set!"
  622. (let ((bv (make-bytevector 2)))
  623. (array-set! bv 255 0)
  624. (array-set! bv 77 1)
  625. (equal? '(255 77)
  626. (bytevector->u8-list bv))))
  627. (pass-if-exception "array-set! [index out-of-range]"
  628. exception:out-of-range
  629. (let ((bv (make-bytevector 2)))
  630. (array-set! bv 0 2)))
  631. (pass-if-exception "array-set! [value out-of-range]"
  632. exception:out-of-range
  633. (let ((bv (make-bytevector 2)))
  634. (array-set! bv 256 0)))
  635. (pass-if "array-type"
  636. (eq? 'vu8 (array-type #vu8())))
  637. (pass-if "array-contents"
  638. (let ((bv (u8-list->bytevector (iota 10))))
  639. (eq? bv (array-contents bv))))
  640. (pass-if "array-ref"
  641. (let ((bv (u8-list->bytevector (iota 10))))
  642. (equal? (iota 10)
  643. (map (lambda (i) (array-ref bv i))
  644. (iota 10)))))
  645. (pass-if "array-set!"
  646. (let ((bv (make-bytevector 10)))
  647. (for-each (lambda (i)
  648. (array-set! bv i i))
  649. (iota 10))
  650. (equal? (iota 10)
  651. (bytevector->u8-list bv))))
  652. (pass-if "make-typed-array"
  653. (let ((bv (make-typed-array 'vu8 77 33)))
  654. (equal? bv (u8-list->bytevector (make-list 33 77)))))
  655. (pass-if-exception "make-typed-array [out-of-range]"
  656. exception:out-of-range
  657. (make-typed-array 'vu8 256 77)))
  658. (with-test-prefix "uniform-array->bytevector"
  659. (pass-if "bytevector"
  660. (let ((bv #vu8(0 1 128 255)))
  661. (equal? bv (uniform-array->bytevector bv))))
  662. (pass-if "empty bitvector"
  663. (let ((bv (uniform-array->bytevector (make-bitvector 0))))
  664. (equal? bv #vu8())))
  665. (pass-if "bitvector < 8"
  666. (let ((bv (uniform-array->bytevector (make-bitvector 4 #t))))
  667. (= (bytevector-length bv) 4)))
  668. (pass-if "bitvector == 8"
  669. (let ((bv (uniform-array->bytevector (make-bitvector 8 #t))))
  670. (= (bytevector-length bv) 4)))
  671. (pass-if "bitvector > 8"
  672. (let ((bv (uniform-array->bytevector (make-bitvector 9 #t))))
  673. (= (bytevector-length bv) 4)))
  674. (pass-if "bitvector == 32"
  675. (let ((bv (uniform-array->bytevector (make-bitvector 32 #t))))
  676. (= (bytevector-length bv) 4)))
  677. (pass-if "bitvector > 32"
  678. (let ((bv (uniform-array->bytevector (make-bitvector 33 #t))))
  679. (= (bytevector-length bv) 8))))
  680. (with-test-prefix "srfi-4 homogeneous numeric vectors as bytevectors"
  681. ;; This failed prior to Guile 2.0.12.
  682. ;; See <http://bugs.gnu.org/18866>.
  683. (pass-if-equal "bytevector-copy on srfi-4 arrays"
  684. (make-bytevector 8 #xFF)
  685. (bytevector-copy (make-u32vector 2 #xFFFFFFFF))))
  686. ;;; Local Variables:
  687. ;;; eval: (put 'with-test-prefix/c&e 'scheme-indent-function 1)
  688. ;;; End: