/[cffi-objects]/freeable.lisp
ViewVC logotype

Diff of /freeable.lisp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 13 by rklochkov, Sat Dec 22 19:24:45 2012 UTC revision 18 by rklochkov, Sat Jan 12 21:26:46 2013 UTC
# Line 30  For uniformity with CFFI :string I chose Line 30  For uniformity with CFFI :string I chose
30  \begin{itemize}  \begin{itemize}
31  \item [[freeable-base]] introduces all necessary fields and handlers  \item [[freeable-base]] introduces all necessary fields and handlers
32  \item [[freeable]] have ready cffi-translator methods  \item [[freeable]] have ready cffi-translator methods
33    \end{itemize}
34  |#  |#
35    
36  (define-foreign-type freeable-base ()  (define-foreign-type freeable-base ()
# Line 55  how to free particular type: [[free-ptr] Line 56  how to free particular type: [[free-ptr]
56  This generic describes, how to free an object with CFFI type [[type]] and  This generic describes, how to free an object with CFFI type [[type]] and
57  pointer [[ptr]]. As [[type]] should be a symbol, you should specialize  pointer [[ptr]]. As [[type]] should be a symbol, you should specialize
58  this generic with EQL specifier if your objects shouldn't be freed with  this generic with EQL specifier if your objects shouldn't be freed with
59  [[foreign-free].  [[foreign-free]].
60    
61  One can ask, why normal specializer by type of object and [[object] as  One can ask, why normal specializer by type of object and [[object]] as
62  a first parameter is not used. Such strange API is developed,  a first parameter is not used. Such strange API is developed,
63  because [[free-ptr]] is used in [[trivial-garbage:finalize]] and in some  because [[free-ptr]] is used in [[trivial-garbage:finalize]] and in some
64  implementation (for example, SBCL) finalizer shouldn't have reference  implementation (for example, SBCL) finalizer shouldn't have reference
# Line 69  redefine [[free-sent-ptr]] and [[free-re Line 70  redefine [[free-sent-ptr]] and [[free-re
70    
71  (defgeneric free-ptr (type ptr)  (defgeneric free-ptr (type ptr)
72    (:documentation "Called to free ptr, unless overriden free-sent-ptr    (:documentation "Called to free ptr, unless overriden free-sent-ptr
73  or free-returned-ptr. TYPE should be specialized with EQL")  or free-returned-ptr. TYPE should be symbol and be specialized with EQL")
74    (:method (type ptr) (foreign-free ptr)))    (:method (type ptr) (foreign-free ptr)))
75    
76  ;;;[ <generic free-sent-ptr>  ;;;[ <generic free-sent-ptr>
77    
78    #|<doc>
79    This generic describes, how to free an object with CFFI type [[type]] and
80    pointer [[ptr]] after sending to foreign space. It has the same parameters
81    as [[cffi:free-translated-object]]. If complex foreign type has additional
82    conditionals or any additional actions when freeing, specialize it on you type.
83    
84    Please, don't call it directly. Use [[free-sent-if-needed]] instead.
85    |#
86    
87  (defgeneric free-sent-ptr (cffi-type ptr param)  (defgeneric free-sent-ptr (cffi-type ptr param)
88      (:documentation "Will be called in free-translated-object.
89    CFFI-TYPE: type defined with define-foreign-type.
90    PTR: foreign pointer
91    PARAM: third parameter of free-translated-object ==
92           returned second value of translate-to-foreign.")
93    (:method ((cffi-type freeable-base) ptr param)    (:method ((cffi-type freeable-base) ptr param)
94      (unless (null-pointer-p ptr)      (unless (null-pointer-p ptr)
95        (free-ptr (type-of cffi-type) ptr))))        (free-ptr (type-of cffi-type) ptr))))
96    
97  ;;;[ <generic free-returned-ptr>  ;;;[ <generic free-returned-ptr>
98    
99    #|<doc>
100    This generic describes, how to free an object with CFFI type [[type]] and
101    pointer [[ptr]] after receiving from foreign space. It has the same parameters
102    as [[cffi:translate-to-foreign]]. If complex foreign type has additional
103    conditionals or any additional actions when freeing, specialize it on you type.
104    
105    Please, don't call it directly. Use [[free-returned-if-needed]] instead.
106    |#
107    
108    
109  (defgeneric free-returned-ptr (cffi-type ptr)  (defgeneric free-returned-ptr (cffi-type ptr)
110      (:documentation "Will be called in translate-from-foreign after conversion.
111    CFFI-TYPE: type defined with define-foreign-type.
112    PTR: foreign pointer")
113    (:method ((cffi-type freeable-base) ptr)    (:method ((cffi-type freeable-base) ptr)
114      (unless (null-pointer-p ptr)      (unless (null-pointer-p ptr)
115        (free-ptr (type-of cffi-type) ptr))))        (free-ptr (type-of cffi-type) ptr))))
# Line 89  or free-returned-ptr. TYPE should be spe Line 117  or free-returned-ptr. TYPE should be spe
117  ;;;[ <function free-sent-if-needed  ;;;[ <function free-sent-if-needed
118    
119  (defun free-sent-if-needed (cffi-type ptr param)  (defun free-sent-if-needed (cffi-type ptr param)
120      "This function should be placed in appropriate place of
121    free-translated-object"
122    (when (fst-free-to-foreign-p cffi-type)    (when (fst-free-to-foreign-p cffi-type)
123      (free-sent-ptr cffi-type ptr param)))      (free-sent-ptr cffi-type ptr param)))
124    
125  ;;;[ <function free-returned-if-needed  ;;;[ <function free-returned-if-needed
126    
127  (defun free-returned-if-needed (cffi-type ptr)  (defun free-returned-if-needed (cffi-type ptr)
128      "This function should be placed in appropriate place of
129    translate-from-foreign"
130    (when (fst-free-from-foreign-p cffi-type)    (when (fst-free-from-foreign-p cffi-type)
131      (free-returned-ptr cffi-type ptr)))      (free-returned-ptr cffi-type ptr)))
132    
133  ;;;[ <class freeable>  ;;;[ <class freeable>
134    
135    #|<doc>
136    This is standard base class for freeable pointers. If you happy with
137    default free algorithm, which implies, that [[free-sent-ptr]] is called after
138    [[free-translated-object]] when type described with [[:free-to-foreign t]]
139    and [[free-returned-ptr]] is called when type described with
140    [[:free-from-foreign t]] after [[translate-from-foreign]].
141    
142    If you need more complicated logic (for example, to free object in
143    translate-from-foreign, not after), you should inherit your class from
144    [[freeable-base]] and
145    call [[free-sent-if-needed]] from [[free-translated-object]]
146    and [[free-returned-if-needed]] from [[translate-from-foreign]].
147    |#
148    
149  (defclass freeable (freeable-base) ()  (defclass freeable (freeable-base) ()
150    (:documentation "Mixing to auto-set translators"))    (:documentation "Mixing to auto-set translators"))
151    
   
   
152  (defmethod free-translated-object :after (ptr (type freeable) param)  (defmethod free-translated-object :after (ptr (type freeable) param)
153    (free-sent-if-needed type ptr param))    (free-sent-if-needed type ptr param))
154    
# Line 113  or free-returned-ptr. TYPE should be spe Line 157  or free-returned-ptr. TYPE should be spe
157    
158  ;;;[ <class freeable-out>  ;;;[ <class freeable-out>
159    
160    #|<doc>
161    This is standard base class for objects, that should be copied back
162    to lisp after foreign function: so-called ``out parameters''.
163    
164    For every class, inherited from [[freeable-out]], you must
165    implement method [[copy-from-foreign]].
166    
167    Then user of your class may set [[:out t]] in initargs for your class
168    and be sure, that all changed data will be copied back to the variables.
169    
170    When implementing [[translate-to-foreign]] you must return (values ptr value),
171    because second value will be passed to [[free-translated-object]], and then
172    as PLACE to [[copy-from-foreign]].
173    |#
174    
175  (define-foreign-type freeable-out (freeable)  (define-foreign-type freeable-out (freeable)
176    ((out :accessor object-out :initarg :out :initform nil    ((out :accessor object-out :initarg :out :initform nil
177          :documentation "This is out param (for fill in foreign side)"))          :documentation "This is out param (for fill in foreign side)"))
178    (:documentation "For returning data in out params.    (:documentation "For returning data in out params.
179  If OUT is t, then translate-to-foreign MUST return (values ptr place)"))  If OUT is t, then translate-to-foreign MUST return (values ptr place)"))
180    
181  (defgeneric copy-from-foreign (type ptr place)  ;;;[ <generic copy-from-foreign>
182    (:documentation "Transfers data from pointer PTR to PLACE"))  
183    #|<doc>
184    This generic must have an implementation for every class inherited from [[freeable-out]].
185    |#
186    
187    (defgeneric copy-from-foreign (cffi-type ptr place)
188      (:documentation "Transfers data from pointer PTR to PLACE.
189    CFFI-TYPE: type defined with define-foreign-type.
190    PTR: foreign pointer
191    PLACE: third parameter of free-translated-object ==
192           returned second value of translate-to-foreign"))
193    
194  (defmethod free-translated-object :before (ptr (type freeable-out) place)  (defmethod free-translated-object :before (ptr (type freeable-out) place)
195    (when (object-out type)    (when (object-out type)

Legend:
Removed from v.13  
changed lines
  Added in v.18

  ViewVC Help
Powered by ViewVC 1.1.5