Modified Files:
[elisp/tamago.git] / egg / sj3rpc.el
1 ;;; egg/sj3rpc.el --- SJ3 Support (low level interface) in Egg
2 ;;;                   Input Method Architecture
3
4 ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc
5
6 ;; Author: NIIBE Yutaka <gniibe@chroot.org>
7
8 ;; Maintainer: TOMURA Satoru <tomura@etl.go.jp>
9
10 ;; Keywords: mule, multilingual, input method
11
12 ;; This file is part of EGG.
13
14 ;; EGG is free software; you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; any later version.
18
19 ;; EGG is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 ;; GNU General Public License for more details.
23
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
26 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
27 ;; Boston, MA 02111-1307, USA.
28
29 ;;; Commentary:
30
31
32 ;;; Code:
33
34 (defvar sj3-server-version 2
35   "*Major version number of SJ3 server.")
36
37 (defvar sj3-server-coding-system 'shift_jis
38   "*Coding system used when decoding and encoding of I/O operation with
39 SJ3 server.  Valid coding systems are depend on the server spec.")
40
41 (eval-when-compile
42   (require 'egg-com)
43   (defmacro sj3-sjis-p ()
44     '(eq 'coding-category-sjis (coding-system-category
45                                 sj3-server-coding-system)))
46   (defmacro sj3-const (c)
47     (cond ((eq c 'OPEN)            1)
48           ((eq c 'CLOSE)           2)
49           ((eq c 'DICADD)         11)
50           ((eq c 'DICDEL)         12)
51           ((eq c 'OPENSTDY)       21)
52           ((eq c 'CLOSESTDY)      22)
53           ((eq c 'STDYSIZE)       23)
54           ((eq c 'LOCK)           31)
55           ((eq c 'UNLOCK)         32)
56           ((eq c 'BEGIN)   '(if (sj3-sjis-p) 41 111))
57           ((eq c 'TANCONV) '(if (sj3-sjis-p) 51 112))
58           ((eq c 'KOUHO)   '(if (sj3-sjis-p) 54 115))
59           ((eq c 'KOUHOSU) '(if (sj3-sjis-p) 55 116))
60           ((eq c 'STDY)           61)
61           ((eq c 'CLSTDY)  '(if (sj3-sjis-p) 62 117))
62           ((eq c 'WREG)    '(if (sj3-sjis-p) 71 118))
63           ((eq c 'WDEL)    '(if (sj3-sjis-p) 72 119))
64           ((eq c 'MKDIC)          81)
65           ((eq c 'MKSTDY)         82)
66           ((eq c 'MKDIR)          83)
67           ((eq c 'ACCESS)         84)
68           ((eq c 'WSCH)    '(if (sj3-sjis-p) 91 120))
69           ((eq c 'WNSCH)   '(if (sj3-sjis-p) 92 121))
70           ((eq c 'VERSION)       103)
71           (t (error "No such constant")))))
72
73 ;; XXX
74 (defconst sj3rpc-error-message (vector ))
75
76 (defun sj3rpc-get-error-message (errno)
77   (or (and (>= errno 0)
78            (< errno (length sj3rpc-error-message))
79            (aref sj3rpc-error-message errno))
80       (format "#%d" errno)))
81
82 (defmacro sj3rpc-call-with-environment (e vlist send-expr &rest receive-exprs)
83   (let ((v (append
84             `((proc (sj3env-get-proc ,e)))
85             vlist)))
86     (list
87      'let v
88      (append
89         `(save-excursion
90            (set-buffer (process-buffer proc))
91            (erase-buffer)
92            ,send-expr
93            (process-send-region proc (point-min) (point-max))
94            (goto-char (prog1 (point) (accept-process-output proc))))
95         receive-exprs))))
96
97 (defmacro sj3rpc-unpack-mb-string ()
98   '(let ((start (point)))
99      (while (not (search-forward "\0" nil t))
100        (comm-accept-process-output))
101      (decode-coding-string (buffer-substring start (1- (point)))
102                            sj3-server-coding-system)))
103 \f
104 (defun sj3rpc-open (proc myhostname username)
105   "Open the session.  Return 0 on success, error code on failure."
106   (comm-call-with-proc proc (result)
107     (comm-format (u u s s s) (sj3-const OPEN) sj3-server-version
108                  myhostname username
109                  ;; program name
110                  (format "%d.emacs-egg" (emacs-pid)))
111     (comm-unpack (i) result)
112     (if (= result -2)
113         0
114       result)))
115
116 (defun sj3rpc-close (proc)
117   (comm-call-with-proc proc (result)
118     (comm-format (u) (sj3-const CLOSE))
119     (comm-unpack (i) result)
120     result))
121
122 (defun sj3rpc-get-stdy-size (proc)
123   "Return STDYSIZE of SJ3 server.  On failure, return error code."
124   (comm-call-with-proc proc (result)
125     (comm-format (u) (sj3-const STDYSIZE))
126     (comm-unpack (u) result)
127     (if (/= result 0)
128         (- result)                      ; failure
129       (comm-unpack (u) result)
130       result)))
131
132 (defsubst sj3rpc-get-stdy (proc)
133   (let ((n 0)
134         (stdy (make-vector sj3-stdy-size 0)))
135     (while (< n sj3-stdy-size)
136       (comm-unpack (b) r)
137       (aset stdy n r)
138       (setq n (1+ n)))
139     stdy))
140
141 (defun sj3rpc-begin (env yomi)
142   "Begin conversion."
143   (let ((yomi-ext (encode-coding-string yomi sj3-server-coding-system))
144         (p 0)
145         len source converted stdy bunsetsu-list bl)
146     (sj3rpc-call-with-environment env (result)
147       (comm-format (u s) (sj3-const BEGIN) yomi-ext)
148       (comm-unpack (u) result)
149       (if (/= result 0)
150           (- result)                    ; failure
151         (comm-unpack (u) result)        ; skip
152         (while (progn
153                  (comm-unpack (b) len)
154                  (> len 0))
155           (setq stdy (sj3rpc-get-stdy proc))
156           (setq converted (sj3rpc-unpack-mb-string))
157           (setq source (decode-coding-string (substring yomi-ext p (+ p len))
158                                              sj3-server-coding-system)
159                 p (+ p len))
160           (let ((bl1 (cons (sj3-make-bunsetsu env
161                                               source converted nil stdy) nil)))
162             (if bl
163                 (setq bl (setcdr bl bl1))
164               (setq bunsetsu-list (setq bl bl1)))))
165         bunsetsu-list))))
166
167 (defun sj3rpc-open-dictionary (proc dict-file-name password)
168   (comm-call-with-proc proc (result)
169     (comm-format (u s s) (sj3-const DICADD) dict-file-name password)
170     (comm-unpack (u) result)
171     (if (/= result 0)
172         (- result)                      ; failure
173       (comm-unpack (u) result)
174       result)))
175
176 (defun sj3rpc-close-dictionary (proc dict-no)
177   (comm-call-with-proc proc (result)
178     (comm-format (u u) (sj3-const DICDEL) dict-no)
179     (comm-unpack (i) result)
180     result))
181
182 (defun sj3rpc-make-dictionary (proc dict-name)
183   (comm-call-with-proc proc (result)
184     (comm-format (u s u u u) (sj3-const MKDIC) dict-name
185                  2048  ; Index length
186                  2048  ; Length
187                  256   ; Number
188                  )
189     (comm-unpack (i) result)
190     result))
191
192 (defun sj3rpc-open-stdy (proc stdy-name)
193   (comm-call-with-proc proc (result)
194     (comm-format (u s s) (sj3-const OPENSTDY) stdy-name "")
195     (comm-unpack (i) result)
196     result))
197
198 (defun sj3rpc-close-stdy (proc)
199   (comm-call-with-proc proc (result)
200     (comm-format (u) (sj3-const CLOSESTDY))
201     (comm-unpack (i) result)
202     result))
203
204 (defun sj3rpc-make-stdy (proc stdy-name)
205   (comm-call-with-proc proc (result)
206     (comm-format (u s u u u) (sj3-const MKSTDY) stdy-name
207                  2048  ; Number
208                  1     ; Step
209                  2048  ; Length
210                  )
211     (comm-unpack (i) result)
212     result))
213
214 (defun sj3rpc-make-directory (proc name)
215   (comm-call-with-proc proc (result)
216     (comm-format (u s) (sj3-const MKDIR) name)
217     (comm-unpack (i) result)
218     result))
219
220 (defun sj3rpc-get-bunsetsu-candidates-sub (proc env yomi yomi-ext len n)
221   (let ((i 0)
222         stdy converted bunsetsu bl bunsetsu-list cylen rest)
223     (comm-call-with-proc-1 proc (result)
224       (comm-format (u u s) (sj3-const KOUHO) len yomi-ext)
225       (comm-unpack (u) result)
226       (if (/= result 0)
227           (- result)                    ; failure
228         (while (< i n)
229           (comm-unpack (u) cylen)
230           (setq stdy (sj3rpc-get-stdy proc))
231           (setq converted (sj3rpc-unpack-mb-string))
232           (setq rest (decode-coding-string (substring yomi-ext cylen)
233                                            sj3-server-coding-system))
234           (setq bunsetsu (sj3-make-bunsetsu env yomi converted rest stdy))
235           (if bl
236               (setq bl (setcdr bl (cons bunsetsu nil)))
237             (setq bunsetsu-list (setq bl (cons bunsetsu nil))))
238           (setq i (1+ i)))
239         (setq bunsetsu (sj3-make-bunsetsu env yomi yomi nil nil))
240         (setq bl (setcdr bl (cons bunsetsu nil)))
241         (setq bunsetsu
242               (sj3-make-bunsetsu env yomi (japanese-katakana yomi) nil nil))
243         (setq bl (setcdr bl (cons bunsetsu nil)))
244         bunsetsu-list))))
245
246 (defun sj3rpc-get-bunsetsu-candidates (env yomi)
247   (let* ((yomi-ext (encode-coding-string yomi sj3-server-coding-system))
248          (len (length yomi-ext)))
249     (sj3rpc-call-with-environment env (result)
250       (comm-format (u u s) (sj3-const KOUHOSU) len yomi-ext)
251       (comm-unpack (u) result)
252       (if (/= result 0)
253           (- result)                    ; failure
254         (comm-unpack (u) result)
255         (if (= result 0)
256             (list (sj3-make-bunsetsu env yomi yomi nil nil)) ; XXX
257           (sj3rpc-get-bunsetsu-candidates-sub proc env
258                                               yomi yomi-ext len result))))))
259
260 (defun sj3rpc-tanbunsetsu-conversion (env yomi)
261   (let* ((yomi-ext (encode-coding-string yomi sj3-server-coding-system))
262         (len (length yomi-ext)) cylen stdy converted rest)
263     (sj3rpc-call-with-environment env (result)
264       (comm-format (u u s) (sj3-const TANCONV) len yomi-ext)
265       (comm-unpack (u) result)
266       (if (/= result 0)
267           (- result)
268         (comm-unpack (u) cylen)
269         (setq stdy (sj3rpc-get-stdy proc))
270         (setq converted (sj3rpc-unpack-mb-string))
271         (setq rest (decode-coding-string (substring yomi-ext cylen)
272                                          sj3-server-coding-system))
273         (setq bunsetsu (sj3-make-bunsetsu env yomi converted rest stdy))))))
274
275 (defun sj3rpc-bunsetsu-stdy (env stdy)
276   (sj3rpc-call-with-environment env (result)
277      (comm-format (u v) (sj3-const STDY) stdy (length stdy))
278      (comm-unpack (u) result)
279      (- result)))
280
281 (defun sj3rpc-kugiri-stdy (env yomi1 yomi2 stdy)
282   (sj3rpc-call-with-environment env (result)
283     (comm-format (u s s v) (sj3-const CLSTDY)
284                  (encode-coding-string yomi1 sj3-server-coding-system)
285                  (encode-coding-string yomi2 sj3-server-coding-system)
286                  stdy (length stdy))
287     (comm-unpack (u) result)
288     (- result)))
289
290 (defun sj3rpc-add-word (env dictionary yomi kanji hinshi)
291   "Register a word KANJI into DICTIONARY with a pronunciation YOMI and
292 a part of speech HINSHI.  Where DICTIONARY should be an integer."
293   (sj3rpc-call-with-environment env ()
294     (comm-format (u u s s u) (sj3-const WREG) dictionary
295                  (encode-coding-string yomi sj3-server-coding-system)
296                  (encode-coding-string kanji sj3-server-coding-system)
297                  hinshi)
298     (comm-unpack (u) result)
299     (- result)))
300
301 ;;; egg/sj3rpc.el ends here.