harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From py...@apache.org
Subject svn commit: r501403 - in /harmony/enhanced/classlib/trunk/modules: luni/src/main/java/org/apache/harmony/luni/platform/ luni/src/main/native/luni/shared/ luni/src/main/native/luni/unix/ nio/src/main/java/org/apache/harmony/nio/internal/
Date Tue, 30 Jan 2007 14:33:42 GMT
Author: pyang
Date: Tue Jan 30 06:33:41 2007
New Revision: 501403

URL: http://svn.apache.org/viewvc?view=rev&rev=501403
Log:
Apply patch for harmony-3037([classlib][nio]DatagramChannelImpl and SocketChannelImpl lack support for direct byte buffer), with bug fixing and code tidy up for compiler warnings

Modified:
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
    harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.c
    harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.h
    harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/unix/libhyluni.exp
    harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java
    harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java?view=diff&rev=501403&r1=501402&r2=501403
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java Tue Jan 30 06:33:41 2007
@@ -67,9 +67,15 @@
 
 	public int read(FileDescriptor aFD, byte[] data, int offset, int count,
 			int timeout) throws IOException;
+    
+    public int readDirect(FileDescriptor aFD, long address, int offset, int count,
+            int timeout) throws IOException;
 
 	public int write(FileDescriptor fd, byte[] data, int offset, int count)
 			throws IOException;
+    
+    public int writeDirect(FileDescriptor fd, long address, int offset, int count)
+            throws IOException;
 
 	public void setNonBlocking(FileDescriptor aFD, boolean block)
 			throws IOException;
@@ -84,20 +90,34 @@
 	public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
 			int length, int port, boolean bindToDevice, int trafficClass,
 			InetAddress inetAddress) throws IOException;
+    
+    public int sendDatagramDirect(FileDescriptor fd, long address, int offset,
+            int length, int port, boolean bindToDevice, int trafficClass,
+            InetAddress inetAddress) throws IOException;
 
 	public int receiveDatagram(FileDescriptor aFD, DatagramPacket packet,
 			byte[] data, int offset, int length, int receiveTimeout,
 			boolean peek) throws IOException;
+    
+    public int receiveDatagramDirect(FileDescriptor aFD, long address, int offset,
+            int length, int receiveTimeout, boolean peek) throws IOException;
 
 	public int recvConnectedDatagram(FileDescriptor aFD, DatagramPacket packet,
 			byte[] data, int offset, int length, int receiveTimeout,
 			boolean peek) throws IOException;
-
+    
+    public int recvConnectedDatagramDirect(FileDescriptor aFD, long address,
+            int offset, int length, int receiveTimeout, boolean peek)
+            throws IOException;
+    
 	public int peekDatagram(FileDescriptor aFD, InetAddress sender,
 			int receiveTimeout) throws IOException;
 
 	public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
 			int offset, int length, boolean bindToDevice) throws IOException;
+    
+    public int sendConnectedDatagramDirect(FileDescriptor fd, long address,
+            int offset, int length, boolean bindToDevice) throws IOException;
 
 	public void disconnectDatagram(FileDescriptor aFD) throws SocketException;
 

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java?view=diff&rev=501403&r1=501402&r2=501403
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java Tue Jan 30 06:33:41 2007
@@ -89,11 +89,21 @@
 			int timeout) throws IOException {
 		return readSocketImpl(aFD, data, offset, count, timeout);
 	}
+    
+    public int readDirect(FileDescriptor aFD, long address, int offset, int count,
+            int timeout) throws IOException {
+        return readSocketDirectImpl(aFD, address, offset, count, timeout);
+    }
 
 	public int write(FileDescriptor aFD, byte[] data, int offset, int count)
 			throws IOException {
 		return writeSocketImpl(aFD, data, offset, count);
 	}
+    
+    public int writeDirect(FileDescriptor aFD, long address, int offset,
+            int count) throws IOException {
+        return writeSocketDirectImpl(aFD, address, offset, count);
+    }
 
 	public void setNonBlocking(FileDescriptor aFD, boolean block)
 			throws IOException {
@@ -145,6 +155,13 @@
 		return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
 				trafficClass, inetAddress);
 	}
+    
+    public int sendDatagramDirect(FileDescriptor fd, long address, int offset,
+            int length, int port, boolean bindToDevice, int trafficClass,
+            InetAddress inetAddress) throws IOException {
+        return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
+                trafficClass, inetAddress);
+    }
 
 	public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
 			int length, int port, InetAddress inetAddress) throws IOException {
@@ -152,11 +169,18 @@
 	}
 
 	public int receiveDatagram(FileDescriptor aFD, DatagramPacket packet,
-			byte[] data, int offset, int length, int receiveTimeout,
-			boolean peek) throws IOException {
-		return receiveDatagramImpl(aFD, packet, data, offset, length,
-				receiveTimeout, peek);
-	}
+            byte[] data, int offset, int length, int receiveTimeout,
+            boolean peek) throws IOException {
+        return receiveDatagramImpl(aFD, packet, data, offset, length,
+                receiveTimeout, peek);
+    }
+    
+    public int receiveDatagramDirect(FileDescriptor aFD, long address,
+            int offset, int length, int receiveTimeout, boolean peek)
+            throws IOException {
+        return receiveDatagramDirectImpl(aFD, address, offset, length,
+                receiveTimeout, peek);
+    }
 
 	public int recvConnectedDatagram(FileDescriptor aFD, DatagramPacket packet,
 			byte[] data, int offset, int length, int receiveTimeout,
@@ -164,6 +188,13 @@
 		return recvConnectedDatagramImpl(aFD, packet, data, offset, length,
 				receiveTimeout, peek);
 	}
+    
+    public int recvConnectedDatagramDirect(FileDescriptor aFD, long address,
+            int offset, int length, int receiveTimeout, boolean peek)
+            throws IOException {
+        return recvConnectedDatagramDirectImpl(aFD, address, offset, length,
+                receiveTimeout, peek);
+    }
 
 	public int peekDatagram(FileDescriptor aFD, InetAddress sender,
 			int receiveTimeout) throws IOException {
@@ -174,6 +205,11 @@
 			int offset, int length, boolean bindToDevice) throws IOException {
 		return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
 	}
