-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtext-objects.lisp
188 lines (163 loc) · 7.76 KB
/
text-objects.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FM-PLUGIN-TOOLS; Base: 10 -*-
;;; $Header: /usr/local/cvsrep/fm-plugin-tools/text-objects.lisp,v 1.18 2010/07/22 09:38:06 edi Exp $
;;; Copyright (c) 2006-2010, Dr. Edmund Weitz. All rights reserved.
;;; Redistribution and use in source and binary forms, with or without
;;; modification, are permitted provided that the following conditions
;;; are met:
;;; * Redistributions of source code must retain the above copyright
;;; notice, this list of conditions and the following disclaimer.
;;; * Redistributions in binary form must reproduce the above
;;; copyright notice, this list of conditions and the following
;;; disclaimer in the documentation and/or other materials
;;; provided with the distribution.
;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(in-package :fm-plugin-tools)
#+:macosx
(defun fm-text-assign-unicode (self string)
"This is a wrapper around FM-TEXT-ASSIGN-UNICODE% which sets up its
second argument by converting the Lisp string STRING to an array of
16-bit values representing a Unicode C string.
Only needed on Mac OS X as a workaround because :EF-WC-STRING can't be
used."
(let ((length (length string)))
;; convert the string
(with-dynamic-foreign-objects ((ptr :unsigned-short :nelems (1+ length)))
;; use Unicode code points
(dotimes (index length)
(setf (dereference ptr :index index)
(char-code (char string index))))
;; delimiter for C string
(setf (dereference ptr :index length) 0)
;; call the "real" function
(fm-text-assign-unicode% self ptr))))
(defun fm-text-get-string (self &key (position 0) size)
"Returns, as a Lisp string, the substring of length SIZE
beginning at POSITION from the string represented by the
FileMaker Text object at SELF."
(when (or (null size)
(= size +k-size-end+))
(setq size (fm-text-get-size self)))
(convert-line-endings
(with-dynamic-foreign-objects ()
(let ((buffer (allocate-dynamic-foreign-object :type #+:win32 :wchar-t #-:win32 :unsigned-short
:nelems (1+ size))))
(fm-text-get-unicode self buffer position size)
(setf (dereference buffer :index size) #\Null)
#+:win32
(convert-from-foreign-string buffer :external-format :unicode)
#-:win32
(loop with string = (make-string size :element-type 'lw:simple-char)
for index from 0 below size
do (setf (char string index)
(code-char (dereference buffer :index index)))
finally (return string))))))
(defmacro with-text ((ptr &optional string) &body body)
"Executes BODY with PTR bound to a fresh Text object optionally
intialized to the Lisp string STRING. The object is guaranteed
to be deleted after the execution of BODY."
(rebinding (string)
`(let (,ptr)
(unwind-protect
(progn
(setq ,ptr (fm-text-constructor1))
(when ,string
(fm-text-assign-unicode ,ptr ,string))
,@body)
(when ,ptr
(ignore-errors
(fm-text-delete ,ptr)))))))
(defclass text-object (fm-object)
()
(:documentation "A TEXT-OBJECT is a Lisp object which is a
proxy for a FileMaker `Text' object."))
(defmethod fm-delete ((text-object text-object))
"Deletes the Text \(C++) object which is proxied by
TEXT-OBJECT."
(fm-text-delete (pointer text-object)))
(defun make-text-object (&optional (string ""))
"Creates and returns a TEXT-OBJECT representing the string
STRING."
(let (ptr)
(handler-bind
((error (lambda (cond)
(declare (ignore cond))
(when ptr
(ignore-errors
(fm-text-delete ptr))))))
(setq ptr (fm-text-constructor1))
(fm-text-assign-unicode ptr string)
(make-instance 'text-object :pointer ptr))))
(defmethod size ((text-object text-object))
"Returns the size of TEXT-OBJECT."
(fm-text-get-size (pointer text-object)))
(defmethod as-string ((text-object text-object) &key (position 0) size)
"Returns the string represented by TEXT-OBJECT as a Lisp
string. Optionally you can return only the SIZE characters
beginning at POSITION."
(fm-text-get-string (pointer text-object)
:position position
:size size))
(defmethod (setf as-string) ((new-value string) (text-object text-object) &key)
"Sets the string represented by TEXT-OBJECT to NEW-VALUE, a
Lisp string."
(fm-text-assign-unicode (pointer text-object) new-value)
new-value)
(defmethod set-text ((text-object text-object) (other-text-object text-object)
&key (position 0) (size +k-size-end+))
"Sets TEXT-OBJECT to be the part of size SIZE starting at
position POSITION of OTHER-TEXT-OBJECT."
(fm-text-set-text (pointer text-object) (pointer other-text-object) position size)
text-object)
(defmethod append-text ((text-object text-object) (other-text-object text-object)
&key (position 0) (size +k-size-end+))
"Appends to the end of TEXT-OBJECT the part of size SIZE
starting at position POSITION of OTHER-TEXT-OBJECT."
(fm-text-append-text (pointer text-object) (pointer other-text-object) position size)
text-object)
(defmethod insert-text ((text-object text-object) (other-text-object text-object)
&key (position 0))
"Inserts OTHER-TEXT-OBJECT at position POSITION of TEXT-OBJECT."
(fm-text-insert-text (pointer text-object) (pointer other-text-object) position)
text-object)
(defmethod delete-text ((text-object text-object) position
&key (size +k-size-end+))
"Deletes the part of TEXT-OBJECT of size SIZE beginning at
position POSITION."
(fm-text-delete-text (pointer text-object) position size)
text-object)
(defmethod get-style ((text-object text-object) position)
"Returns the character style \(as a STYLE-OBJECT) of the
character at position POSITION of TEXT-OBJECT."
(let ((style-object (make-style-object)))
(fm-text-get-style (pointer text-object) (pointer style-object) position)
style-object))
(defmethod get-default-style ((text-object text-object))
"Returns the default character style \(as a STYLE-OBJECT) of
TEXT-OBJECT."
(let ((style-object (make-style-object)))
(fm-text-get-default-style (pointer text-object) (pointer style-object))
style-object))
(defmethod set-style ((text-object text-object) (style-object style-object)
position size)
"Sets the character style of the SIZE characters of TEXT-OBJECT
beginning at position POSITION to STYLE-OBJECT."
(fm-text-set-style (pointer text-object) (pointer style-object) position size)
text-object)
(defmethod remove-style ((text-object text-object) (style-object style-object))
"Removes the character style STYLE-OBJECT from TEXT-OBJECT."
(fm-text-remove-style (pointer text-object) (pointer style-object))
text-object)
(defmethod reset-all-style-buffers ((text-object text-object))
"Removes all characters styles from TEXT-OBJECT."
(fm-text-reset-all-style-buffers (pointer text-object))
text-object)