imTransR.c revision b4ee4795
1/*
2 * Copyright 1992 Sun Microsystems, Inc.  All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23/******************************************************************
24
25              Copyright 1992, 1993, 1994 by FUJITSU LIMITED
26
27Permission to use, copy, modify, distribute, and sell this software
28and its documentation for any purpose is hereby granted without fee,
29provided that the above copyright notice appear in all copies and
30that both that copyright notice and this permission notice appear
31in supporting documentation, and that the name of FUJITSU LIMITED
32not be used in advertising or publicity pertaining to distribution
33of the software without specific, written prior permission.
34FUJITSU LIMITED makes no representations about the suitability of
35this software for any purpose.
36It is provided "as is" without express or implied warranty.
37
38FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
39INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
40EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
41CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
42USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44PERFORMANCE OF THIS SOFTWARE.
45
46  Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
47          Takashi Fujiwara     FUJITSU LIMITED
48                               fujiwara@a80.tech.yk.fujitsu.co.jp
49
50******************************************************************/
51
52#ifdef HAVE_CONFIG_H
53#include <config.h>
54#endif
55#include "Xlibint.h"
56#include "Xlcint.h"
57#include "XimTrInt.h"
58#include "Ximint.h"
59
60Public TransportSW _XimTransportRec[] = {
61    { "X",          _XimXConf },  /* 1st entry must be X.
62					This will be a fallback */
63#ifdef TCPCONN
64    { "tcp",        _XimTransConf }, /* use X transport lib */
65#endif /* TCPCONN */
66#if defined(UNIXCONN) || defined(LOCALCONN)
67    { "local",      _XimTransConf }, /* use X transport lib */
68#endif /* UNIXCONN */
69#ifdef DNETCONN
70    { "dnet",     _XimTransConf }, /* use X transport lib */
71#endif /* DNETCONN */
72#ifdef STREAMSCONN
73    { "streams",    _XimTransConf }, /* use X transport lib */
74#endif /* STREAMSCONN */
75    { (char *)NULL, (Bool (*)(Xim, char *))NULL },
76};
77
78Public Bool
79_XimConnect(Xim im)
80{
81    return im->private.proto.connect(im);
82}
83
84Public Bool
85_XimShutdown(Xim im)
86{
87    return im->private.proto.shutdown(im);
88}
89
90Public Bool
91_XimWrite(Xim im, INT16 len, XPointer data)
92{
93    return im->private.proto.write(im, len, data);
94}
95
96Private int
97_CheckProtocolData(
98    Xim		  im,
99    char	 *recv_buf)
100{
101    int		 data_len;
102
103    data_len = (int)(((*((CARD16 *)recv_buf + 1)) * 4) + XIM_HEADER_SIZE);
104    return data_len;
105}
106
107Private int
108_XimReadData(
109    Xim		 im,
110    INT16	*len,
111    XPointer	 buf,
112    int		 buf_size)
113{
114    char	*hold_buf;
115    char	*tmp;
116    int		 data_len;
117    int		 packet_size;
118    int		 ret_len;
119    register int i;
120
121    if (buf_size < XIM_HEADER_SIZE) {
122	*len = (INT16)XIM_HEADER_SIZE;
123	return XIM_OVERFLOW;
124    }
125
126    bzero(buf, buf_size);
127    packet_size = 0;
128    data_len = 0;
129
130    if ((hold_buf = im->private.proto.hold_data)) {
131	data_len = im->private.proto.hold_data_len;
132	if (data_len >= XIM_HEADER_SIZE) {
133	    packet_size = _CheckProtocolData(im, hold_buf);
134	    if (packet_size > buf_size) {
135		*len = (INT16)packet_size;
136		return XIM_OVERFLOW;
137	    }
138	    if (packet_size <= data_len) {
139		memcpy(buf, hold_buf, packet_size);
140		for (i = packet_size; i < data_len; i++) {
141		    if (hold_buf[i])
142			break;
143		}
144		data_len -= i;
145
146		if (data_len) {
147		    if (!(tmp = (char *)Xmalloc(data_len))) {
148			return XIM_FALSE;
149		    }
150		    memcpy(tmp, &hold_buf[i], data_len);
151		    im->private.proto.hold_data = tmp;
152		    im->private.proto.hold_data_len = data_len;
153		} else {
154		    im->private.proto.hold_data = 0;
155		    im->private.proto.hold_data_len = 0;
156		}
157		Xfree(hold_buf);
158		*len = (INT16)packet_size;
159		return XIM_TRUE;
160	    }
161	}
162	memcpy(buf, hold_buf, data_len);
163	buf_size -= data_len;
164	Xfree(hold_buf);
165	im->private.proto.hold_data = 0;
166	im->private.proto.hold_data_len = 0;
167    }
168
169    if (!packet_size) {
170	while (data_len < XIM_HEADER_SIZE) {
171	    if (!(im->private.proto.read(im,
172			(XPointer)&buf[data_len], buf_size, &ret_len))) {
173		return XIM_FALSE;
174	    }
175	    data_len += ret_len;
176	    buf_size -= ret_len;
177	}
178	packet_size = _CheckProtocolData(im, buf);
179    }
180
181    if (packet_size > buf_size) {
182	if (!(tmp = (char *)Xmalloc(data_len))) {
183	    return XIM_FALSE;
184	}
185	memcpy(tmp, buf, data_len);
186	bzero(buf, data_len);
187	im->private.proto.hold_data = tmp;
188	im->private.proto.hold_data_len = data_len;
189	*len = (INT16)packet_size;
190	return XIM_OVERFLOW;
191    }
192
193    while (data_len < packet_size) {
194	if (!(im->private.proto.read(im,
195			(XPointer)&buf[data_len], buf_size, &ret_len))) {
196	    return XIM_FALSE;
197	}
198	data_len += ret_len;
199	buf_size -= ret_len;
200    }
201
202    for (i = packet_size; i < data_len; i++) {
203	if (buf[i])
204	    break;
205    }
206    data_len -= i;
207
208    if (data_len) {
209	if (!(tmp = (char *)Xmalloc(data_len))) {
210	    return XIM_FALSE;
211	}
212	memcpy(tmp, &buf[i], data_len);
213	bzero(&buf[i], data_len);
214	im->private.proto.hold_data = tmp;
215	im->private.proto.hold_data_len = data_len;
216    } else {
217	im->private.proto.hold_data = 0;
218	im->private.proto.hold_data_len = 0;
219    }
220    *len = (INT16)packet_size;
221    return XIM_TRUE;
222}
223
224Private Bool
225_XimCallDispatcher(
226    Xim		 im,
227    INT16	 len,
228    XPointer	 data)
229{
230    return im->private.proto.call_dispatcher(im, len, data);
231}
232
233Public int
234_XimRead(Xim im, INT16 *len, XPointer buf, int buf_size,
235	 Bool (*predicate)(Xim, INT16, XPointer, XPointer), XPointer arg)
236{
237    INT16	 read_len;
238    int		 ret_code;
239
240    for (;;) {
241	ret_code = _XimReadData(im, &read_len, buf, buf_size);
242	if(ret_code != XIM_TRUE) {
243	    return ret_code;
244	}
245	if ((*predicate)(im, read_len, buf, arg))
246	    break;
247	if (_XimCallDispatcher(im, read_len, buf))
248	    continue;
249	_XimError(im, 0, XIM_BadProtocol, (INT16)0, (CARD16)0, (char *)NULL);
250    }
251    *len = read_len;
252    return True;
253}
254
255Public Bool
256_XimRegisterDispatcher(
257    Xim		 im,
258    Bool	 (*callback)(
259			     Xim, INT16, XPointer, XPointer
260			     ),
261    XPointer	 call_data)
262{
263    return im->private.proto.register_dispatcher(im, callback, call_data);
264}
265
266Public void
267_XimFlush(Xim im)
268{
269    im->private.proto.flush(im);
270    return;
271}
272
273Public Bool
274_XimFilterWaitEvent(Xim im)
275{
276    INT16	 read_len;
277    CARD32	 reply32[BUFSIZE/4];
278    char	*reply = (char *)reply32;
279    XPointer	 preply;
280    int		 buf_size;
281    int		 ret_code;
282
283    buf_size = BUFSIZE;
284    ret_code = _XimReadData(im, &read_len, (XPointer)reply, buf_size);
285    if(ret_code == XIM_TRUE) {
286	preply = reply;
287    } else if(ret_code == XIM_OVERFLOW) {
288	if(read_len <= 0) {
289	    preply = reply;
290	} else {
291	    buf_size = (int)read_len;
292	    preply = (XPointer)Xmalloc(buf_size);
293	    ret_code = _XimReadData(im, &read_len, preply, buf_size);
294	    if(ret_code != XIM_TRUE) {
295		if (preply != reply)
296		    Xfree(preply);
297		return False;
298	    }
299	}
300    } else {
301	return False;
302    }
303    if (_XimCallDispatcher(im, read_len, preply)) {
304	if(reply != preply)
305	    Xfree(preply);
306	return True;
307    }
308    _XimError(im, 0, XIM_BadProtocol, (INT16)0, (CARD16)0, (char *)NULL);
309    if(reply != preply)
310	Xfree(preply);
311    return True;
312}
313