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
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 (declare (optimize (speed 3) (safety 0)))
27 (length-types (length types
))
28 (length-auto-list (length auto-list
)))
29 ((= i length-auto-list
)
31 (declare (fixnum length-types length-auto-list i
))
32 (if (>= i length-types
)
33 (push t new-types
) ;; types is shorter than num-fields
37 (case (nth i auto-list
)
45 (case (nth i auto-list
)
51 (if (eq :int32
(nth i auto-list
))
55 (if (eq :int64
(nth i auto-list
))
66 (uffi:def-function
"atoi"
67 ((str (* :unsigned-char
)))
70 (uffi:def-function
("strtoul" c-strtoul
)
71 ((str (* :unsigned-char
))
72 (endptr (* :unsigned-char
))
74 :returning
:unsigned-long
)
76 (uffi:def-function
"atol"
77 ((str (* :unsigned-char
)))
80 (uffi:def-function
"atof"
81 ((str (* :unsigned-char
)))
84 (uffi:def-function
"atol64"
85 ((str (* :unsigned-char
))
86 (high32 (* :unsigned-int
)))
88 :returning
:unsigned-int
)
90 (uffi:def-constant
+2^
32+ 4294967296)
91 (uffi:def-constant
+2^
64+ 18446744073709551616)
92 (uffi:def-constant
+2^
32-
1+ (1- +2^
32+))
94 (defmacro make-64-bit-integer
(high32 low32
)
95 `(if (zerop (ldb (byte 1 31) ,high32
))
96 (+ ,low32
(ash ,high32
32))
97 (- (+ ,low32
(ash ,high32
32)) +2^
64+)))
99 ;; From high to low ints
100 (defmacro make-128-bit-integer
(a b c d
)
101 `(+ ,d
(ash ,c
32) (ash ,b
64) (ash ,a
96)))
103 (defmacro split-64-bit-integer
(int64)
104 `(values (ash ,int64 -
32) (logand ,int64
+2^
32-
1+)))
106 (uffi:def-type char-ptr-def
(* :unsigned-char
))
108 (defun strtoul (char-ptr)
109 (declare (optimize (speed 3) (safety 0) (space 0))
110 (type char-ptr-def char-ptr
))
111 (c-strtoul char-ptr uffi
:+null-cstring-pointer
+ 10))
113 (defun convert-raw-field (char-ptr types index
&optional length
)
114 (declare (optimize (speed 3) (safety 0) (space 0))
115 (type char-ptr-def char-ptr
))
116 (let ((type (if (consp types
)
120 ((uffi:null-pointer-p char-ptr
)
135 (uffi:with-foreign-object
(high32-ptr :unsigned-int
)
136 (let ((low32 (atol64 char-ptr high32-ptr
))
137 (high32 (uffi:deref-pointer high32-ptr
:unsigned-int
)))
140 (make-64-bit-integer high32 low32
)))))
143 (uffi:convert-from-foreign-usb8 char-ptr length
)
144 (error "Can't return blob since length is not specified.")))
146 ;; sb-unicode still broken with converting with length, assume
147 ;; that string is null terminated
149 (uffi:convert-from-foreign-string char-ptr
:locale
:none
)
152 (uffi:convert-from-foreign-string char-ptr
:locale
:none
153 :null-terminated-p nil
155 (uffi:convert-from-foreign-string char-ptr
:locale
:none
))))))))