OSDN Git Service

* config/i386/i386.md (*sinxf2): Rename to *sinxf2_i387.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / java-net / gnu_java_net_VMPlainDatagramSocketImpl.c
1 /* VMPlainDatagramSocketImpl.c - Native methods for PlainDatagramSocketImpl
2    Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10  
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 /* do not move; needed here because of some macro definitions */
39 #include <config.h>
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44
45 #include <jni.h>
46 #include <jcl.h>
47
48 #include "javanet.h"
49
50 #include "target_native.h"
51 #ifndef WITHOUT_NETWORK
52   #include "target_native_network.h"
53 #endif /* WITHOUT_NETWORK */
54
55
56 #include "gnu_java_net_VMPlainDatagramSocketImpl.h"
57
58 /*
59  * Note that most of the functions in this module simply redirect to another
60  * internal function.  Why?  Because many of these functions are shared
61  * with PlainSocketImpl. 
62  */
63
64 /*************************************************************************/
65
66 /*
67  * Creates a new datagram socket
68  */
69 JNIEXPORT void JNICALL
70 Java_gnu_java_net_VMPlainDatagramSocketImpl_create(JNIEnv *env,
71                                                    jclass klass __attribute__ ((__unused__))
72                                                    , jobject obj)
73 {
74
75 #ifndef WITHOUT_NETWORK
76   _javanet_create(env, obj, 0);
77 #else /* not WITHOUT_NETWORK */
78 #endif /* not WITHOUT_NETWORK */
79 }
80
81 /*************************************************************************/
82
83 /*
84  * Close the socket.
85  */
86 JNIEXPORT void JNICALL
87 Java_gnu_java_net_VMPlainDatagramSocketImpl_close(JNIEnv *env,
88                                                   jclass klass __attribute__ ((__unused__)),
89                                                   jobject obj)
90 {
91
92 #ifndef WITHOUT_NETWORK
93   _javanet_close(env, obj, 0);
94 #else /* not WITHOUT_NETWORK */
95 #endif /* not WITHOUT_NETWORK */
96 }
97
98 /*************************************************************************/
99
100 /*
101  * Connects to the specified destination.
102  */
103 JNIEXPORT void JNICALL
104 Java_gnu_java_net_VMPlainDatagramSocketImpl_connect(JNIEnv *env,
105                                                     jclass klass __attribute__ ((__unused__)),
106                                                     jobject obj,
107                                                     jobject addr, jint port)
108 {
109 #ifndef WITHOUT_NETWORK
110
111   _javanet_connect(env, obj, addr, port, 0);
112 #else /* not WITHOUT_NETWORK */
113 #endif /* not WITHOUT_NETWORK */
114 }
115
116 /*************************************************************************/
117
118 /*
119  * This method binds the specified address to the specified local port.
120  * Note that we have to set the local address and local port public instance 
121  * variables. 
122  */
123 JNIEXPORT void JNICALL
124 Java_gnu_java_net_VMPlainDatagramSocketImpl_bind(JNIEnv *env,
125                                                  jclass klass __attribute__ ((__unused__)),
126                                                  jobject obj,
127                                                  jint port, jobject addr)
128 {
129
130 #ifndef WITHOUT_NETWORK
131   _javanet_bind(env, obj, addr, port, 0);
132 #else /* not WITHOUT_NETWORK */
133 #endif /* not WITHOUT_NETWORK */
134 }
135
136 /*************************************************************************/
137
138 /*
139  * This method sets the specified option for a socket
140  */
141 JNIEXPORT void JNICALL
142 Java_gnu_java_net_VMPlainDatagramSocketImpl_setOption(JNIEnv *env,
143                                                       jclass klass __attribute__ ((__unused__)),
144                                                       jobject obj, 
145                                                       jint option_id,
146                                                       jobject val)
147 {
148
149 #ifndef WITHOUT_NETWORK
150   _javanet_set_option(env, obj, option_id, val);
151 #else /* not WITHOUT_NETWORK */
152 #endif /* not WITHOUT_NETWORK */
153 }
154
155 /*************************************************************************/
156
157 /*
158  * This method sets the specified option for a socket
159  */
160 JNIEXPORT jobject JNICALL
161 Java_gnu_java_net_VMPlainDatagramSocketImpl_getOption(JNIEnv *env,
162                                                       jclass klass __attribute__ ((__unused__)),
163                                                       jobject obj, 
164                                                       jint option_id)
165 {
166
167 #ifndef WITHOUT_NETWORK
168   return(_javanet_get_option(env, obj, option_id));
169 #else /* not WITHOUT_NETWORK */
170   return NULL;
171 #endif /* not WITHOUT_NETWORK */
172 }
173
174 /*************************************************************************/
175
176 /*
177  * Reads a buffer from a remote host
178  */
179 JNIEXPORT void JNICALL
180 Java_gnu_java_net_VMPlainDatagramSocketImpl_nativeReceive(JNIEnv     *env,
181                                                           jclass     klass __attribute__ ((__unused__)),
182                                                           jobject    obj,
183                                                           jbyteArray arr,
184                                                           jint       offset,
185                                                           jint       length,
186                                                           jbyteArray receivedFromAddress,
187                                                           jintArray  receivedFromPort,
188                                                           jintArray  receivedLength)
189 {
190 #ifndef WITHOUT_NETWORK
191   int           addr, *port, *bytes_read;
192   char          *addressBytes;
193
194   addr = 0;
195     
196   port = (int*)(*env)->GetIntArrayElements(env, receivedFromPort, NULL);
197   if (port == NULL)
198     {
199       JCL_ThrowException(env, IO_EXCEPTION, "Internal error: could not access receivedFromPort array");
200       return;
201     }
202   
203   bytes_read = (int*)(*env)->GetIntArrayElements(env, receivedLength, NULL);
204   if (bytes_read == NULL)
205     {
206       (*env)->ReleaseIntArrayElements(env, receivedFromPort, (jint*)port, 0);
207       JCL_ThrowException(env, IO_EXCEPTION, "Internal error: could not access receivedLength array");
208       return;
209     }
210
211   /* Receive the packet */
212   /* should we try some sort of validation on the length? */
213   (*bytes_read) = _javanet_recvfrom(env, obj, arr, offset, length, &addr, port);
214
215   /* Special case the strange situation where the receiver didn't want any
216      bytes. */
217   if (length == 0 && (*bytes_read) == -1)
218     *bytes_read = 0;
219
220   if ((*bytes_read) == -1)
221     {
222       (*env)->ReleaseIntArrayElements(env, receivedFromPort, (jint*)port, 0);
223       (*env)->ReleaseIntArrayElements(env, receivedLength, (jint*)bytes_read, 0);
224       JCL_ThrowException(env, IO_EXCEPTION, "Internal error: receive");
225       return;
226     }
227
228   (*env)->ReleaseIntArrayElements(env, receivedFromPort, (jint*)port, 0);
229   (*env)->ReleaseIntArrayElements(env, receivedLength, (jint*)bytes_read, 0);
230
231   if ((*env)->ExceptionOccurred(env))
232     {
233       return;
234     }
235
236   DBG("PlainDatagramSocketImpl.receive(): Received packet\n");
237   
238   
239   /* Store the address */
240   addressBytes = (char*)(*env)->GetPrimitiveArrayCritical(env, receivedFromAddress, NULL);
241   TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES(addr,
242                                                addressBytes[0],
243                                                addressBytes[1],
244                                                addressBytes[2],
245                                                addressBytes[3]
246                                               );
247   (*env)->ReleasePrimitiveArrayCritical(env, receivedFromAddress, addressBytes, 0);
248     
249 #else /* not WITHOUT_NETWORK */
250 #endif /* not WITHOUT_NETWORK */
251 }
252
253 /*************************************************************************/
254
255 /*
256  * Writes a buffer to the remote host
257  */
258 JNIEXPORT void JNICALL
259 Java_gnu_java_net_VMPlainDatagramSocketImpl_nativeSendTo(JNIEnv  *env,
260                                                          jclass  klass __attribute__ ((__unused__)),
261                                                          jobject obj, 
262                                                          jobject addr,
263                                                          jint    port,
264                                                          jarray  buf, 
265                                                          jint    offset,
266                                                          jint    len)
267 {
268 #ifndef WITHOUT_NETWORK
269   jint netAddress;
270
271   /* check if address given, tr 7.3.2005 */
272   if (addr != NULL)
273     {
274       netAddress = _javanet_get_netaddr(env, addr);
275       if ((*env)->ExceptionOccurred(env))
276         {
277           return;
278         }
279     }
280   else
281     {
282       netAddress = 0;
283     }
284
285   DBG("PlainDatagramSocketImpl.sendto(): have addr\n");
286
287   _javanet_sendto(env, obj, buf, offset, len, netAddress, port);
288   if ((*env)->ExceptionOccurred(env))
289     {
290       return;
291     }
292
293   DBG("PlainDatagramSocketImpl.sendto(): finished\n");
294 #else /* not WITHOUT_NETWORK */
295 #endif /* not WITHOUT_NETWORK */
296 }
297
298 /*************************************************************************/
299
300 /*
301  * Joins a multicast group
302  */
303 JNIEXPORT void JNICALL
304 Java_gnu_java_net_VMPlainDatagramSocketImpl_join(JNIEnv *env,
305                                                  jclass klass __attribute__ ((__unused__)),
306                                                  jobject obj, 
307                                                  jobject addr)
308 {
309 #ifndef WITHOUT_NETWORK
310   jint netAddress;
311   int  fd;
312   int  result;
313
314   /* check if address given, tr 7.3.2005 */
315   if (addr != NULL)
316     {
317       netAddress = _javanet_get_netaddr(env, addr);
318       if ((*env)->ExceptionOccurred(env))
319         {
320           JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
321           return;
322         }
323     }
324   else
325     {
326       netAddress = 0;
327     }
328
329   fd = _javanet_get_int_field(env, obj, "native_fd");
330   if ((*env)->ExceptionOccurred(env))
331     {
332       JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
333       return;
334     }
335
336   DBG("PlainDatagramSocketImpl.join(): have native fd\n");
337
338   TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_ADD_MEMBERSHIP(fd,netAddress,result);
339
340   if (result != TARGET_NATIVE_OK)
341     {
342       JCL_ThrowException(env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING());
343       return;
344     }
345
346   DBG("PlainDatagramSocketImpl.join(): finished\n");
347 #else /* not WITHOUT_NETWORK */
348 #endif /* not WITHOUT_NETWORK */
349 }
350
351 /*************************************************************************/
352
353 /*
354  * Leaves a multicast group
355  */
356 JNIEXPORT void JNICALL
357 Java_gnu_java_net_VMPlainDatagramSocketImpl_leave(JNIEnv *env,
358                                                   jclass klass __attribute__ ((__unused__)),
359                                                   jobject obj, 
360                                                   jobject addr)
361 {
362 #ifndef WITHOUT_NETWORK
363   jint netAddress;
364   int  fd;
365   int  result;
366
367   /* check if address given, tr 7.3.2005 */
368   if (addr != NULL)
369     {
370       netAddress = _javanet_get_netaddr(env, addr);
371       if ((*env)->ExceptionOccurred(env))
372         {
373           JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
374           return;
375         }
376     }
377   else
378     {
379       netAddress = 0;
380     }
381
382   fd = _javanet_get_int_field(env, obj, "native_fd");
383   if ((*env)->ExceptionOccurred(env))
384     { JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; }
385
386   DBG("PlainDatagramSocketImpl.leave(): have native fd\n");
387
388   TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_DROP_MEMBERSHIP(fd,netAddress,result);
389   if (result!=TARGET_NATIVE_OK)
390     {
391       JCL_ThrowException(env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING());
392       return;
393     }
394
395   DBG("PlainDatagramSocketImpl.leave(): finished\n");
396 #else /* not WITHOUT_NETWORK */
397 #endif /* not WITHOUT_NETWORK */
398 }
399