Blob Blame History Raw
From 8ff5f22e4e15986d50e2866acd84a68230c041d5 Mon Sep 17 00:00:00 2001
From: Konstantin Shabanov <mail@etehtsea.me>
Date: Thu, 6 Apr 2017 12:34:33 +0700
Subject: [PATCH] Move abstract implementations from jnr-unixsocket

---
 .../channels/AbstractNativeDatagramChannel.java    |  79 +++++++++++++++
 .../channels/AbstractNativeSocketChannel.java      | 101 +++++++++++++++++++
 src/main/java/jnr/enxio/channels/Common.java       | 110 +++++++++++++++++++++
 .../jnr/enxio/channels/NativeSocketChannel.java    |  46 ++-------
 4 files changed, 299 insertions(+), 37 deletions(-)
 create mode 100644 src/main/java/jnr/enxio/channels/AbstractNativeDatagramChannel.java
 create mode 100644 src/main/java/jnr/enxio/channels/AbstractNativeSocketChannel.java
 create mode 100644 src/main/java/jnr/enxio/channels/Common.java

diff --git a/src/main/java/jnr/enxio/channels/AbstractNativeDatagramChannel.java b/src/main/java/jnr/enxio/channels/AbstractNativeDatagramChannel.java
new file mode 100644
index 0000000..a48d6bc
--- /dev/null
+++ b/src/main/java/jnr/enxio/channels/AbstractNativeDatagramChannel.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 Fritz Elfert
+ *
+ * This file is part of the JNR project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jnr.enxio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+public abstract class AbstractNativeDatagramChannel extends DatagramChannel
+    implements ByteChannel, NativeSelectableChannel {
+
+    private final Common common;
+
+    public AbstractNativeDatagramChannel(int fd) {
+        this(NativeSelectorProvider.getInstance(), fd);
+    }
+
+    AbstractNativeDatagramChannel(SelectorProvider provider, int fd) {
+        super(provider);
+        common = new Common(fd);
+    }
+
+    public void setFD(int fd) {
+        common.setFD(fd);
+    }
+
+    public final int getFD() {
+        return common.getFD();
+    }
+
+    @Override
+    protected void implCloseSelectableChannel() throws IOException {
+        Native.close(common.getFD());
+    }
+
+    @Override
+    protected void implConfigureBlocking(boolean block) throws IOException {
+        Native.setBlocking(common.getFD(), block);
+    }
+
+    public int read(ByteBuffer dst) throws IOException {
+        return common.read(dst);
+    }
+
+    @Override
+    public long read(ByteBuffer[] dsts, int offset,
+            int length) throws IOException {
+        return common.read(dsts, offset, length);
+    }
+
+    public int write(ByteBuffer src) throws IOException {
+        return common.write(src);
+    }
+
+    @Override
+    public long write(ByteBuffer[] srcs, int offset,
+            int length) throws IOException {
+        return common.write(srcs, offset, length);
+    }
+
+}
diff --git a/src/main/java/jnr/enxio/channels/AbstractNativeSocketChannel.java b/src/main/java/jnr/enxio/channels/AbstractNativeSocketChannel.java
new file mode 100644
index 0000000..65ead06
--- /dev/null
+++ b/src/main/java/jnr/enxio/channels/AbstractNativeSocketChannel.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 Marcus Linke
+ *
+ * This file is part of the JNR project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jnr.enxio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+import jnr.constants.platform.Shutdown;
+
+public abstract class AbstractNativeSocketChannel extends SocketChannel
+    implements ByteChannel, NativeSelectableChannel {
+
+    private final Common common;
+
+    public AbstractNativeSocketChannel(int fd) {
+        this(NativeSelectorProvider.getInstance(), fd);
+    }
+
+    AbstractNativeSocketChannel(SelectorProvider provider, int fd) {
+        super(provider);
+        common = new Common(fd);
+    }
+
+    public void setFD(int fd) {
+        common.setFD(fd);
+    }
+
+    public final int getFD() {
+        return common.getFD();
+    }
+
+    @Override
+    protected void implCloseSelectableChannel() throws IOException {
+        Native.close(common.getFD());
+    }
+
+    @Override
+    protected void implConfigureBlocking(boolean block) throws IOException {
+        Native.setBlocking(common.getFD(), block);
+    }
+
+    public int read(ByteBuffer dst) throws IOException {
+        return common.read(dst);
+    }
+
+    @Override
+    public long read(ByteBuffer[] dsts, int offset,
+            int length) throws IOException {
+        return common.read(dsts, offset, length);
+    }
+
+    public int write(ByteBuffer src) throws IOException {
+        return common.write(src);
+    }
+
+    @Override
+    public long write(ByteBuffer[] srcs, int offset,
+            int length) throws IOException {
+        return common.write(srcs, offset, length);
+    }
+
+    @Override
+    public SocketChannel shutdownInput() throws IOException {
+        int n = Native.shutdown(common.getFD(), SHUT_RD);
+        if (n < 0) {
+            throw new IOException(Native.getLastErrorString());
+        }
+        return this;
+    }
+
+    @Override
+    public SocketChannel shutdownOutput() throws IOException {
+        int n = Native.shutdown(common.getFD(), SHUT_WR);
+        if (n < 0) {
+            throw new IOException(Native.getLastErrorString());
+        }
+        return this;
+    }
+
+    private static final int SHUT_RD = Shutdown.SHUT_RD.intValue();
+    private static final int SHUT_WR = Shutdown.SHUT_WR.intValue();
+}
diff --git a/src/main/java/jnr/enxio/channels/Common.java b/src/main/java/jnr/enxio/channels/Common.java
new file mode 100644
index 0000000..cd750e8
--- /dev/null
+++ b/src/main/java/jnr/enxio/channels/Common.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 Fritz Elfert
+ *
+ * This file is part of the JNR project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jnr.enxio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import jnr.constants.platform.Errno;
+
+/**
+ * Helper class, providing common methods.
+ */
+final class Common {
+
+    private int _fd = -1;
+
+    Common(int fd) {
+        _fd = fd;
+    }
+
+    void setFD(int fd) {
+        _fd = fd;
+    }
+
+    int getFD() {
+        return _fd;
+    }
+
+    int read(ByteBuffer dst) throws IOException {
+        int n = Native.read(_fd, dst);
+        switch (n) {
+            case 0:
+                return -1;
+
+            case -1:
+                switch (Native.getLastError()) {
+                    case EAGAIN:
+                    case EWOULDBLOCK:
+                        return 0;
+
+                    default:
+                        throw new IOException(Native.getLastErrorString());
+                }
+
+            default:
+                return n;
+        }
+    }
+
+    long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException {
+        long total = 0;
+
+        for (int i = 0; i < length; i++) {
+            ByteBuffer dst = dsts[offset + i];
+            long read = read(dst);
+            if (read == -1) {
+                return read;
+            }
+            total += read;
+        }
+
+        return total;
+    }
+
+    int write(ByteBuffer src) throws IOException {
+        int n = Native.write(_fd, src);
+        if (n < 0) {
+            switch (Native.getLastError()) {
+                case EAGAIN:
+                case EWOULDBLOCK:
+                    return 0;
+            default:
+                throw new IOException(Native.getLastErrorString());
+            }
+        }
+
+        return n;
+    }
+
+    long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException {
+
+        long result = 0;
+        int index = 0;
+
+        for (index = offset; index < length; index++) {
+            result += write(srcs[index]);
+        }
+
+        return result;
+    }
+
+}
diff --git a/src/main/java/jnr/enxio/channels/NativeSocketChannel.java b/src/main/java/jnr/enxio/channels/NativeSocketChannel.java
index 445ba1a..082ead1 100644
--- a/src/main/java/jnr/enxio/channels/NativeSocketChannel.java
+++ b/src/main/java/jnr/enxio/channels/NativeSocketChannel.java
@@ -29,7 +29,7 @@
 public class NativeSocketChannel extends AbstractSelectableChannel
         implements ByteChannel, NativeSelectableChannel {
 
-    private final int fd;
+    private final Common common;
     private final int validOps;
 
     public NativeSocketChannel(int fd) {
@@ -42,18 +42,18 @@ public NativeSocketChannel(int fd, int ops) {
 
     NativeSocketChannel(SelectorProvider provider, int fd, int ops) {
         super(provider);
-        this.fd = fd;
+        common = new Common(fd);
         this.validOps = ops;
     }
 
     @Override
     protected void implCloseSelectableChannel() throws IOException {
-       Native.close(fd);
+        Native.close(common.getFD());
     }
 
     @Override
     protected void implConfigureBlocking(boolean block) throws IOException {
-        Native.setBlocking(fd, block);
+        Native.setBlocking(common.getFD(), block);
     }
 
     @Override
@@ -61,54 +61,26 @@ public final int validOps() {
         return validOps;
     }
     public final int getFD() {
-        return fd;
+        return common.getFD();
     }
 
     public int read(ByteBuffer dst) throws IOException {
-        int n = Native.read(fd, dst);
-        switch (n) {
-            case 0:
-                return -1;
-
-            case -1:
-                switch (Native.getLastError()) {
-                    case EAGAIN:
-                    case EWOULDBLOCK:
-                        return 0;
-
-                    default:
-                        throw new IOException(Native.getLastErrorString());
-                }
-
-            default:
-                return n;
-        }
+        return common.read(dst);
     }
 
     public int write(ByteBuffer src) throws IOException {
-        int n = Native.write(fd, src);
-        if (n < 0) {
-            switch (Native.getLastError()) {
-                case EAGAIN:
-                case EWOULDBLOCK:
-                    return 0;
-            default:
-                throw new IOException(Native.getLastErrorString());
-            }
-        }
-
-        return n;
+        return common.write(src);
     }
     
     public void shutdownInput() throws IOException {
-        int n = Native.shutdown(fd, SHUT_RD);
+        int n = Native.shutdown(common.getFD(), SHUT_RD);
         if (n < 0) {
             throw new IOException(Native.getLastErrorString());
         }
     }
     
     public void shutdownOutput() throws IOException {
-        int n = Native.shutdown(fd, SHUT_WR);
+        int n = Native.shutdown(common.getFD(), SHUT_WR);
         if (n < 0) {
             throw new IOException(Native.getLastErrorString());
         }