+    
+    public int sendConnectedDatagramDirect(FileDescriptor fd, long address,
+            int offset, int length, boolean bindToDevice) throws IOException {
+        return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
+    }
 
 	public void disconnectDatagram(FileDescriptor aFD) throws SocketException {
 		disconnectDatagramImpl(aFD);
@@ -390,9 +426,15 @@
 
 	static native int readSocketImpl(FileDescriptor aFD, byte[] data,
 			int offset, int count, int timeout) throws IOException;
+    
+    static native int readSocketDirectImpl(FileDescriptor aFD, long address,
+            int offset, int count, int timeout) throws IOException;
 
 	static native int writeSocketImpl(FileDescriptor fd, byte[] data,
 			int offset, int count) throws IOException;
+    
+    static native int writeSocketDirectImpl(FileDescriptor fd, long address,
+            int offset, int count) throws IOException;
 
 	static native void setNonBlockingImpl(FileDescriptor aFD,
 			boolean block);
@@ -499,6 +541,10 @@
 	static native int receiveDatagramImpl(FileDescriptor aFD,
 			DatagramPacket packet, byte[] data, int offset, int length,
 			int receiveTimeout, boolean peek) throws IOException;
+    
+    static native int receiveDatagramDirectImpl(FileDescriptor aFD,
+            long address, int offset, int length, int receiveTimeout,
+            boolean peek) throws IOException;
 
 	/*
 	 * Recieve data on the connected socket into the specified buffer. The
@@ -517,6 +563,10 @@
 	static native int recvConnectedDatagramImpl(FileDescriptor aFD,
 			DatagramPacket packet, byte[] data, int offset, int length,
 			int receiveTimeout, boolean peek) throws IOException;
+    
+    static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
+            long address, int offset, int length,
+            int receiveTimeout, boolean peek) throws IOException;
 
 	/*
 	 * Send the <code>data</code> to the nominated target <code>address</code>
@@ -536,6 +586,11 @@
 			byte[] data, int offset, int length, int port,
 			boolean bindToDevice, int trafficClass, InetAddress inetAddress)
 			throws IOException;
+    
+    static native int sendDatagramDirectImpl(FileDescriptor fd,
+            long address, int offset, int length, int port,
+            boolean bindToDevice, int trafficClass, InetAddress inetAddress)
+            throws IOException;
 
 	/*
 	 * Send the <code>data</code> to the address and port to which the was
@@ -550,6 +605,10 @@
 	static native int sendConnectedDatagramImpl(FileDescriptor fd,
 			byte[] data, int offset, int length, boolean bindToDevice)
 			throws IOException;
+    
+    static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
+            long address, int offset, int length, boolean bindToDevice)
+            throws IOException;
 
 	/*
 	 * Answer the result of attempting to create a server stream socket in the

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.c?view=diff&rev=501403&r1=501402&r2=501403
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.c (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.c Tue Jan 30 06:33:41 2007
@@ -44,6 +44,10 @@
 int 
 selectRead (JNIEnv * env,hysocket_t hysocketP, I_32 uSecTime, BOOLEAN accept);
 
+int receiveDatagram(JNIEnv * env, jclass thisClz, jobject fileDescriptor, 
+    jobject datagramPacket, jbyte* message, jint offset, jint msgLength, jint timeout, jboolean peek);
+
+
 /**
  * A helper method, to set the remote address into the DatagramPacket.
  *
@@ -265,6 +269,62 @@
   setSocketImplPort (env, socketImpl, hysock_ntohs (nPort));
 }
 
+int receiveDatagram(JNIEnv * env,
+		  jclass thisClz,  jobject  fileDescriptor, jobject datagramPacket, jbyte* message,
+		  jint offset, jint msgLength, jint timeout,  jboolean peek)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  hysocket_t hysocketP;	
+  hysockaddr_struct sockaddrP;  
+  I_32 result, localCount;
+  I_32 flags = HYSOCK_NOFLAGS;
+  jbyte	nlocalAddrBytes[HYSOCK_INADDR6_LEN];
+
+  hysocketP = getJavaIoFileDescriptorContentsAsAPointer	(env, fileDescriptor);
+  result = pollSelectRead (env,	fileDescriptor,	timeout, TRUE);	
+  //result = selectRead (env,hysocketP, timeout, FALSE);
+  if (0	> result)
+    return (jint) 0;
+
+  if (!hysock_socketIsValid (hysocketP))
+    {
+      throwJavaNetSocketException (env,	HYPORT_ERROR_SOCKET_BADSOCKET);	
+      return (jint) 0;
+    }
+
+  hysock_sockaddr_init6	(&sockaddrP, (U_8 *) nlocalAddrBytes,
+       HYSOCK_INADDR_LEN, HYADDR_FAMILY_AFINET4, 0, 0, 0,
+       hysocketP);
+
+  localCount = (msgLength < 65536) ? msgLength : 65536;	
+ 
+  if (peek)
+    {
+      result = hysock_setflag (HYSOCK_MSG_PEEK,	&flags);
+      if (result)
+	{
+	  throwJavaNetSocketException (env, result);
+	  return (jint)	0;
+	}
+    }
+  result =
+    hysock_readfrom (hysocketP,	(U_8 *)message, localCount, flags, &sockaddrP);  
+  
+  if (result < 0)
+    {
+      throwJavaNetSocketException (env,	result);
+      return (jint) 0;
+    }
+  else
+    {
+      if(datagramPacket != NULL)
+      {
+      	updatePacket (env, &sockaddrP, datagramPacket, result);
+      }
+      return (jint) result;
+    }
+}
+
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
  * Method:    oneTimeInitializationDatagram
@@ -391,30 +451,14 @@
 	      jint count, jint timeout)	
 {
   PORT_ACCESS_FROM_ENV (env);
-  hysocket_t hysocketP;	
   jbyte	*message;
-  I_32 result, localCount;
+  I_32 localCount;
+  jint result;
 
 /* TODO: ARRAY PINNING */
 #define	INTERNAL_RECEIVE_BUFFER_MAX 2048
   U_8 internalBuffer[INTERNAL_RECEIVE_BUFFER_MAX];
 
-  hysocketP =getJavaIoFileDescriptorContentsAsAPointer (env, fileDescriptor);
-
-  /*----------------the older form,nearly the same with below------------
-  //result = pollSelectRead (env, fileDescriptor, timeout, TRUE);
-  */
-  result = selectRead (env,hysocketP, timeout, FALSE);	    
-  if (0	>= result)
-	return (jint) 0;
-
-
-  if (!hysock_socketIsValid (hysocketP))
-    {
-      throwJavaNetSocketException (env,	HYPORT_ERROR_SOCKET_BADSOCKET);	
-      return (jint) 0;
-    }
-
   localCount = (count <	65536) ? count : 65536;	
 
   if (localCount > INTERNAL_RECEIVE_BUFFER_MAX)	
@@ -431,8 +475,8 @@
       message =	(jbyte *)internalBuffer;	
     }
 
-
-  result = hysock_read (hysocketP, (U_8 *) message, localCount, HYSOCK_NOFLAGS);
+  result = Java_org_apache_harmony_luni_platform_OSNetworkSystem_readSocketDirectImpl(env, thisClz, fileDescriptor,
+      (jlong)message, offset, count, timeout);  
 
   if (result > 0)
     (*env)->SetByteArrayRegion (env, data, offset, result, (jbyte *)message);
@@ -442,7 +486,45 @@
       hymem_free_memory	((U_8 *)message);
     }
 #undef INTERNAL_MAX
+   return result;
+}
 
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    readSocketDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIII)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_readSocketDirectImpl(JNIEnv * env, 
+          jclass thisClz,
+	      jobject fileDescriptor,
+	      jlong address, jint offset,
+	      jint count, jint timeout)	
+{
+  PORT_ACCESS_FROM_ENV (env);
+  hysocket_t hysocketP;	
+  jbyte	*message = (jbyte *)address;
+  I_32 result, localCount;
+
+  hysocketP =getJavaIoFileDescriptorContentsAsAPointer (env, fileDescriptor);
+
+  /*----------------the older form,nearly the same with below------------
+  //result = pollSelectRead (env, fileDescriptor, timeout, TRUE);
+  */
+  result = selectRead (env,hysocketP, timeout, FALSE);	    
+  if (0	>= result)
+	return (jint) 0;
+
+
+  if (!hysock_socketIsValid (hysocketP))
+    {
+      throwJavaNetSocketException (env,	HYPORT_ERROR_SOCKET_BADSOCKET);	
+      return (jint) 0;
+    }
+
+  localCount = (count <	65536) ? count : 65536;	
+
+  result = hysock_read (hysocketP, (U_8 *) message, localCount, HYSOCK_NOFLAGS);
+  
   /* If	no bytes are read, return -1 to	signal 'endOfFile' to the Java input stream */
   if (0	< result)
     {
@@ -470,9 +552,9 @@
 	   jint	count)
 {
   PORT_ACCESS_FROM_ENV (env);
-  hysocket_t socketP;
   jbyte	*message;
-  I_32 result =	0, sent	= 0;
+  I_32 sent	= 0;
+  jint result = 0;
 
 /* TODO: ARRAY PINNING */
 #define	INTERNAL_SEND_BUFFER_MAX 512
@@ -492,25 +574,52 @@
       message =	(jbyte *)internalBuffer;	
     }
 
-
   (*env)->GetByteArrayRegion (env, data, offset, count,	message);
-  while	(sent <	count)
+  
+  result = Java_org_apache_harmony_luni_platform_OSNetworkSystem_writeSocketDirectImpl(env, thisClz,
+	   fileDescriptor, (jlong) message, offset, count);
+    
+  if ((U_8 *)message != internalBuffer)
     {
-      socketP =	
+      hymem_free_memory	(message);
+    }
+#undef INTERNAL_SEND_BUFFER_MAX
+   return result;
+}
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    writeSocketDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JII)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_writeSocketDirectImpl(JNIEnv * env,
+       jclass thisClz,
+	   jobject fileDescriptor,
+	   jlong address, jint offset,
+	   jint	count)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  hysocket_t socketP;
+  jbyte	*message = (jbyte *)address;
+  I_32 result =	0, sent	= 0;
+
+  if(sent < count)
+  {
+  	socketP =	
 	getJavaIoFileDescriptorContentsAsAPointer (env,	fileDescriptor);
-      if (!hysock_socketIsValid	(socketP))
+    if (!hysock_socketIsValid(socketP))
 	{
-	  if (((U_8 *)message) != internalBuffer)
-	    {
-	      hymem_free_memory	(message);
-	    }
-
-	  throwJavaNetSocketException (env,
+	   throwJavaNetSocketException (env,
 	    sent ==
 	    0 ?	HYPORT_ERROR_SOCKET_BADSOCKET :	
 	  HYPORT_ERROR_SOCKET_INTERRUPTED);
 	  return (jint)	0;
 	}
+  }
+  
+  while	(sent <	count)
+    {
+      
       result =
 	hysock_write (socketP, (U_8 *) message + sent, (I_32) count - sent,
 	HYSOCK_NOFLAGS);
@@ -518,12 +627,7 @@
 	break;
       sent += result;
     }
-  if ((U_8 *)message != internalBuffer)
-    {
-      hymem_free_memory	(message);
-    }
-#undef INTERNAL_SEND_BUFFER_MAX
-
+    
   /**
    * We	should always throw an exception if all	the data cannot	be sent	because	Java methods
    * assume all	the data will be sent or an error occurs.
@@ -1180,6 +1284,7 @@
       return hport;
     }
 }
+
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
  * Method:    receiveDatagramImpl
@@ -1198,29 +1303,10 @@
 		  jboolean peek)
 {
   PORT_ACCESS_FROM_ENV (env);
-  hysocket_t hysocketP;	
-  hysockaddr_struct sockaddrP;
   jbyte	*message;
-  I_32 result, localCount;
-  I_32 flags = HYSOCK_NOFLAGS;
-  jbyte	nlocalAddrBytes[HYSOCK_INADDR6_LEN];
-
-  hysocketP = getJavaIoFileDescriptorContentsAsAPointer	(env, fileDescriptor);
-  result = pollSelectRead (env,	fileDescriptor,	timeout, TRUE);	
-  //result = selectRead (env,hysocketP, timeout, FALSE);
-  if (0	> result)
-    return (jint) 0;
-
-  if (!hysock_socketIsValid (hysocketP))
-    {
-      throwJavaNetSocketException (env,	HYPORT_ERROR_SOCKET_BADSOCKET);	
-      return (jint) 0;
-    }
-
-  hysock_sockaddr_init6	(&sockaddrP, (U_8 *) nlocalAddrBytes,
-       HYSOCK_INADDR_LEN, HYADDR_FAMILY_AFINET4, 0, 0, 0,
-       hysocketP);
-
+  jint result; 
+  I_32 localCount;
+  
   localCount = (msgLength < 65536) ? msgLength : 65536;	
   message = hymem_allocate_memory (localCount);	
   if (message == NULL)
@@ -1228,32 +1314,34 @@
       throwNewOutOfMemoryError (env, "");
       return 0;	
     }
-  if (peek)
-    {
-      result = hysock_setflag (HYSOCK_MSG_PEEK,	&flags);
-      if (result)
-	{
-	  hymem_free_memory (message);
-	  throwJavaNetSocketException (env, result);
-	  return (jint)	0;
-	}
-    }
-  result =
-    hysock_readfrom (hysocketP,	(U_8 *)message, localCount, flags, &sockaddrP);
+  
+  result = receiveDatagram(env, thisClz, fileDescriptor, datagramPacket, message, offset, localCount , timeout, peek);
+    
   if (result > 0)
-    (*env)->SetByteArrayRegion (env, data, offset, result, message);
-  hymem_free_memory (message);
-  if (result < 0)
     {
-      throwJavaNetSocketException (env,	result);
-      return (jint) 0;
-    }
-  else
-    {
-      updatePacket (env, &sockaddrP, datagramPacket, result);
-      return (jint) result;
+      (*env)->SetByteArrayRegion (env, data, offset, result, message);
     }
+  hymem_free_memory (message);
+  return result;
 }
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    receiveDatagramDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIIIZ)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_receiveDatagramDirectImpl(JNIEnv *env,
+		jclass thisClz, 
+		jobject fileDescriptor, 
+		jlong address, 
+		jint offset, 
+		jint msgLength, 
+		jint timeout, 
+		jboolean peek)
+{
+  return receiveDatagram(env, thisClz, fileDescriptor, NULL, (jbyte*) address, offset, msgLength, timeout, peek);
+}
+
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
  * Method:    recvConnectedDatagramImpl	
@@ -1275,13 +1363,61 @@
 		 jboolean
 		 peek)
 {
+
   PORT_ACCESS_FROM_ENV (env);
-  hysocket_t hysocketP;	
   jbyte	*message;
+  jint result;
+  I_32 localCount;
+  
+  /* allocate the buffer into which data will be read */
+  localCount = (msgLength < 65536) ? msgLength : 65536;	
+  message = hymem_allocate_memory (localCount);	
+  if (message == NULL)
+    {
+      throwNewOutOfMemoryError (env, "");
+      return 0;	
+    }
+    
+  result = Java_org_apache_harmony_luni_platform_OSNetworkSystem_recvConnectedDatagramDirectImpl(env, thisClz, fileDescriptor, (jlong)message, offset, localCount, timeout, peek);  
+  if (result > 0)
+    {
+      (*env)->SetByteArrayRegion (env, data, offset, result, message);
+      /* update	the packet with	the legth of data received.
+	 Since we are connected	we did not get back an address.	 This
+	 address is cached within the PlainDatagramSocket  java	object and is filled in	at
+	 the java level	*/
+      if(datagramPacket != NULL)
+      {
+      	setDatagramPacketLength (env, datagramPacket, result);
+      }
+    }
+  hymem_free_memory ( message);  
+  return result; 
+}
+
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    recvConnectedDatagramDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIIIZ)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_recvConnectedDatagramDirectImpl(JNIEnv *env, 
+		jclass thisClz, 
+		jobject fileDescriptor, 
+		jlong address, 
+		jint offset, 
+		jint msgLength, 
+		jint timeout, 
+		jboolean peek)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  hysocket_t hysocketP;
+  jbyte * message = (jbyte *)address;	  
   I_32 result;
   I_32 localCount;
   I_32 flags = HYSOCK_NOFLAGS;
 
