#lang scheme/base
(require scheme/foreign "libcrypto.ss" "macros.ss" "error.ss")
(provide (all-defined-out))
(define/ffi (RAND_bytes _pointer _uint) -> _int : check-error)
(define/ffi (RAND_pseudo_bytes _pointer _uint) -> _int : check-error)
(define/ffi (RAND_add (bs : _bytes) (len : _int = (bytes-length bs)) _int))
(define/ffi (RAND_seed (bs : _bytes) (len : _int = (bytes-length bs))))
(define/ffi (RAND_status) -> _bool)
(define/ffi (RAND_load_file _path _long) -> _int)
(define/ffi (RAND_write_file _path) -> _int)
(define/ffi (RAND_file_name) -> _path)
(define-rule (define-rand rand rand! randf)
  (begin
    (define* rand!
      ((bs) (randf bs (bytes-length bs)))
      ((bs start)
       (check-output-range rand! bs start (bytes-length bs))
       (randf (ptr-add bs start) (- (bytes-length bs) start)))
      ((bs start end)
       (check-output-range rand! bs start end)
       (randf (ptr-add bs start) (- end start))))
    (define (rand k)
      (let ((bs (make-bytes k)))
        (randf bs k)
        bs))
    (put-symbols! rand.symbols rand rand!)))
(define-symbols rand.symbols
  (RAND_status random-rnd-status)
  (RAND_add random-rnd-add)
  (RAND_seed random-rnd-seed)
  (RAND_load_file random-rnd-read)
  (RAND_write_file random-rnd-write)
  (RAND_file_name random-rnd-filename))
(define-rand random-bytes random-bytes! RAND_bytes)
(define-rand pseudo-random-bytes pseudo-random-bytes! RAND_pseudo_bytes)
(define-provider provide-rand rand.symbols)