r1683: *** empty log message ***
[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.2 2002/03/27 12:09:39 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 auto-list)
24   "Ensure a field type list meets expectations"
25   (let ((length-types (length types))
26         (new-types '()))
27     (loop for i from 0 below (length auto-list)
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
34                   (case (nth i auto-list)
35                     (:int32
36                      :int32)
37                     (:int64
38                      :int64)
39                     (t
40                      t)))
41                  (:double
42                   (case (nth i auto-list)
43                     (:double
44                      :double)
45                     (t
46                      t)))
47                  (t
48                   t))
49                new-types)))
50     (nreverse new-types)))
51
52 (uffi:def-function "atoi"
53     ((str (* :unsigned-char)))
54   :returning :int)
55
56 (uffi:def-function "atol"
57     ((str (* :unsigned-char)))
58   :returning :long)
59
60 (uffi:def-function "atof"
61     ((str (* :unsigned-char)))
62   :returning :double)
63
64 (uffi:def-function "atol64"
65     ((str (* :unsigned-char))
66      (high32 (* :int)))
67   :returning :int)
68
69 (uffi:def-constant +2^32+ 4294967296)
70 (uffi:def-constant +2^32-1+ (1- +2^32+))
71
72 (defmacro make-64-bit-integer (high32 low32)
73   `(+ ,low32 (* ,high32 +2^32+)))
74
75 (defmacro split-64-bit-integer (int64)
76   `(values (ash ,int64 -32) (logand ,int64 +2^32-1+)))
77
78 (defun convert-raw-field (char-ptr types index)
79   (let ((type (if (listp types)
80                   (nth index types)
81                   types)))
82     (case type
83       (:double
84        (atof char-ptr))
85       (:int32
86        (atoi char-ptr))
87       (:int64
88        (uffi:with-foreign-object (high32-ptr :int)
89          (let ((low32 (atol64 char-ptr high32-ptr))
90                (high32 (uffi:deref-pointer high32-ptr :int)))
91            (if (zerop high32)
92                low32
93                (make-64-bit-integer high32 low32)))))
94       (t
95        (uffi:convert-from-foreign-string char-ptr)))))