+  localCount = (msgLength < 65536) ? msgLength : 65536;
   /* check if there is any data	to be read before we go	ahead and do the read */
   result = pollSelectRead (env,	fileDescriptor,	timeout, TRUE);	
   if (0	> result)
@@ -1297,22 +1433,12 @@
       return (jint) 0;
     }
 
-  /* allocate the buffer into which data will be read */
-  localCount = (msgLength < 65536) ? msgLength : 65536;	
-  message = hymem_allocate_memory (localCount);	
-  if (message == NULL)
-    {
-      throwNewOutOfMemoryError (env, "");
-      return 0;	
-    }
-
   /* check for peek option, if so set the appropriate flag */
   if (peek)
     {
       result = hysock_setflag (HYSOCK_MSG_PEEK,	&flags);
       if (result)
 	{
-	  hymem_free_memory ( message);	
 	  throwJavaNetSocketException (env, result);
 	  return (jint)	0;
 	}
@@ -1321,11 +1447,7 @@
   /* read the data and copy it to the return array, then free the buffer as we
      no	longer need it */
   result = hysock_read (hysocketP, (U_8 *)message, localCount,	flags);	
-  if (result > 0)
-    {
-      (*env)->SetByteArrayRegion (env, data, offset, result, message);
-    }
-  hymem_free_memory ( message);	
+  	
   if (result < 0)
     {
       if ((HYPORT_ERROR_SOCKET_CONNRESET == result)
@@ -1342,11 +1464,6 @@
     }
   else
     {
-      /* update	the packet with	the legth of data received.
-	 Since we are connected	we did not get back an address.	 This
-	 address is cached within the PlainDatagramSocket  java	object and is filled in	at
-	 the java level	*/
-      setDatagramPacketLength (env, datagramPacket, result);
       return (jint) result;
     }
 }
@@ -1370,7 +1487,42 @@
 	       jobject inetAddress)
 {
   PORT_ACCESS_FROM_ENV (env);
-  jbyte	*message;
+  jbyte	*message; 
+  jint result =	0;
+
+  message = hymem_allocate_memory(msgLength);	
+  if (message == NULL)
+    {
+      throwNewOutOfMemoryError (env, "");
+      return 0;	
+    }
+  (*env)->GetByteArrayRegion (env, data, offset, msgLength, message);
+  result = Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendDatagramDirectImpl(env, thisClz, 
+      fileDescriptor,(jlong)message, offset, msgLength, targetPort, bindToDevice, trafficClass, inetAddress);
+  hymem_free_memory(message);    
+  return result;
+}
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    sendDatagramDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIIIZILjava/net/InetAddress;)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendDatagramDirectImpl(JNIEnv * env,
+	       jclass thisClz,
+	       jobject
+	       fileDescriptor,
+	       jlong address,	
+	       jint offset,
+	       jint msgLength,
+	       jint targetPort,	
+	       jboolean	
+	       bindToDevice,
+	       jint trafficClass,
+	       jobject inetAddress)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  jbyte	*message = (jbyte *)address;
   jbyte	nhostAddrBytes[HYSOCK_INADDR6_LEN];
   int length;
 
@@ -1401,27 +1553,19 @@
 
   flags	= HYSOCK_NOFLAGS;
 
-  message = hymem_allocate_memory ( msgLength);	
-  if (message == NULL)
-    {
-      throwNewOutOfMemoryError (env, "");
-      return 0;	
-    }
-  (*env)->GetByteArrayRegion (env, data, offset, msgLength, message);
-
-  do
-    {
-      socketP =	
+  socketP =	
 	getJavaIoFileDescriptorContentsAsAPointer (env,	fileDescriptor);
-      if (!hysock_socketIsValid	(socketP))
+    if (!hysock_socketIsValid	(socketP))
 	{
-	  hymem_free_memory ( message);	
 	  throwJavaNetSocketException (env,
 	    sent ==
 	    0 ?	HYPORT_ERROR_SOCKET_BADSOCKET :	
 	  HYPORT_ERROR_SOCKET_INTERRUPTED);
 	  return (jint)	0;
 	}
+		
+  do
+    {
       result =
 	hysock_writeto (socketP, (U_8 *)message + sent, (I_32)	msgLength - sent,
 	flags, &sockaddrP);
@@ -1431,7 +1575,6 @@
     }
   while	(sent <	msgLength);
 
-  hymem_free_memory ( message);	
   if (result < 0)
     {
       throwJavaNetSocketException (env,	result);
@@ -1461,22 +1604,50 @@
 		 jboolean
 		 bindToDevice)
 {
-  PORT_ACCESS_FROM_ENV (env);
-  jbyte	*message;
-  I_32 result =	0;
-  I_32 sent = 0;
-  hysocket_t socketP;
-  int flags = HYSOCK_NOFLAGS;
-
-  /* allocate a	local buffer into which	we will	copy the data to be sent and which we will use	
+	PORT_ACCESS_FROM_ENV (env);
+	jbyte	*message;
+	jint result;
+	/* allocate a local buffer into which	we will	copy the data to be sent and which we will use	
      for the write call	*/
-  message = hymem_allocate_memory ( msgLength);	
-  if (message == NULL)
+	message = hymem_allocate_memory ( msgLength);	
+    if (message == NULL)
     {
       throwNewOutOfMemoryError (env, "");
       return 0;	
     }
-  (*env)->GetByteArrayRegion (env, data, offset, msgLength, message);
+    (*env)->GetByteArrayRegion (env, data, offset, msgLength, message);
+    result = Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendConnectedDatagramDirectImpl(env, thisClz, fileDescriptor, (jlong)message, offset, msgLength, bindToDevice);
+    /* ok	free the buffer	and return the length sent  */
+    hymem_free_memory ( message);
+    return result;    
+}		 
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    sendConnectedDatagramDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIIZ)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendConnectedDatagramDirectImpl(JNIEnv 
+		*env, 
+		jclass 
+		thisClz, 
+		jobject 
+		fileDescriptor, 
+		jlong 
+		address, 
+		jint 
+		offset, 
+		jint 
+		msgLength, 
+		jboolean 
+		bindToDevice)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  jbyte	*message = (jbyte *)address;
+  I_32 result =	0;
+  I_32 sent = 0;
+  hysocket_t socketP;
+  int flags = HYSOCK_NOFLAGS;  
 
   do
     {
@@ -1504,9 +1675,6 @@
       sent += result;
     }
   while	(sent <	msgLength);
