chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] call Chicken Scheme from C and pass a bytevector


From: Claude Marinier
Subject: Re: [Chicken-users] call Chicken Scheme from C and pass a bytevector
Date: Fri, 28 Jun 2013 08:47:09 -0400 (EDT)
User-agent: Alpine 2.02 (DEB 1266 2009-07-14)

Hi,

After considering your comments (Dan & Felix), reading the documents, and some experimentation, I have a solution.

I decided to use atomic data. I believe the C_BYTEBLOCK_BIT is for the GC and C_BYTEVECTOR_TYPE is the scheme type. The size is in bytes because it is a byte vector, right?

struct ipv4_addr_struct {
    C_header tag;
    u_int8_t octets[4];
};
typedef struct ipv4_addr_struct ipv4_addr;

#define IPv4_ADDR_SIZE ( sizeof(ipv4_addr) - sizeof(C_header) )
static const C_header IPv4_ADDR_TAG
    = IPv4_ADDR_SIZE | C_BYTEBLOCK_BIT | C_BYTEVECTOR_TYPE;

struct ipv6_addr_struct {
    C_header tag;
    u_int16_t words[8];
};
typedef struct ipv6_addr_struct ipv6_addr;

#define IPv6_ADDR_SIZE ( sizeof(ipv6_addr) - sizeof(C_header) )
static const C_header IPv6_ADDR_TAG
    = IPv6_ADDR_SIZE | C_BYTEBLOCK_BIT | C_BYTEVECTOR_TYPE;

It is used like this. There may be a better way to handle the casting.

    saddr_o = C_alloc( IPv4_ADDR_SIZE );
    saddr_s = (ipv4_addr *)saddr_o;
    saddr_s->tag = IPv4_ADDR_TAG;
    memcpy( saddr_s->octets, saddr, sizeof(saddr) );

After that, I put it and the destination address in a regular vector along with the other packet info.

The scheme packet processing code changed very little: it now uses blob->u8vector (blob->u16vector for IPv6).

(define-external (process_packet (scheme-object packet)) int
  (let ((eth-type (vector-ref packet 0)))
    (case eth-type

      [(#x0800)  ; IPv4
        (let ((addr1 (blob->u8vector (vector-ref packet 1)))
              (addr2 (blob->u8vector (vector-ref packet 2)))
              (proto (vector-ref packet 3)))

It has been running for a while and seems OK. More testing will follow.

Thanks.

--
Claude Marinier

On Fri, 28 Jun 2013, Felix wrote:

Actually, the bytes should probably be allocated in the structure,
right?

  struct ipv4_addr_struct {
    C_header tag;
    uint8_t octets[4];
  };
  typedef struct ipv4_addr_struct ipv4_addr;

  static const C_header BTREE_TAG =
    ((sizeof(ipv4_addr) - sizeof(C_header)) /
    sizeof(C_word)) | C_BYTEVECTOR_TYPE;

This would be a "blob" (or bytevector), right.


cheers,
felix



reply via email to

[Prev in Thread] Current Thread [Next in Thread]