* src/native/jni.h: Removed.
[cacao.git] / src / native / vm / cldc1.1 / com_sun_cldc_io_j2me_socket_Protocol.cpp
1 /* src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.cpp
2
3    Copyright (C) 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <stdint.h>
29 #include <errno.h>
30 #include <netdb.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34
35 #include "vm/types.h"
36
37 #include "mm/memory.h"
38
39 #include "native/jni.hpp"
40 #include "native/llni.h"
41 #include "native/native.h"
42
43 #if defined(ENABLE_JNI_HEADERS)
44 # include "native/include/com_sun_cldc_io_j2me_socket_Protocol.h"
45 #endif
46
47 #include "vm/global.h"
48 #include "vm/vm.hpp" /* REMOVE ME: temporarily */
49
50
51 // Native functions are exported as C functions.
52 extern "C" {
53
54 /*
55  * Class:     com/sun/cldc/io/j2me/socket/Protocol
56  * Method:    open0
57  * Signature: ([BII)I
58  */
59 JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_open0(JNIEnv *env, jclass clazz, jbyteArray hostname, jint port, jint mode)
60 {
61         struct hostent *phostent;
62     struct sockaddr_in serv_addr;
63
64         // The hostname byte-array is a NULL terminated C-string.
65         // XXX Not GC safe.
66         char* name = (char*) &(LLNI_array_data((java_handle_bytearray_t*) hostname));
67
68         /* get the host */
69
70         phostent = gethostbyname(name);
71
72         if (phostent == NULL)
73                 return -1;
74
75         /* fill the sockaddr structure */
76
77         serv_addr.sin_family = AF_INET;
78         serv_addr.sin_port   = htons(port);
79
80         MCOPY(&serv_addr.sin_addr, phostent->h_addr, u1, phostent->h_length);
81
82         /* create the socket */
83
84         int sockfd = socket(AF_INET, SOCK_STREAM, 0);
85
86         if (sockfd < 0)
87                 return -1;
88
89         /* connect the socket */
90
91         int result = connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr));
92
93         if (result < 0)
94                 return -1;
95
96         return sockfd;
97 }
98
99
100 /*
101  * Class:     com/sun/cldc/io/j2me/socket/Protocol
102  * Method:    readBuf
103  * Signature: (I[BII)I
104  */
105 JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf(JNIEnv *env, jclass clazz, jint handle, jbyteArray b, jint off, jint len)
106 {
107         // Get pointer to the buffer.
108         // XXX Not GC safe.
109         void* buf = &(LLNI_array_direct((java_handle_bytearray_t*) b, off));
110
111         // Receive from the socket.
112         ssize_t result = recv(handle, buf, len, 0);
113
114         if (result == 0) {
115                 // The peer has performed an orderly shutdown.
116                 return -1;
117         }
118         else if (result < 0) {
119                 vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf: recv failed");
120         }
121
122         return result;
123 }
124
125
126 /*
127  * Class:     com/sun/cldc/io/j2me/socket/Protocol
128  * Method:    readByte
129  * Signature: (I)I
130  */
131 JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_readByte(JNIEnv *env, jclass clazz, jint handle)
132 {
133         char byte;
134         
135         // Receive from the socket.
136         ssize_t result = recv(handle, &byte, 1, 0);
137
138         if (result == 0) {
139                 // The peer has performed an orderly shutdown.
140                 return -1;
141         }
142         else if (result < 0) {
143                 // TODO Should throw an IOException.
144                 vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_readByte: recv failed");
145         }
146
147         return byte;
148 }
149
150
151 /*
152  * Class:     com/sun/cldc/io/j2me/socket/Protocol
153  * Method:    writeBuf
154  * Signature: (I[BII)I
155  */
156 JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf(JNIEnv *env, jclass clazz, jint handle, jbyteArray b, jint off, jint len)
157 {
158         // Get pointer to the buffer.
159         // XXX Not GC safe.
160         void* buf = &(LLNI_array_direct((java_handle_bytearray_t*) b, off));
161         
162         // Send the given byte to the socket.
163         ssize_t result = send(handle, buf, len, 0);
164
165         if (result < 0) {
166                 // TODO Should throw an IOException.
167                 vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf: send failed");
168         }
169
170         return result;
171 }
172
173
174 /*
175  * Class:     com/sun/cldc/io/j2me/socket/Protocol
176  * Method:    writeByte
177  * Signature: (II)I
178  */
179 JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte(JNIEnv *env, jclass clazz, jint handle, jint b)
180 {
181         char byte = (char) b;
182
183         // Send the given byte to the socket.
184         ssize_t result = send(handle, &byte, 1, 0);
185
186         if (result < 0)
187                 vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte: send failed");
188
189         return result;
190 }
191
192
193 /*
194  * Class:     com/sun/cldc/io/j2me/socket/Protocol
195  * Method:    available0
196  * Signature: (I)I
197  */
198 JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_available0(JNIEnv *env, jclass clazz, jint handle)
199 {
200         // NOTE: Sun doesn't have an implementation too.
201         return 0;
202 }
203
204
205 /*
206  * Class:     com/sun/cldc/io/j2me/socket/Protocol
207  * Method:    close0
208  * Signature: (I)V
209  */
210 JNIEXPORT void JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_close0(JNIEnv *env, jclass clazz, jint handle)
211 {
212         // Close the file descriptor.
213         int result = close(handle);
214
215         if (result < 0)
216                 vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_close0: close failed");
217 }
218
219 } // extern "C"
220
221
222 /* native methods implemented by this file ************************************/
223  
224 static JNINativeMethod methods[] = {
225         { (char*) "open0",      (char*) "([BII)I",  (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_open0      },
226         { (char*) "readBuf",    (char*) "(I[BII)I", (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf    },
227         { (char*) "readByte",   (char*) "(I)I",     (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_readByte   },
228         { (char*) "writeBuf",   (char*) "(I[BII)I", (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf   },
229         { (char*) "writeByte",  (char*) "(II)I",    (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte  },
230         { (char*) "available0", (char*) "(I)I",     (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_available0 },
231         { (char*) "close0",     (char*) "(I)V",     (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_close0     },
232 };
233
234  
235 /* _Jv_com_sun_cldc_io_j2me_socket_Protocol_init *******************************
236  
237    Register native functions.
238  
239 *******************************************************************************/
240  
241 // FIXME
242 extern "C" {
243 void _Jv_com_sun_cldc_io_j2me_socket_Protocol_init(void)
244 {
245         utf *u;
246  
247         u = utf_new_char("com/sun/cldc/io/j2me/socket/Protocol");
248  
249         native_method_register(u, methods, NATIVE_METHODS_COUNT);
250 }
251 }
252
253
254 /*
255  * These are local overrides for various environment variables in Emacs.
256  * Please do not remove this and leave it at the end of the file, where
257  * Emacs will automagically detect them.
258  * ---------------------------------------------------------------------
259  * Local variables:
260  * mode: c++
261  * indent-tabs-mode: t
262  * c-basic-offset: 4
263  * tab-width: 4
264  * End:
265  * vim:noexpandtab:sw=4:ts=4:
266  */