-
-  /* ok	free the buffer	and return the length sent or an exception as appropriate  */
-  hymem_free_memory ( message);	
 
 #if defined(LINUX)
   if (result < 0)

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.h?view=diff&rev=501403&r1=501402&r2=501403
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.h (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/shared/OSNetworkSystem.h Tue Jan 30 06:33:41 2007
@@ -103,6 +103,14 @@
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    readSocketDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIII)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_readSocketDirectImpl
+  (JNIEnv *, jclass, jobject, jlong, jint, jint, jint);
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
  * Method:    writeSocketImpl
  * Signature: (Ljava/io/FileDescriptor;[BII)I
  */
@@ -111,6 +119,14 @@
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    writeSocketDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JII)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_writeSocketDirectImpl
+  (JNIEnv *, jclass, jobject, jlong, jint, jint);
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
  * Method:    setNonBlockingImpl
  * Signature: (Ljava/io/FileDescriptor;Z)V
  */
@@ -231,6 +247,14 @@
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    receiveDatagramDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIIIZ)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_receiveDatagramDirectImpl
+  (JNIEnv *, jclass, jobject, jlong, jint, jint, jint, jboolean);
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
  * Method:    recvConnectedDatagramImpl
  * Signature: (Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I
  */
@@ -239,6 +263,14 @@
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    recvConnectedDatagramDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIIIZ)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_recvConnectedDatagramDirectImpl
+  (JNIEnv *, jclass, jobject, jlong, jint, jint, jint, jboolean);
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
  * Method:    sendDatagramImpl
  * Signature: (Ljava/io/FileDescriptor;[BIIIZILjava/net/InetAddress;)I
  */
@@ -247,11 +279,27 @@
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    sendDatagramDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIIIZILjava/net/InetAddress;)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendDatagramDirectImpl
+  (JNIEnv *, jclass, jobject, jlong, jint, jint, jint, jboolean, jint, jobject);
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
  * Method:    sendConnectedDatagramImpl
  * Signature: (Ljava/io/FileDescriptor;[BIIZ)I
  */
 JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendConnectedDatagramImpl
   (JNIEnv *, jclass, jobject, jbyteArray, jint, jint, jboolean);
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    sendConnectedDatagramDirectImpl
+ * Signature: (Ljava/io/FileDescriptor;JIIZ)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendConnectedDatagramDirectImpl
+  (JNIEnv *, jclass, jobject, jlong, jint, jint, jboolean);  
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/unix/libhyluni.exp
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/unix/libhyluni.exp?view=diff&rev=501403&r1=501402&r2=501403
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/unix/libhyluni.exp (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/native/luni/unix/libhyluni.exp Tue Jan 30 06:33:41 2007
@@ -202,7 +202,9 @@
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_createSocketImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_createDatagramSocketImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_readSocketImpl;
+		Java_org_apache_harmony_luni_platform_OSNetworkSystem_readSocketDirectImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_writeSocketImpl;
+		Java_org_apache_harmony_luni_platform_OSNetworkSystem_writeSocketDirectImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_setNonBlockingImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_connectSocketImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_connectWithTimeoutSocketImpl;
@@ -218,9 +220,13 @@
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_socketBindImpl2;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_peekDatagramImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_receiveDatagramImpl;
+		Java_org_apache_harmony_luni_platform_OSNetworkSystem_receiveDatagramDirectImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_recvConnectedDatagramImpl;
+		Java_org_apache_harmony_luni_platform_OSNetworkSystem_recvConnectedDatagramDirectImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendDatagramImpl;
+		Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendDatagramDirectImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendConnectedDatagramImpl;
+		Java_org_apache_harmony_luni_platform_OSNetworkSystem_sendConnectedDatagramDirectImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_createServerStreamSocketImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_createMulticastSocketImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_receiveStreamImpl;

Modified: harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java?view=diff&rev=501403&r1=501402&r2=501403
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java Tue Jan 30 06:33:41 2007
@@ -42,14 +42,14 @@
 import org.apache.harmony.luni.platform.INetworkSystem;
 import org.apache.harmony.luni.platform.Platform;
 import org.apache.harmony.luni.util.ErrorCodeException;
-
-
+import org.apache.harmony.nio.AddressUtil;
 
 /*
  * The default implementation class of java.nio.channels.DatagramChannel.
  * 
  */
-class DatagramChannelImpl extends DatagramChannel implements FileDescriptorHandler{
+class DatagramChannelImpl extends DatagramChannel implements
+        FileDescriptorHandler {
 
     // -------------------------------------------------------------------
     // Class variables
@@ -61,7 +61,7 @@
 
     // default timeout used to nonblocking mode.
     private static final int DEFAULT_TIMEOUT = 1;
-    
+
     private static final int ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK = -211;
 
     // -------------------------------------------------------------------
@@ -86,13 +86,9 @@
     // whether the socket is bound
     boolean isBound = false;
 
-    // lock for read and receive
-    private class ReadLock {}
-    private final Object readLock = new ReadLock();
-
-    // lock for write and send
-    private class WriteLock {}
-    private final Object writeLock = new WriteLock();
+    private final Object readLock = new Object();
+
+    private final Object writeLock = new Object();
 
     // used to store the trafficClass value which is simply returned
     // as the value that was set. We also need it to pass it to methods
@@ -112,11 +108,11 @@
         fd = new FileDescriptor();
         networkSystem.createDatagramSocket(fd, true);
     }
-    
+
     /*
      * for native call
      */
-    private DatagramChannelImpl() throws IOException {
+    private DatagramChannelImpl(){
         super(SelectorProvider.provider());
         fd = new FileDescriptor();
         connectAddress = new InetSocketAddress(0);
@@ -130,6 +126,7 @@
      * Getting the internal DatagramSocket If we have not the socket, we create
      * a new one.
      */
+    @Override
     synchronized public DatagramSocket socket() {
         if (null == socket) {
             socket = new DatagramSocketAdapter(SocketImplProvider
@@ -137,7 +134,7 @@
         }
         return socket;
     }
-    
+
     /**
      * Answer the local address from the IP stack. This method should not be
      * called directly as it does not check the security policy.
@@ -146,7 +143,8 @@
      * @see DatagramSocket
      */
     InetAddress getLocalAddress() {
-        return networkSystem.getSocketLocalAddress(fd, NetUtil.preferIPv6Addresses());
+        return networkSystem.getSocketLocalAddress(fd, NetUtil
+                .preferIPv6Addresses());
     }
 
     // -------------------------------------------------------------------
@@ -157,6 +155,7 @@
      * 
      * @see java.nio.channels.DatagramChannel#isConnected()
      */
+    @Override
     synchronized public boolean isConnected() {
         return connected;
     }
@@ -165,6 +164,7 @@
      * 
      * @see java.nio.channels.DatagramChannel#connect(java.net.SocketAddress)
      */
+    @Override
     synchronized public DatagramChannel connect(SocketAddress address)
             throws IOException {
         // must open
@@ -210,6 +210,7 @@
      * 
      * @see java.nio.channels.DatagramChannel#disconnect()
      */
+    @Override
     synchronized public DatagramChannel disconnect() throws IOException {
         if (!isConnected() || !isOpen()) {
             return this;
@@ -231,9 +232,10 @@
      * 
      * @see java.nio.channels.DatagramChannel#receive(java.nio.ByteBuffer)
      */
+    @Override
     public SocketAddress receive(ByteBuffer target) throws IOException {
         // must not null and not readonly
-        checkNotNullNotReadOnly(target);
+        checkWritable(target);
         // must open
         checkOpen();
 
@@ -256,12 +258,14 @@
                         networkSystem.recvConnectedDatagram(fd, receivePacket,
                                 receivePacket.getData(), receivePacket
                                         .getOffset(),
-                                receivePacket.getLength(), isBlocking()?0:DEFAULT_TIMEOUT, false);
+                                receivePacket.getLength(), isBlocking() ? 0
+                                        : DEFAULT_TIMEOUT, false);
                     } else {
                         networkSystem.receiveDatagram(fd, receivePacket,
                                 receivePacket.getData(), receivePacket
                                         .getOffset(),
-                                receivePacket.getLength(), isBlocking()?0:DEFAULT_TIMEOUT, false);
+                                receivePacket.getLength(), isBlocking() ? 0
+                                        : DEFAULT_TIMEOUT, false);
                     }
 
                     // security check
@@ -297,15 +301,16 @@
      * @see java.nio.channels.DatagramChannel#send(java.nio.ByteBuffer,
      *      java.net.SocketAddress)
      */
-    public int send(ByteBuffer source, SocketAddress address)
+    @Override
+    public int send(ByteBuffer source, SocketAddress socketAddress)
             throws IOException {
         // must not null
         checkNotNull(source);
         // must open
         checkOpen();
 
-        // transfer address
-        InetSocketAddress isa = (InetSocketAddress) address;
+        // transfer socketAddress
+        InetSocketAddress isa = (InetSocketAddress) socketAddress;
         if (null == isa.getAddress()) {
             throw new IOException();
         }
@@ -329,27 +334,36 @@
 
         // the return value.
         int sendCount = 0;
-
         try {
             begin();
-            byte[] array;
+            byte[] array = null;
             int length = source.remaining();
             int oldposition = source.position();
-            int start;
-            if (source.hasArray()) {
-                array = source.array();
-                start = oldposition;
+            int start = oldposition;
+            if (source.isDirect()) {
+                synchronized (writeLock) {
+                    long data_address = AddressUtil
+                            .getDirectBufferAddress(source);
+                    sendCount = networkSystem.sendDatagramDirect(fd,
+                            data_address, start, length, isa.getPort(), false,
+                            trafficClass, isa.getAddress());
+                }
             } else {
-                array = new byte[length];
-                source.get(array);
-                start = 0;
-            }            
-            synchronized (writeLock) {
-                sendCount = networkSystem.sendDatagram(fd, array, start,
-                        length, isa.getPort(), false, trafficClass, isa
-                                .getAddress());
+                if (source.hasArray()) {
+                    array = source.array();
+                    start += source.arrayOffset();
+                } else {
+                    array = new byte[length];
+                    source.get(array);
+                    start = 0;
+                }
+                synchronized (writeLock) {
+                    sendCount = networkSystem.sendDatagram(fd, array, start,
+                            length, isa.getPort(), false, trafficClass, isa
+                                    .getAddress());
+                }
             }
-            source.position(oldposition + sendCount);            
+            source.position(oldposition + sendCount);
             return sendCount;
         } finally {
             end(sendCount >= 0);
@@ -364,25 +378,34 @@
      * 
      * @see java.nio.channels.DatagramChannel#read(java.nio.ByteBuffer)
      */
+    @Override
     public int read(ByteBuffer target) throws IOException {
-        if (null == target){
+        if (null == target) {
             throw new NullPointerException();
         }
         // status must be open and connected
         checkOpenConnected();
         // target buffer must be not null and not readonly
-        checkNotNullNotReadOnly(target);
+        checkWritable(target);
 
-        if (!target.hasRemaining()){
+        if (!target.hasRemaining()) {
             return 0;
-        }        
-        byte[] readArray = new byte[target.remaining()];
-        int readCount;
-        synchronized (readLock) {
-            readCount = readImpl(readArray);
         }
-        if (0 != readCount) {
-            target.put(readArray, 0, readCount);
+
+        int readCount  = 0;
+        if (target.isDirect() || target.hasArray()) {
+            readCount = readImpl(target);
+            if(readCount > 0){
+                target.position(target.position() + readCount);
+            }
+
+        } else {
+            byte[] readArray = new byte[target.remaining()];
+            ByteBuffer readBuffer = ByteBuffer.wrap(readArray);
+            readCount = readImpl(readBuffer);
+            if(readCount > 0){
+                target.put(readArray, 0, readCount);
+            }
         }
         return readCount;
     }
@@ -392,37 +415,38 @@
      * @see java.nio.channels.DatagramChannel#read(java.nio.ByteBuffer[], int,
      *      int)
      */
+    @Override
     public long read(ByteBuffer[] targets, int offset, int length)
             throws IOException {
-        if (length < 0 || offset < 0 || (long)length + (long)offset > targets.length) {
+        if (length < 0 || offset < 0
+                || (long) length + (long) offset > targets.length) {
             throw new IndexOutOfBoundsException();
-        }        
+        }
+
         // status must be open and connected
         checkOpenConnected();
-        
+
         int totalCount = 0;
         for (int val = offset; val < length; val++) {
             // target buffer must be not null and not readonly
-            checkNotNullNotReadOnly(targets[val]);
+            checkWritable(targets[val]);
             totalCount += targets[val].remaining();
         }
+
         // read data to readBuffer, and then transfer data from readBuffer to
         // targets.
-        byte[] readBuffer = new byte[totalCount];
-        int readCount ;
-        synchronized (readLock) {
-            readCount = readImpl(readBuffer);
-        }
-        if (readCount > 0) {
-            int left = readCount;
-            int index = offset;
-            // transfer data from readBuffer to targets
-            while (left > 0) {
-                int putLength = Math.min(targets[index].remaining(), left);                
-                targets[index].put(readBuffer, readCount - left, putLength);
-                index++;
-                left -= putLength;
-            }
+        ByteBuffer readBuffer = ByteBuffer.allocate(totalCount);
+        int readCount;
+        readCount = readImpl(readBuffer);
+        int left = readCount;
+        int index = offset;
+        // transfer data from readBuffer to targets
+        byte[] readArray = readBuffer.array();
+        while (left > 0) {
+            int putLength = Math.min(targets[index].remaining(), left);
+            targets[index].put(readArray, readCount - left, putLength);
+            index++;
+            left -= putLength;
         }
         return readCount;
     }
@@ -430,110 +454,151 @@
     /*
      * read from channel, and store the result in the target.
      */
-    private int readImpl(byte[] target) throws IOException {
-        // the return value
-        int readCount = 0;
-
-        try {
-            begin();
-            // timeout == 0 means block read.
-            // DEFAULT_TIMEOUT is used in non-block mode.
-            int timeout = isBlocking() ? 0 : DEFAULT_TIMEOUT;
-            DatagramPacket pack;
-            pack = new DatagramPacket(target, target.length);
-            if (isConnected()) {
-                readCount = networkSystem.recvConnectedDatagram(fd, pack, pack
-                        .getData(), 0, pack.getLength(), timeout, false);
-            } else {
-                readCount = networkSystem.receiveDatagram(fd, pack, pack
-                        .getData(), 0, pack.getLength(), timeout, false);
+    private int readImpl(ByteBuffer readBuffer) throws IOException {
+        synchronized(readLock){
+            int readCount = 0;
+            try {
+                begin();
+                // timeout == 0 means block read.
+                // DEFAULT_TIMEOUT is used in non-block mode.
+                int timeout = isBlocking() ? 0 : DEFAULT_TIMEOUT;
+                int start = readBuffer.position();
+                int length = readBuffer.remaining();
+                if (readBuffer.isDirect()) {
+                    long address = AddressUtil.getDirectBufferAddress(readBuffer);
+                    if (isConnected()) {
+                        readCount = networkSystem.recvConnectedDatagramDirect(fd,
+                                address, start, length, timeout, false);
+                    } else {
+                        readCount = networkSystem.receiveDatagramDirect(fd,
+                                address, start, length, timeout, false);
+                    }
+                } else {
+                    // the target is assured to have array.
+                    byte[] target = readBuffer.array();
+                    start += readBuffer.arrayOffset();
+                    if (isConnected()) {
+                        readCount = networkSystem.recvConnectedDatagram(fd, null,
+                                target, start, length, timeout, false);
+                    } else {
+                        readCount = networkSystem.receiveDatagram(fd, null, target,
+                                start, length, timeout, false);
+                    }
+                }
+                return readCount;
+            } catch (InterruptedIOException e) {
+                // InterruptedIOException will be thrown when timeout.
+                return 0;
+            } finally {
+                end(readCount > 0);
             }
-            return readCount;
-        } catch (InterruptedIOException e) {
-            // InterruptedIOException will be thrown when timeout.
-            return 0;
-        } finally {
-            end(readCount > 0);
         }
     }
 
     /*
      * @see java.nio.channels.DatagramChannel#write(java.nio.ByteBuffer)
      */
+    @Override
     public int write(ByteBuffer source) throws IOException {
         // source buffer must be not null
         checkNotNull(source);
         // status must be open and connected
         checkOpenConnected();
         // return immediately if source is full
-        if (!source.hasRemaining()){
+        if (!source.hasRemaining()) {
             return 0;
         }
 
-        synchronized (writeLock) {
-            return writeImpl(source);
+        ByteBuffer writeBuffer = null;
+        byte[] writeArray = null;
+        int oldposition = source.position();
+        int result;
+        if (source.isDirect() || source.hasArray()) {
+            writeBuffer = source;
+        } else {
+            writeArray = new byte[source.remaining()];
+            source.get(writeArray);
+            writeBuffer = ByteBuffer.wrap(writeArray);
+        }
+        result = writeImpl(writeBuffer);
+        if (result > 0) {
+            source.position(oldposition + result);
         }
+        return result;
     }
 
     /*
      * @see java.nio.channels.DatagramChannel#write(java.nio.ByteBuffer[], int,
      *      int)
      */
+    @Override
     public long write(ByteBuffer[] sources, int offset, int length)
             throws IOException {
-        if (length < 0 || offset < 0 || (long)length + (long)offset > sources.length) {
+        if (length < 0 || offset < 0
+                || (long) length + (long) offset > sources.length) {
             throw new IndexOutOfBoundsException();
         }
+
         // status must be open and connected
         checkOpenConnected();
-        synchronized (writeLock) {
-            int count = 0;
-            for (int val = offset; val < length; val++) {
-                count = count + sources[val].remaining();
-            }
-            ByteBuffer writeBuf = ByteBuffer.allocate(count);
-            for (int val = offset; val < length; val++) {
-                writeBuf.put(sources[val]);
-            }
-            writeBuf.flip();
-            return writeImpl(writeBuf);
+        int count = calculateByteBufferArray(sources, offset, length);
+        if (0 == count) {
+            return 0;
+        }
+        ByteBuffer writeBuf = ByteBuffer.allocate(count);
+        for (int val = offset; val < length+offset; val++) {
+            ByteBuffer source = sources[val];
+            int oldPosition = source.position();
+            writeBuf.put(source);
+            source.position(oldPosition);
+        }
+        writeBuf.flip();
+        int result = writeImpl(writeBuf);
+        int val = offset;
+        int written = result;
+        while (result > 0) {
+            ByteBuffer source = sources[val];
+            int gap = Math.min(result, source.remaining());
+            source.position(source.position() + gap);
+            val++;
+            result -= gap;
         }
+        return written;
     }
 
     /*
      * write the source. return the count of bytes written.
      */
     private int writeImpl(ByteBuffer buf) throws IOException {
-        // the return value
-        int result = 0;
-        try {
-            begin();            
-            byte[] array;
-            int length = buf.remaining();
-            int oldposition = buf.position();
-            int start;
-            if (buf.hasArray()) {
-                array = buf.array();  
-                start = oldposition;
-            } else {
-                array = new byte[length];
-                buf.get(array);
-                start = 0;
-            }
-            result = networkSystem.sendConnectedDatagram(fd, array, start,
-                    length, isBound);
-            buf.position(oldposition + result);
-            return result;
-        } catch (SocketException e){
-            if (e.getCause() instanceof ErrorCodeException) {
-                if (ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK == ((ErrorCodeException) e
-                        .getCause()).getErrorCode()) {
-                    return result;
+        synchronized(writeLock){
+            int result = 0;
+            try {
+                begin();
+                int length = buf.remaining();
+                int start = buf.position();
+    
+                if (buf.isDirect()) {
+                    long address = AddressUtil.getDirectBufferAddress(buf);
+                    result = networkSystem.sendConnectedDatagramDirect(fd, address,
+                            start, length, isBound);
+                } else {
+                    // buf is assured to have array.
+                    start += buf.arrayOffset();
+                    result = networkSystem.sendConnectedDatagram(fd, buf.array(),
+                            start, length, isBound);
+                }
+                return result;
+            } catch (SocketException e) {
+                if (e.getCause() instanceof ErrorCodeException) {
+                    if (ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK == ((ErrorCodeException) e
+                            .getCause()).getErrorCode()) {
+                        return result;
+                    }
                 }
+                throw e;
+            } finally {
+                end(result > 0);
             }
-            throw e;   
-        } finally {
-            end(result > 0);
         }
     }
 
@@ -544,6 +609,7 @@
     /*
      * do really closing action here
      */
+    @Override
     synchronized protected void implCloseSelectableChannel() throws IOException {
         connected = false;
         if (null != socket && !socket.isClosed()) {
@@ -557,6 +623,8 @@
      * 
      * @see java.nio.channels.spi.AbstractSelectableChannel#implConfigureBlocking(boolean)
      */
+    @Override
+    @SuppressWarnings("unused")
     protected void implConfigureBlocking(boolean blockingMode)
             throws IOException {
         // Do nothing here. For real read/write operation in nonblocking mode,
@@ -600,7 +668,7 @@
      * buffer check, must not null and not read only buffer, for read and
      * receive.
      */
-    private void checkNotNullNotReadOnly(ByteBuffer target) {
+    private void checkWritable(ByteBuffer target) {
         // including checking of NPE.
         if (target.isReadOnly()) {
             throw new IllegalArgumentException();
@@ -618,6 +686,15 @@
         return fd;
     }
 
+    private int calculateByteBufferArray(ByteBuffer[] sources, int offset,
+            int length) {
+        int sum = 0;
+        for (int val = offset; val < offset + length; val++) {
+            sum += sources[val].remaining();
+        }
+        return sum;
+    }
+
     /*
      * The adapter class of DatagramSocket
      */
@@ -627,19 +704,20 @@
          * The internal datagramChannelImpl.
          */
         private DatagramChannelImpl channelImpl;
-        
+
         /*
          * init the datagramSocketImpl and datagramChannelImpl
          */
         DatagramSocketAdapter(DatagramSocketImpl socketimpl,
                 DatagramChannelImpl channelImpl) {
             super(socketimpl);
-            this.channelImpl = channelImpl;            
+            this.channelImpl = channelImpl;
         }
 
         /*
          * get the internal datagramChannelImpl
          */
+        @Override
         public DatagramChannel getChannel() {
             return channelImpl;
         }
@@ -647,6 +725,7 @@
         /*
          * @see java.net.DatagramSocket#isBound()
          */
+        @Override
         public boolean isBound() {
             return channelImpl.isBound;
         }
@@ -654,6 +733,7 @@
         /*
          * @see java.net.DatagramSocket#isConnected()
          */
+        @Override
         public boolean isConnected() {
             return channelImpl.isConnected();
         }
@@ -661,23 +741,26 @@
         /*
          * @see java.net.DatagramSocket#getInetAddress()
          */
+        @Override
         public InetAddress getInetAddress() {
             if (null == channelImpl.connectAddress) {
                 return null;
             }
             return channelImpl.connectAddress.getAddress();
         }
-        
+
         /*
          * @see java.net.DatagramSocket#getLocalAddress()
          */
-        public InetAddress getLocalAddress(){
+        @Override
+        public InetAddress getLocalAddress() {
             return channelImpl.getLocalAddress();
         }
 
         /*
          * @see java.net.DatagramSocket#getPort()
          */
+        @Override
         public int getPort() {
             if (null == channelImpl.connectAddress) {
                 return -1;
@@ -688,6 +771,7 @@
         /*
          * @see java.net.DatagramSocket#bind(java.net.SocketAddress)
          */
+        @Override
         public void bind(SocketAddress localAddr) throws SocketException {
             if (channelImpl.isConnected()) {
                 throw new AlreadyConnectedException();
@@ -699,6 +783,7 @@
         /*
          * @see java.net.DatagramSocket#receive(java.net.DatagramPacket)
          */
+        @Override
         public void receive(DatagramPacket packet) throws IOException {
             if (!channelImpl.isBlocking()) {
                 throw new IllegalBlockingModeException();
@@ -709,16 +794,18 @@
         /*
          * @see java.net.DatagramSocket#send(java.net.DatagramPacket)
          */
+        @Override
         public void send(DatagramPacket packet) throws IOException {
             if (!channelImpl.isBlocking()) {
                 throw new IllegalBlockingModeException();
             }
             super.send(packet);
         }
-        
+
         /*
          * @see java.net.DatagramSocket#close()
          */
+        @Override
         public void close() {
             synchronized (channelImpl) {
                 if (channelImpl.isOpen()) {
@@ -735,6 +822,7 @@
         /*
          * @see java.net.DatagramSocket#disconnect()
          */
+        @Override
         public void disconnect() {
             try {
                 channelImpl.disconnect();

Modified: harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java?view=diff&rev=501403&r1=501402&r2=501403
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java Tue Jan 30 06:33:41 2007
@@ -47,9 +47,9 @@
 import org.apache.harmony.luni.platform.INetworkSystem;
 import org.apache.harmony.luni.platform.Platform;
 import org.apache.harmony.luni.util.ErrorCodeException;
+import org.apache.harmony.nio.AddressUtil;
 import org.apache.harmony.nio.internal.nls.Messages;
 
-
 /*
  * 
  * The default implementation class of java.nio.channels.SocketChannel.
@@ -123,12 +123,9 @@
     // whether the socket is bound
     boolean isBound = false;
 
-    // lock for read and write
-    private class ReadLock {}
-    private final Object readLock = new ReadLock();
+    private final Object readLock = new Object();
 
-    private class WriteLock {}
-    private final Object writeLock = new WriteLock();
+    private final Object writeLock = new Object();
 
     // this content is a point used to set in connect_withtimeout() in pending
     // mode
@@ -157,13 +154,13 @@
     /*
      * for native call
      */
-    private SocketChannelImpl() throws IOException {
-		super(SelectorProvider.provider());
-		fd = new FileDescriptor();
-		connectAddress = new InetSocketAddress(0);
-		status = SOCKET_STATUS_CONNECTED;
-	}
-    
+    private SocketChannelImpl(){
+        super(SelectorProvider.provider());
+        fd = new FileDescriptor();
+        connectAddress = new InetSocketAddress(0);
+        status = SOCKET_STATUS_CONNECTED;
+    }
+
     // Keep this to see if need next version
     // SocketChannelImpl(SelectorProvider selectorProvider, FileDescriptor fd,
     // SocketImpl si) {
@@ -192,6 +189,7 @@
      * Getting the internal Socket If we have not the socket, we create a new
      * one.
      */
+    @Override
     synchronized public Socket socket() {
         if (null == socket) {
             try {
@@ -217,6 +215,7 @@
     /*
      * @see java.nio.channels.SocketChannel#isConnected()
      */
+    @Override
     synchronized public boolean isConnected() {
         return status == SOCKET_STATUS_CONNECTED;
     }
@@ -231,6 +230,7 @@
     /*
      * @see java.nio.channels.SocketChannel#isConnectionPending()
      */
+    @Override
     synchronized public boolean isConnectionPending() {
         return status == SOCKET_STATUS_PENDING;
     }
@@ -238,6 +238,7 @@
     /*
      * @see java.nio.channels.SocketChannel#connect(java.net.SocketAddress)
      */
+    @Override
     public boolean connect(SocketAddress socketAddress) throws IOException {
         // status must be open and unconnected
         checkUnconnected();
@@ -257,7 +258,7 @@
         int result = EOF;
         boolean finished = false;
 
-        try {           
+        try {
             if (!isBound) {
                 // bind
                 networkSystem.bind2(fd, 0, true, InetAddress
@@ -276,7 +277,7 @@
                         inetSocketAddress.getAddress(), inetSocketAddress
                                 .getPort(), HY_SOCK_STEP_START, connectContext);
                 // set back to nonblocking to work around with a bug in portlib
-                if (!this.isBlocking()){
+                if (!this.isBlocking()) {
                     networkSystem.setNonBlocking(fd, true);
                 }
             }
@@ -286,11 +287,11 @@
             if (e instanceof ConnectException && !isBlocking()) {
                 status = SOCKET_STATUS_PENDING;
             } else {
-                if (isOpen()){
+                if (isOpen()) {
                     close();
                     finished = true;
-                }                
-                throw e;                
+                }
+                throw e;
             }
         } finally {
             if (isBlocking()) {
@@ -301,7 +302,7 @@
         // set local port
         localPort = networkSystem.getSocketLocalPort(fd, false);
         localAddress = networkSystem.getSocketLocalAddress(fd, false);
-        
+
         // set the connected address.
         connectAddress = inetSocketAddress;
         synchronized (this) {
@@ -318,6 +319,7 @@
     /*
      * @see java.nio.channels.SocketChannel#finishConnect()
      */
+    @Override
     public boolean finishConnect() throws IOException {
         // status check
         synchronized (this) {
@@ -351,10 +353,10 @@
             isBound = finished;
             localAddress = networkSystem.getSocketLocalAddress(fd, false);
         } catch (ConnectException e) {
-            if (isOpen()){
+            if (isOpen()) {
                 close();
                 finished = true;
-            }     
+            }
             throw e;
         } finally {
             end(finished);
@@ -373,6 +375,7 @@
     /*
      * @see java.nio.channels.SocketChannel#read(java.nio.ByteBuffer)
      */
+    @Override
     public int read(ByteBuffer target) throws IOException {
         if (null == target) {
             throw new NullPointerException();
@@ -381,13 +384,22 @@
         if (!target.hasRemaining()) {
             return 0;
         }
-        byte[] readArray = new byte[target.remaining()];
+        
         int readCount;
-        synchronized (readLock) {
-            readCount = readImpl(readArray);
-        }
-        if (EOF != readCount) {
-            target.put(readArray, 0, readCount);
+        if (target.isDirect() || target.hasArray()) {
+            readCount = readImpl(target);
+            if (readCount > 0) {
+                target.position(target.position() + readCount);
+            }
+        } else {
+            ByteBuffer readBuffer = null;
+            byte[] readArray = null;
+            readArray = new byte[target.remaining()];
+            readBuffer = ByteBuffer.wrap(readArray);
+            readCount = readImpl(readBuffer);
+            if (readCount > 0) {
+                target.put(readArray, 0, readCount);
+            }
         }
         return readCount;
     }
@@ -396,31 +408,31 @@
      * @see java.nio.channels.SocketChannel#read(java.nio.ByteBuffer[], int,
      *      int)
      */
+    @Override
     public long read(ByteBuffer[] targets, int offset, int length)
             throws IOException {
         if (!isIndexValid(targets, offset, length)) {
             throw new IndexOutOfBoundsException();
         }
-        checkOpenConnected();
 
+        checkOpenConnected();
         int totalCount = calculateByteBufferArray(targets, offset, length);
         if (0 == totalCount) {
             return 0;
         }
-        byte[] readBuffer = new byte[totalCount];
+        byte[] readArray = new byte[totalCount];
+        ByteBuffer readBuffer = ByteBuffer.wrap(readArray);
         int readCount;
         // read data to readBuffer, and then transfer data from readBuffer to
         // targets.
-        synchronized (readLock) {
-            readCount = readImpl(readBuffer);
-        }
+        readCount = readImpl(readBuffer);
         if (readCount > 0) {
             int left = readCount;
             int index = offset;
-            // transfer data from readBuffer to targets
+            // transfer data from readArray to targets
             while (left > 0) {
                 int putLength = Math.min(targets[index].remaining(), left);
-                targets[index].put(readBuffer, readCount - left, putLength);
+                targets[index].put(readArray, readCount - left, putLength);
                 index++;
                 left -= putLength;
             }
@@ -430,26 +442,40 @@
 
     private boolean isIndexValid(ByteBuffer[] targets, int offset, int length) {
         return (length >= 0) && (offset >= 0)
-                && (length + offset <= targets.length);
+                && ((long)length + (long)offset <= targets.length);
     }
 
     /*
      * read from channel, and store the result in the target.
-     *
-     * @param target    output parameter
+     * 
+     * @param target output parameter
      */
-    private int readImpl(byte[] target) throws IOException {
-        int readCount = 0;
-        try {
-            if (isBlocking()){
-                begin();
-            }
-            readCount = networkSystem.read(fd, target, 0, target.length,
-                    (isBlocking() ? TIMEOUT_BLOCK : TIMEOUT_NONBLOCK));
-            return readCount;
-        } finally {
-            if (isBlocking()){
-                end(readCount > 0);
+    private int readImpl(ByteBuffer target) throws IOException {
+        synchronized(readLock){
+            int readCount = 0;
+            try {
+                if (isBlocking()) {
+                    begin();
+                }
+                int offset = target.position();
+                int length = target.remaining();
+                if (target.isDirect()) {
+                    long address = AddressUtil.getDirectBufferAddress(target);
+                    readCount = networkSystem.readDirect(fd, address, offset,
+                            length, (isBlocking() ? TIMEOUT_BLOCK
+                                    : TIMEOUT_NONBLOCK));
+                } else {
+                    // target is assured to have array.
+                    byte[] array = target.array();
+                    offset += target.arrayOffset();
+                    readCount = networkSystem.read(fd, array, offset, length,
+                            (isBlocking() ? TIMEOUT_BLOCK : TIMEOUT_NONBLOCK));
+                }
+                return readCount;
+            } finally {
+                if (isBlocking()) {
+                    end(readCount > 0);
+                }
             }
         }
     }
@@ -458,6 +484,7 @@
      * 
      * @see java.nio.channels.SocketChannel#write(java.nio.ByteBuffer)
      */
+    @Override
     public int write(ByteBuffer source) throws IOException {
         if (null == source) {
             throw new NullPointerException();
@@ -466,77 +493,99 @@
         if (!source.hasRemaining()) {
             return 0;
         }
-        synchronized (writeLock) {
-            return writeImpl(source);
-        }
+        return writeImpl(source);
     }
 
     /*
      * @see java.nio.channels.SocketChannel#write(java.nio.ByteBuffer[], int,
      *      int)
      */
+    @Override
     public long write(ByteBuffer[] sources, int offset, int length)
             throws IOException {
         if (!isIndexValid(sources, offset, length)) {
             throw new IndexOutOfBoundsException();
         }
+
         checkOpenConnected();
-        if (0 == calculateByteBufferArray(sources, offset, length)) {
+        int count = calculateByteBufferArray(sources, offset, length);
+        if (0 == count) {
             return 0;
         }
-        synchronized (writeLock) {
-            long writeCount = 0;
-            for (int val = offset; val < offset + length; val++) {
-                writeCount = writeCount + writeImpl(sources[val]);
-            }
-            return writeCount;
+        ByteBuffer writeBuf = ByteBuffer.allocate(count);
+        for (int val = offset; val < length+offset; val++) {
+            ByteBuffer source = sources[val];
+            int oldPosition = source.position();
+            writeBuf.put(source);
+            source.position(oldPosition);
+        }
+        writeBuf.flip();
+        int result = writeImpl(writeBuf);
+        int val = offset;
+        int written = result;
+        while (result > 0) {
+            ByteBuffer source = sources[val];
+            int gap = Math.min(result, source.remaining());
+            source.position(source.position() + gap);
+            val++;
+            result -= gap;
         }
+        return written;
     }
 
-    private int calculateByteBufferArray(ByteBuffer[] sources, int offset, int length){
+    private int calculateByteBufferArray(ByteBuffer[] sources, int offset,
+            int length) {
         int sum = 0;
         for (int val = offset; val < offset + length; val++) {
             sum = sum + sources[val].remaining();
         }
         return sum;
     }
+
     /*
      * write the source. return the count of bytes written.
      */
     private int writeImpl(ByteBuffer source) throws IOException {
-        if (!source.hasRemaining()) {
-            return 0;
-        }
-        int writeCount = 0;
-        try {
-            int pos = source.position();
-            int length = source.remaining();
-            if (isBlocking()){
-                begin();
+        synchronized(writeLock){
+            if (!source.hasRemaining()) {
+                return 0;
             }
-            if (source.hasArray()) {
-                writeCount = networkSystem.write(fd, source.array(), pos,
-                        length);
-            } else {
-                byte[] array = new byte[length];
-                source.get(array);
-                writeCount = networkSystem.write(fd, array, 0, length);
-            }
-            source.position(pos + writeCount);
-        } catch (SocketException e) {
-            if (e.getCause() instanceof ErrorCodeException) {
-                if (ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK == ((ErrorCodeException) e
-                        .getCause()).getErrorCode()) {
-                    return writeCount;
+            int writeCount = 0;
+            try {
+                int pos = source.position();
+                int length = source.remaining();
+                if (isBlocking()) {
+                    begin();
+                }
+                if (source.isDirect()) {
+                    long address = AddressUtil.getDirectBufferAddress(source);
+                    writeCount = networkSystem
+                            .writeDirect(fd, address, pos, length);
+                } else if (source.hasArray()) {
+                    pos += source.arrayOffset();
+                    writeCount = networkSystem.write(fd, source.array(), pos,
+                            length);
+                } else {
+                    byte[] array = new byte[length];
+                    source.get(array);
+                    writeCount = networkSystem.write(fd, array, 0, length);
+                }
+                source.position(pos + writeCount);
+            } catch (SocketException e) {
+                if (e.getCause() instanceof ErrorCodeException) {
+                    if (ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK == ((ErrorCodeException) e
+                            .getCause()).getErrorCode()) {
+                        return writeCount;
+                    }
+                }
+                throw e;
+            } finally {
+                if (isBlocking()) {
+                    end(writeCount >= 0);
                 }
             }
-            throw e;
-        } finally {
-            if (isBlocking()){
-                end(writeCount >= 0);
-            }
+            return writeCount;
         }
-        return writeCount;
     }
 
     // -------------------------------------------------------------------
@@ -606,6 +655,7 @@
     /*
      * do really closing action here
      */
+    @Override
     synchronized protected void implCloseSelectableChannel() throws IOException {
         if (SOCKET_STATUS_CLOSED != status) {
             status = SOCKET_STATUS_CLOSED;
@@ -620,6 +670,7 @@
     /*
      * @see java.nio.channels.spi.AbstractSelectableChannel#implConfigureBlocking(boolean)
      */
+    @Override
     protected void implConfigureBlocking(boolean blockMode) throws IOException {
         synchronized (blockingLock()) {
             networkSystem.setNonBlocking(fd, !blockMode);
@@ -636,7 +687,7 @@
     // -------------------------------------------------------------------
     // Adapter classes for internal socket.
     // -------------------------------------------------------------------
-    
+
     private static class SocketAdapter extends Socket {
 
         // ----------------------------------------------------
@@ -662,6 +713,7 @@
          * 
          * @see java.net.Socket#getChannel()
          */
+        @Override
         public SocketChannel getChannel() {
             return channel;
         }
@@ -670,6 +722,7 @@
          * 
          * @see java.net.Socket#isBound()
          */
+        @Override
         public boolean isBound() {
             return channel.isBound;
         }
@@ -678,6 +731,7 @@
          * 
          * @see java.net.Socket#isConnected()
          */
+        @Override
         public boolean isConnected() {
             return channel.isConnected();
         }
@@ -686,6 +740,7 @@
          * 
          * @see java.net.Socket#getLocalAddress()
          */
+        @Override
         public InetAddress getLocalAddress() {
             try {
                 return channel.getLocalAddress();
@@ -698,6 +753,7 @@
          * 
          * @see java.net.Socket#connect(java.net.SocketAddress, int)
          */
+        @Override
         public void connect(SocketAddress remoteAddr, int timeout)
                 throws IOException {
             if (!channel.isBlocking()) {
@@ -719,6 +775,7 @@
          * 
          * @see java.net.Socket#bind(java.net.SocketAddress)
          */
+        @Override
         public void bind(SocketAddress localAddr) throws IOException {
             if (channel.isConnected()) {
                 throw new AlreadyConnectedException();
@@ -738,6 +795,7 @@
          * 
          * @see java.net.Socket#close()
          */
+        @Override
         public void close() throws IOException {
             synchronized (channel) {
                 if (channel.isOpen()) {
@@ -749,36 +807,46 @@
             }
         }
 
-        
+        @Override
         public boolean getReuseAddress() throws SocketException {
             checkOpen();
             return ((Boolean) socketImpl.getOption(SocketOptions.SO_REUSEADDR))
                     .booleanValue();
         }
-        
+
+        @Override
         public synchronized int getReceiveBufferSize() throws SocketException {
             checkOpen();
-            return ((Integer) socketImpl.getOption(SocketOptions.SO_RCVBUF)).intValue();
+            return ((Integer) socketImpl.getOption(SocketOptions.SO_RCVBUF))
+                    .intValue();
         }
-        
+
+        @Override
         public synchronized int getSendBufferSize() throws SocketException {
             checkOpen();
-            return ((Integer) socketImpl.getOption(SocketOptions.SO_SNDBUF)).intValue();
+            return ((Integer) socketImpl.getOption(SocketOptions.SO_SNDBUF))
+                    .intValue();
         }
-        
+
+        @Override
         public synchronized int getSoTimeout() throws SocketException {
             checkOpen();
-            return ((Integer) socketImpl.getOption(SocketOptions.SO_TIMEOUT)).intValue();
+            return ((Integer) socketImpl.getOption(SocketOptions.SO_TIMEOUT))
+                    .intValue();
         }
-        
+
+        @Override
         public int getTrafficClass() throws SocketException {
             checkOpen();
-            return ((Number) socketImpl.getOption(SocketOptions.IP_TOS)).intValue();
+            return ((Number) socketImpl.getOption(SocketOptions.IP_TOS))
+                    .intValue();
         }
+
         /*
          * 
          * @see java.net.Socket#getKeepAlive()
          */
+        @Override
         public boolean getKeepAlive() throws SocketException {
             checkOpen();
             return ((Boolean) socketImpl.getOption(SocketOptions.SO_KEEPALIVE))
@@ -789,6 +857,7 @@
          * 
          * @see java.net.Socket#getOOBInline()
          */
+        @Override
         public boolean getOOBInline() throws SocketException {
             checkOpen();
             return ((Boolean) socketImpl.getOption(SocketOptions.SO_OOBINLINE))
@@ -799,6 +868,7 @@
          * 
          * @see java.net.Socket#getSoLinger()
          */
+        @Override
         public int getSoLinger() throws SocketException {
             checkOpen();
             return ((Integer) socketImpl.getOption(SocketOptions.SO_LINGER))
@@ -808,15 +878,17 @@
         /*
          * @see java.net.Socket#getTcpNoDelay()
          */
+        @Override
         public boolean getTcpNoDelay() throws SocketException {
             checkOpen();
             return ((Boolean) socketImpl.getOption(SocketOptions.TCP_NODELAY))
                     .booleanValue();
         }
 
-        /* 
+        /*
          * @see java.net.Socket#getOutputStream()
          */
+        @Override
         public OutputStream getOutputStream() throws IOException {
             if (!channel.isOpen()) {
                 // nio.00=Socket is closed
@@ -825,7 +897,7 @@
             if (!channel.isConnected()) {
                 // nio.01=Socket is not connected
                 throw new SocketException(Messages.getString("nio.01")); //$NON-NLS-1$
-            }             
+            }
             if (isOutputShutdown()) {
                 // nio.02=Socket output is shutdown
                 throw new SocketException(Messages.getString("nio.02")); //$NON-NLS-1$
@@ -837,6 +909,7 @@
          * 
          * @see java.net.Socket#getInputStream()
          */
+        @Override
         public InputStream getInputStream() throws IOException {
             if (!channel.isOpen()) {
                 // nio.00=Socket is closed
@@ -845,7 +918,7 @@
             if (!channel.isConnected()) {
                 // nio.01=Socket is not connected
                 throw new SocketException(Messages.getString("nio.01")); //$NON-NLS-1$
-            }             
+            }
             if (isInputShutdown()) {
                 // nio.03=Socket input is shutdown
                 throw new SocketException(Messages.getString("nio.03")); //$NON-NLS-1$
@@ -871,7 +944,6 @@
         }
     }
 
-    
     /*
      * This output stream delegates all operations to the associated channel.
      * Throws an IllegalBlockingModeException if the channel is in non-blocking
@@ -887,16 +959,17 @@
         /*
          * Closes this stream and channel
          * 
-         * @exception IOException
-         *                thrown if an error occurs during the close
+         * @exception IOException thrown if an error occurs during the close
          */
+        @Override
         public void close() throws IOException {
             channel.close();
         }
-        
-        /* 
+
+        /*
          * @see java.io.OutputStream#write(byte[], int, int)
          */
+        @Override
         public void write(byte[] buffer, int offset, int count)
                 throws IOException {
             if (0 > offset || 0 > count || count + offset > buffer.length) {
@@ -905,19 +978,20 @@
             ByteBuffer buf = ByteBuffer.wrap(buffer, offset, count);
             if (!channel.isBlocking()) {
                 throw new IllegalBlockingModeException();
-            }            
+            }
             channel.write(buf);
         }
 
-        /* 
+        /*
          * @see java.io.OutputStream#write(int)
          */
+        @Override
         public void write(int oneByte) throws IOException {
             if (!channel.isBlocking()) {
                 throw new IllegalBlockingModeException();
             }
             ByteBuffer buffer = ByteBuffer.allocate(1);
-            buffer.put((byte)(oneByte & 0xFF));
+            buffer.put((byte) (oneByte & 0xFF));
             channel.write(buffer);
         }
     }
@@ -933,17 +1007,19 @@
         public SocketChannelInputStream(SocketChannel channel) {
             this.channel = channel;
         }
-        
+
         /*
          * Closes this stream and channel.
          */
+        @Override
         public void close() throws IOException {
             channel.close();
         }
 
-        /* 
+        /*
          * @see java.io.InputStream#read()
          */
+        @Override
         public int read() throws IOException {
             if (!channel.isBlocking()) {
                 throw new IllegalBlockingModeException();
@@ -953,9 +1029,10 @@
             return (-1 == result) ? result : buf.get() & 0xFF;
         }
 
-        /* 
+        /*
          * @see java.io.InputStream#read(byte[], int, int)
          */
+        @Override
         public int read(byte[] buffer, int offset, int count)
                 throws IOException {
             if (0 > offset || 0 > count || count + offset > buffer.length) {



Mime
View raw message