27059e28b509b5057c251818cd55d37a3fe74a57
[clsql.git] / interfaces / clsql-uffi / clsql-uffi.cl
1 ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          clsql-uffi.cl
6 ;;;; Purpose:       Common functions for interfaces using UFFI
7 ;;;; Programmers:   Kevin M. Rosenberg
8 ;;;; Date Started:  Mar 2002
9 ;;;;
10 ;;;; $Id: clsql-uffi.cl,v 1.1 2002/03/27 07:58:42 kevin Exp $
11 ;;;;
12 ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg
13 ;;;;
14 ;;;; CLSQL users are granted the rights to distribute and use this software
15 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
16 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
17 ;;;; *************************************************************************
18
19 (declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0)))
20 (in-package :clsql-uffi)
21
22
23 (defun canonicalize-type-list (types num-fields)
24   "Ensure a field type list meets expectations"
25   (let ((length-types (length types))
26         (new-types '()))
27     (loop for i from 0 below num-fields
28           do
29           (if (>= i length-types)
30               (push t new-types) ;; types is shorted than num-fields
31               (push
32                (case (nth i types)
33                  ((:int :long :double :longlong t)
34                   (nth i types))
35                  (t
36                   t))
37                new-types)))
38     (nreverse new-types)))
39
40 (uffi:def-function "atoi"
41     ((str (* :unsigned-char)))
42   :returning :int)
43
44 (uffi:def-function "atol"
45     ((str (* :unsigned-char)))
46   :returning :long)
47
48 (uffi:def-function "atof"
49     ((str (* :unsigned-char)))
50   :returning :double)
51
52 (uffi:def-function "atol64"
53     ((str (* :unsigned-char))
54      (high32 (* :int)))
55   :returning :int)
56
57 (uffi:def-constant +2^32+ 4294967296)
58 (uffi:def-constant +2^32-1+ (1- +2^32+))
59
60 (defmacro make-64-bit-integer (high32 low32)
61   `(+ ,low32 (* ,high32 +2^32+)))
62
63 (defmacro split-64-bit-integer (int64)
64   `(values (ash ,int64 -32) (logand ,int64 +2^32-1+)))
65
66 (defun convert-raw-field (char-ptr types index)
67   (let ((type (if (listp types)
68                   (nth index types)
69                   types)))
70     (case type
71       (:int
72        (atoi char-ptr))
73       (:long
74        (atol char-ptr))
75       (:double
76        (atof char-ptr))
77       (:longlong
78        (uffi:with-foreign-object (high32-ptr :int)
79          (let ((low32 (atol64 char-ptr high32-ptr))
80                (high32 (uffi:deref-pointer high32-ptr :int)))
81            (if (zerop high32)
82                low32
83                (make-64-bit-integer high32 low32)))))
84       (otherwise
85        (uffi:convert-from-foreign-string char-ptr)))))