71 lines
2.7 KiB
Scheme
71 lines
2.7 KiB
Scheme
;;;; -*- mode: Scheme; indent-tabs-mode: nil; fill-column: 80; -*-
|
|
;;;;
|
|
;;;; Copyright (C) 2010, 2011, 2013, 2015 Free Software Foundation, Inc.
|
|
;;;;
|
|
;;;; This program is free software: you can redistribute it and/or modify
|
|
;;;; it under the terms of the GNU General Public License as published by
|
|
;;;; the Free Software Foundation, either version 3 of the License, or
|
|
;;;; (at your option) any later version.
|
|
;;;;
|
|
;;;; This program is distributed in the hope that it will be useful,
|
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
;;;; GNU General Public License for more details.
|
|
;;;;
|
|
;;;; You should have received a copy of the GNU General Public License
|
|
;;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
(define *writers* (@@ (system foreign) *writers*))
|
|
(define *readers* (@@ (system foreign) *readers*))
|
|
|
|
(define (write-c-struct* bv offset types vals)
|
|
(let lp ((offset offset) (types types) (vals vals))
|
|
(cond
|
|
((not (pair? types))
|
|
(or (null? vals)
|
|
(throw 'invalid-arg "write-c-struct*" vals)))
|
|
((not (pair? vals))
|
|
(or (padding? vals)
|
|
(throw 'invalid-arg "write-c-struct*" types)))
|
|
(else
|
|
;; alignof will error-check
|
|
(let* ((type (car types))
|
|
(offset (align offset (alignof* type))))
|
|
(cond ((pair? type)
|
|
(write-c-struct* bv offset (car types) (car vals)))
|
|
((not (pad? type))
|
|
((assv-ref *writers* type) bv offset (car vals))))
|
|
(lp (+ offset (sizeof* type)) (cdr types)
|
|
(if (pad? type) vals (cdr vals))))))))
|
|
|
|
(define (read-c-struct* bv offset types)
|
|
(let lp ((offset offset) (types types) (vals '()))
|
|
(cond
|
|
((not (pair? types))
|
|
(reverse vals))
|
|
(else
|
|
;; alignof will error-check
|
|
(let* ((type (car types))
|
|
(offset (align offset (alignof* type))))
|
|
(lp (+ offset (sizeof* type)) (cdr types)
|
|
(cond ((pair? type)
|
|
(cons (read-c-struct* bv offset (car types)) vals))
|
|
((pad? type) vals)
|
|
(else
|
|
(cons ((assv-ref *readers* type) bv offset) vals)))))))))
|
|
|
|
(define* (make-c-struct* types vals #:rest union-references)
|
|
(let* ((types (replace-unions types union-references))
|
|
(bv (make-bytevector (sizeof* types) 0)))
|
|
(write-c-struct* bv 0 types vals)
|
|
(bytevector->pointer bv)))
|
|
|
|
(define* (parse-c-struct* foreign types #:rest union-references)
|
|
(let* ((types (replace-unions types union-references))
|
|
(size (fold (lambda (type total)
|
|
(+ (sizeof* type)
|
|
(align total (alignof* type))))
|
|
0
|
|
types)))
|
|
(read-c-struct* (pointer->bytevector foreign size) 0 types)))
|