chickadee » jiffi » struct-copier

(struct-copier ...) → proceduresyntax

Expands to an anonymous procedure that performs a shallow copy of the memory from the source struct/union, overwriting the destination struct/union. Returns the destination struct/union after copying.

Usage:

(struct-copier
  ("STRUCT_NAME" UNWRAP)
  name: NAME)  ; optional

"STRUCT_NAME" is a string containing the name of the C struct/union, exactly as it appears in C.

UNWRAP is an existing armor unwrapper procedure, such as a procedure defined with define-armor-type.

NAME is an expression that evaluates to the procedure name (usually a symbol) to show in error messages if either struct argument cannot be unwrapped. If NAME is omitted or #f, error messages will not include a procedure name.

The procedure will behave similar to this pseudo-code:

(lambda (src dest)
  (copy-bytes! (UNWRAP src NAME)
               (UNWRAP dest NAME)
               (foreign-type-size STRUCT_NAME))
  dest)
The procedure does not copy the values of extra slots you may have defined with define-armor-type.
The procedure only performs a shallow copy of the C struct/union, byte-for-byte. This is safe for C structs/unions that only hold direct values like numbers or fixed-size arrays. But, if the C struct/union has a field that holds a pointer, that field of both the source and destination structs will hold a pointer to the same address, which can cause bugs if you are not careful.

src and dest can each be an armor, pointer, locative, or blob. It is okay to be different, for example if src is a blob and dest is a pointer. See "Warning about bare data" in the Getting Started guide. The procedure signals an exception if either src or dest are null.

Example:

;; Destructive copier
(define copy-event!
  (struct-copier
   ("FOO_Event" unwrap-event)
   name: 'copy-event!))

;; Non-destructive copier based on destructive copier
(define (copy-event ev)
  (copy-event! ev (make-event/blob)))

;; Or using struct-copier directly inside a procedure
(define (copy-event ev)
  ((struct-copier
    ("FOO_Event" unwrap-event)
    name: 'copy-event)
   ev (make-event/blob)))