1 ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
5 ;;;; Name: clsql-uffi.cl
6 ;;;; Purpose: Common functions for interfaces using UFFI
7 ;;;; Programmers: Kevin M. Rosenberg
8 ;;;; Date Started: Mar 2002
10 ;;;; $Id: clsql-uffi.lisp,v 1.28 2003/05/29 05:19:50 kevin Exp $
12 ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg
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 ;;;; *************************************************************************
19 (in-package #:clsql-uffi)
22 (defun canonicalize-type-list (types auto-list)
23 "Ensure a field type list meets expectations"
24 (let ((length-types (length types))
26 (loop for i from 0 below (length auto-list)
28 (if (>= i length-types)
29 (push t new-types) ;; types is shorted than num-fields
33 (case (nth i auto-list)
41 (case (nth i auto-list)
47 (if (eq :int32 (nth i auto-list))
51 (if (eq :int64 (nth i auto-list))
57 (nreverse new-types)))
59 (uffi:def-function "atoi"
60 ((str (* :unsigned-char)))
63 (uffi:def-function "atol"
64 ((str (* :unsigned-char)))
67 (uffi:def-function "atof"
68 ((str (* :unsigned-char)))
71 (uffi:def-function "atol64"
72 ((str (* :unsigned-char))
74 :returning :unsigned-int)
76 (uffi:def-constant +2^32+ 4294967296)
77 (uffi:def-constant +2^32-1+ (1- +2^32+))
79 (defmacro make-64-bit-integer (high32 low32)
80 `(+ ,low32 (* ,high32 +2^32+)))
82 (defmacro split-64-bit-integer (int64)
83 `(values (ash ,int64 -32) (logand ,int64 +2^32-1+)))
85 (defvar +ascii-N-value+ (char-code #\N))
86 (defvar +ascii-U-value+ (char-code #\U))
88 (uffi:def-type char-ptr-def (* :unsigned-char))
90 (defun char-ptr-points-to-null (char-ptr)
91 "Returns T if foreign character pointer refers to 'NULL' string. Only called for numeric entries"
92 ;; Uses short cut and returns T if first character is #\N. It should
93 ;; never be non-numeric
94 (declare (type char-ptr-def char-ptr))
95 (let ((char (uffi:ensure-char-character
96 (uffi:deref-pointer char-ptr :char))))
97 (char-equal char #\N)))
99 (defun convert-raw-field (char-ptr types index)
100 (let ((type (if (listp types)
104 ((and (or (eq type :double) (eq type :int32) (eq type :int)
106 (char-ptr-points-to-null char-ptr))
115 (uffi:with-foreign-object (high32-ptr :int)
116 (let ((low32 (atol64 char-ptr high32-ptr))
117 (high32 (uffi:deref-pointer high32-ptr :int)))
120 (make-64-bit-integer high32 low32)))))
122 #+(or allegro lispworks) (native-to-string char-ptr) ;; optimized
123 #-(or allegro lispworks) (uffi:convert-from-foreign-string char-ptr)))))))
126 (uffi:def-function "strlen"
127 ((str (* :unsigned-char)))
128 :returning :unsigned-int)
130 #+(or lispworks (and allegro ics))
131 (defun native-to-string (s)
132 (declare (optimize (speed 3) (space 0) (safety 0) (compilation-speed 0))
133 (type char-ptr-def s))
134 (let* ((len (strlen s))
135 (str (make-string len)))
136 (declare (fixnum len)
142 (code-char (uffi:deref-array s '(:array :unsigned-char) i)))
146 #+(and allegro (not ics))
147 (defun native-to-string (s)
148 (declare (optimize (speed 3) (space 0) (safety 0) (compilation-speed 0))
149 (type char-ptr-def s))
150 (let* ((len (strlen s))
152 (str (make-string len)))
153 (declare (fixnum len)
154 (type (simple-array (signed-byte 32) (*)) str))
158 (setf (aref (the (simple-array (signed-byte 32) (*)) str) i)
159 (uffi:deref-array s '(:array :int) i))
164 (setf (aref (the (simple-array (signed-byte 8) (*)) str) i)
165 (uffi:deref-array s '(:array :unsigned-char) i))