74.upstream.scm 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. ; Octet-addressed binary objects
  2. ; Copyright (C) Michael Sperber (2005). All Rights Reserved.
  3. ;
  4. ; Permission is hereby granted, free of charge, to any person
  5. ; obtaining a copy of this software and associated documentation files
  6. ; (the "Software"), to deal in the Software without restriction,
  7. ; including without limitation the rights to use, copy, modify, merge,
  8. ; publish, distribute, sublicense, and/or sell copies of the Software,
  9. ; and to permit persons to whom the Software is furnished to do so,
  10. ; subject to the following conditions:
  11. ;
  12. ; The above copyright notice and this permission notice shall be
  13. ; included in all copies or substantial portions of the Software.
  14. ;
  15. ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. ; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. ; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. ; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19. ; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20. ; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. ; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. ; SOFTWARE.
  23. ; This uses SRFIs 23, 26, 60, and 66
  24. (define *endianness/little* (list 'little))
  25. (define *endianness/big* (list 'big))
  26. (define-syntax endianness
  27. (syntax-rules (little big native)
  28. ((endianness little) *endianness/little*)
  29. ((endianness big) *endianness/big*)
  30. ;; change this to the endianness of your architecture
  31. ((endianness native) *endianness/big*)))
  32. (define blob? u8vector?)
  33. (define (make-blob k)
  34. (make-u8vector k 0))
  35. (define (blob-length b)
  36. (u8vector-length b))
  37. (define (blob-u8-ref b k)
  38. (u8vector-ref b k))
  39. (define (blob-u8-set! b k octet)
  40. (u8vector-set! b k octet))
  41. (define (blob-s8-ref b k)
  42. (u8->s8 (u8vector-ref b k)))
  43. (define (u8->s8 octet)
  44. (if (> octet 127)
  45. (- octet 256)
  46. octet))
  47. (define (blob-s8-set! b k val)
  48. (u8vector-set! b k (s8->u8 val)))
  49. (define (s8->u8 val)
  50. (if (negative? val)
  51. (+ val 256)
  52. val))
  53. (define (index-iterate start count low-first?
  54. unit proc)
  55. (if low-first?
  56. (let loop ((index 0)
  57. (acc unit))
  58. (if (>= index count)
  59. acc
  60. (loop (+ index 1)
  61. (proc (+ start index) acc))))
  62. (let loop ((index (- (+ start count) 1))
  63. (acc unit))
  64. (if (< index start)
  65. acc
  66. (loop (- index 1)
  67. (proc index acc))))))
  68. (define (blob-uint-ref size endness blob index)
  69. (index-iterate index size
  70. (eq? (endianness big) endness)
  71. 0
  72. (lambda (index acc)
  73. (+ (u8vector-ref blob index) (arithmetic-shift acc 8)))))
  74. (define (blob-sint-ref size endness blob index)
  75. (let ((high-byte (u8vector-ref blob
  76. (if (eq? endness (endianness big))
  77. index
  78. (- (+ index size) 1)))))
  79. (if (> high-byte 127)
  80. (- (+ 1
  81. (index-iterate index size
  82. (eq? (endianness big) endness)
  83. 0
  84. (lambda (index acc)
  85. (+ (- 255 (u8vector-ref blob index))
  86. (arithmetic-shift acc 8))))))
  87. (index-iterate index size
  88. (eq? (endianness big) endness)
  89. 0
  90. (lambda (index acc)
  91. (+ (u8vector-ref blob index) (arithmetic-shift acc 8)))))))
  92. (define (make-uint-ref size)
  93. (cut blob-uint-ref size <> <> <>))
  94. (define (make-sint-ref size)
  95. (cut blob-sint-ref size <> <> <>))
  96. (define (blob-uint-set! size endness blob index val)
  97. (index-iterate index size (eq? (endianness little) endness)
  98. val
  99. (lambda (index acc)
  100. (u8vector-set! blob index (remainder acc 256))
  101. (quotient acc 256)))
  102. (values))
  103. (define (blob-sint-set! size endness blob index val)
  104. (if (negative? val)
  105. (index-iterate index size (eq? (endianness little) endness)
  106. (- -1 val)
  107. (lambda (index acc)
  108. (u8vector-set! blob index (- 255 (remainder acc 256)))
  109. (quotient acc 256)))
  110. (index-iterate index size (eq? (endianness little) endness)
  111. val
  112. (lambda (index acc)
  113. (u8vector-set! blob index (remainder acc 256))
  114. (quotient acc 256))))
  115. (values))
  116. (define (make-uint-set! size)
  117. (cut blob-uint-set! size <> <> <> <>))
  118. (define (make-sint-set! size)
  119. (cut blob-sint-set! size <> <> <> <>))
  120. (define (make-ref/native base base-ref)
  121. (lambda (blob index)
  122. (ensure-aligned index base)
  123. (base-ref (endianness native) blob index)))
  124. (define (make-set!/native base base-set!)
  125. (lambda (blob index val)
  126. (ensure-aligned index base)
  127. (base-set! (endianness native) blob index val)))
  128. (define (ensure-aligned index base)
  129. (if (not (zero? (remainder index base)))
  130. (error "non-aligned blob access" index base)))
  131. (define blob-u16-ref (make-uint-ref 2))
  132. (define blob-u16-set! (make-uint-set! 2))
  133. (define blob-s16-ref (make-sint-ref 2))
  134. (define blob-s16-set! (make-sint-set! 2))
  135. (define blob-u16-native-ref (make-ref/native 2 blob-u16-ref))
  136. (define blob-u16-native-set! (make-set!/native 2 blob-u16-set!))
  137. (define blob-s16-native-ref (make-ref/native 2 blob-s16-ref))
  138. (define blob-s16-native-set! (make-set!/native 2 blob-s16-set!))
  139. (define blob-u32-ref (make-uint-ref 4))
  140. (define blob-u32-set! (make-uint-set! 4))
  141. (define blob-s32-ref (make-sint-ref 4))
  142. (define blob-s32-set! (make-sint-set! 4))
  143. (define blob-u32-native-ref (make-ref/native 4 blob-u32-ref))
  144. (define blob-u32-native-set! (make-set!/native 4 blob-u32-set!))
  145. (define blob-s32-native-ref (make-ref/native 4 blob-s32-ref))
  146. (define blob-s32-native-set! (make-set!/native 4 blob-s32-set!))
  147. (define blob-u64-ref (make-uint-ref 8))
  148. (define blob-u64-set! (make-uint-set! 8))
  149. (define blob-s64-ref (make-sint-ref 8))
  150. (define blob-s64-set! (make-sint-set! 8))
  151. (define blob-u64-native-ref (make-ref/native 8 blob-u64-ref))
  152. (define blob-u64-native-set! (make-set!/native 8 blob-u64-set!))
  153. (define blob-s64-native-ref (make-ref/native 8 blob-s64-ref))
  154. (define blob-s64-native-set! (make-set!/native 8 blob-s64-set!))
  155. ; Auxiliary stuff
  156. (define (blob-copy! source source-start target target-start count)
  157. (u8vector-copy! source source-start target target-start count))
  158. (define (blob-copy b)
  159. (u8vector-copy b))
  160. (define (blob=? b1 b2)
  161. (u8vector=? b1 b2))
  162. (define (blob->u8-list b)
  163. (u8vector->list b))
  164. (define (blob->s8-list b)
  165. (map u8->s8 (u8vector->list b)))
  166. (define (u8-list->blob l)
  167. (list->u8vector l))
  168. (define (s8-list->blob l)
  169. (list->u8vector (map s8->u8 l)))
  170. (define (make-blob->int-list blob-ref)
  171. (lambda (size endness b)
  172. (let ((ref (cut blob-ref size endness b <>))
  173. (length (blob-length b)))
  174. (let loop ((i 0) (r '()))
  175. (if (>= i length)
  176. (reverse r)
  177. (loop (+ i size)
  178. (cons (ref i) r)))))))
  179. (define blob->uint-list (make-blob->int-list blob-uint-ref))
  180. (define blob->sint-list (make-blob->int-list blob-sint-ref))
  181. (define (make-int-list->blob blob-set!)
  182. (lambda (size endness l)
  183. (let* ((blob (make-blob (* size (length l))))
  184. (set! (cut blob-set! size endness blob <> <>)))
  185. (let loop ((i 0) (l l))
  186. (if (null? l)
  187. blob
  188. (begin
  189. (set! i (car l))
  190. (loop (+ i size) (cdr l))))))))
  191. (define uint-list->blob (make-int-list->blob blob-uint-set!))
  192. (define sint-list->blob (make-int-list->blob blob-sint-set!))