From 5093e21985b318b6958b1fe5b3adfe87dcbeb244 Mon Sep 17 00:00:00 2001 From: fangli Date: Sat, 8 Oct 2022 22:22:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AF=AD=E9=9F=B3=E6=B5=81?= =?UTF-8?q?=E8=BF=87=E5=A4=A7=E5=AF=BC=E8=87=B4CPU=E5=88=A9=E7=94=A8?= =?UTF-8?q?=E7=8E=87=E8=BE=83=E9=AB=98=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sourceforge/peers/demo/CustomConfig.java | 6 +- .../java/net/sourceforge/peers/Config.java | 2 +- .../net/sourceforge/peers/JavaConfig.java | 4 + .../java/net/sourceforge/peers/XmlConfig.java | 8 +- .../sourceforge/peers/media/MediaManager.java | 2 +- .../sourceforge/peers/media/RtpSender.java | 8 +- .../net/sourceforge/peers/rtp/RtpSession.java | 11 +- .../peers/sip/core/useragent/SipListener.java | 16 +- .../transaction/ServerTransactionUser.java | 2 +- .../peers/stream/MediaPipedInputStream.java | 462 ++++++++++++++++++ .../peers/stream/MediaPipedOutputStream.java | 178 +++++++ pom.xml | 51 +- upgrade.sh | 9 + 13 files changed, 711 insertions(+), 48 deletions(-) create mode 100644 peers-lib/src/main/java/net/sourceforge/peers/stream/MediaPipedInputStream.java create mode 100644 peers-lib/src/main/java/net/sourceforge/peers/stream/MediaPipedOutputStream.java create mode 100644 upgrade.sh diff --git a/peers-demo/src/main/java/net/sourceforge/peers/demo/CustomConfig.java b/peers-demo/src/main/java/net/sourceforge/peers/demo/CustomConfig.java index 9883f0f8..8a1c31ea 100644 --- a/peers-demo/src/main/java/net/sourceforge/peers/demo/CustomConfig.java +++ b/peers-demo/src/main/java/net/sourceforge/peers/demo/CustomConfig.java @@ -60,5 +60,9 @@ public void setPublicInetAddress(InetAddress inetAddress) { @Override public void setRtpPort(int rtpPort) { } @Override public void save() { } @Override public void setAuthorizationUsername(String authorizationUsername) { } - + + public long getRtpSendInterval() { + return 0; + } + } diff --git a/peers-lib/src/main/java/net/sourceforge/peers/Config.java b/peers-lib/src/main/java/net/sourceforge/peers/Config.java index 3249f3d3..7697381f 100644 --- a/peers-lib/src/main/java/net/sourceforge/peers/Config.java +++ b/peers-lib/src/main/java/net/sourceforge/peers/Config.java @@ -51,5 +51,5 @@ public interface Config { public void setMediaFile(String mediaFile); public void setRtpPort(int rtpPort); public void setAuthorizationUsername(String authorizationUsername); - + public long getRtpSendInterval(); } diff --git a/peers-lib/src/main/java/net/sourceforge/peers/JavaConfig.java b/peers-lib/src/main/java/net/sourceforge/peers/JavaConfig.java index a21f438c..7e9d1787 100644 --- a/peers-lib/src/main/java/net/sourceforge/peers/JavaConfig.java +++ b/peers-lib/src/main/java/net/sourceforge/peers/JavaConfig.java @@ -152,6 +152,10 @@ public void setAuthorizationUsername(String authorizationUsername) { this.authorizationUsername = authorizationUsername; } + public long getRtpSendInterval() { + return 19562000; + } + @Override public String getMediaFile() { return mediaFile; diff --git a/peers-lib/src/main/java/net/sourceforge/peers/XmlConfig.java b/peers-lib/src/main/java/net/sourceforge/peers/XmlConfig.java index 6e3e60aa..2a5923bb 100644 --- a/peers-lib/src/main/java/net/sourceforge/peers/XmlConfig.java +++ b/peers-lib/src/main/java/net/sourceforge/peers/XmlConfig.java @@ -52,12 +52,8 @@ public class XmlConfig implements Config { public final static int RTP_DEFAULT_PORT = 8000; private Logger logger; - private File file; private Document document; - - // persistent variables - private InetAddress localInetAddress; private String userPart; private String domain; @@ -365,6 +361,10 @@ public void setAuthorizationUsername(String authorizationUsername) { authUserNode.setTextContent(authorizationUsername); } + public long getRtpSendInterval() { + return 0; + } + @Override public String getMediaFile() { return mediaFile; diff --git a/peers-lib/src/main/java/net/sourceforge/peers/media/MediaManager.java b/peers-lib/src/main/java/net/sourceforge/peers/media/MediaManager.java index 0c54cb54..c90f6173 100644 --- a/peers-lib/src/main/java/net/sourceforge/peers/media/MediaManager.java +++ b/peers-lib/src/main/java/net/sourceforge/peers/media/MediaManager.java @@ -274,7 +274,7 @@ public void sendDtmf(char digit) { public void stopSession() { if (rtpSession != null) { rtpSession.stop(); - while (!rtpSession.isSocketClosed()) { + while (rtpSession !=null && !rtpSession.isSocketClosed()) { try { Thread.sleep(15); } catch (InterruptedException e) { diff --git a/peers-lib/src/main/java/net/sourceforge/peers/media/RtpSender.java b/peers-lib/src/main/java/net/sourceforge/peers/media/RtpSender.java index 093ec30f..d73c377b 100644 --- a/peers-lib/src/main/java/net/sourceforge/peers/media/RtpSender.java +++ b/peers-lib/src/main/java/net/sourceforge/peers/media/RtpSender.java @@ -100,8 +100,7 @@ public void run() { long offset = 0; long lastSentTime = System.nanoTime(); // indicate if its the first time that we send a packet (dont wait) - boolean firstTime = true; - + int firstTimes = 0; while (!isStopped) { numBytesRead = 0; try { @@ -150,12 +149,13 @@ public void run() { timestamp += buf_size; } rtpPacket.setTimestamp(timestamp); - if (firstTime) { + if (firstTimes < 15) { rtpSession.send(rtpPacket); lastSentTime = System.nanoTime(); - firstTime = false; + firstTimes++; continue; } + // todo改成config里取 sleepTime = 19500000 - (System.nanoTime() - lastSentTime) + offset; if (sleepTime > 0) { try { diff --git a/peers-lib/src/main/java/net/sourceforge/peers/rtp/RtpSession.java b/peers-lib/src/main/java/net/sourceforge/peers/rtp/RtpSession.java index ee258849..1cb3308c 100644 --- a/peers-lib/src/main/java/net/sourceforge/peers/rtp/RtpSession.java +++ b/peers-lib/src/main/java/net/sourceforge/peers/rtp/RtpSession.java @@ -174,18 +174,9 @@ public Void run() { } class Receiver implements Runnable { - + private final byte[] buf = new byte[512]; @Override public void run() { - int receiveBufferSize; - try { - receiveBufferSize = datagramSocket.getReceiveBufferSize(); - } catch (SocketException e) { - logger.error("cannot get datagram socket receive buffer size", - e); - return; - } - byte[] buf = new byte[receiveBufferSize]; final DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length); final int noException = 0; diff --git a/peers-lib/src/main/java/net/sourceforge/peers/sip/core/useragent/SipListener.java b/peers-lib/src/main/java/net/sourceforge/peers/sip/core/useragent/SipListener.java index de9c5adc..7e480338 100644 --- a/peers-lib/src/main/java/net/sourceforge/peers/sip/core/useragent/SipListener.java +++ b/peers-lib/src/main/java/net/sourceforge/peers/sip/core/useragent/SipListener.java @@ -25,20 +25,20 @@ public interface SipListener { - public void registering(SipRequest sipRequest); + void registering(SipRequest sipRequest); - public void registerSuccessful(SipResponse sipResponse); + void registerSuccessful(SipResponse sipResponse); - public void registerFailed(SipResponse sipResponse); + void registerFailed(SipResponse sipResponse); - public void incomingCall(SipRequest sipRequest, SipResponse provResponse); + void incomingCall(SipRequest sipRequest, SipResponse provResponse); - public void remoteHangup(SipRequest sipRequest); + void remoteHangup(SipRequest sipRequest); - public void ringing(SipResponse sipResponse); + void ringing(SipResponse sipResponse); - public void calleePickup(SipResponse sipResponse); + void calleePickup(SipResponse sipResponse); - public void error(SipResponse sipResponse); + void error(SipResponse sipResponse); } diff --git a/peers-lib/src/main/java/net/sourceforge/peers/sip/transaction/ServerTransactionUser.java b/peers-lib/src/main/java/net/sourceforge/peers/sip/transaction/ServerTransactionUser.java index b17e7080..cfab6b35 100644 --- a/peers-lib/src/main/java/net/sourceforge/peers/sip/transaction/ServerTransactionUser.java +++ b/peers-lib/src/main/java/net/sourceforge/peers/sip/transaction/ServerTransactionUser.java @@ -21,5 +21,5 @@ public interface ServerTransactionUser { - public void transactionFailure(); + void transactionFailure(); } diff --git a/peers-lib/src/main/java/net/sourceforge/peers/stream/MediaPipedInputStream.java b/peers-lib/src/main/java/net/sourceforge/peers/stream/MediaPipedInputStream.java new file mode 100644 index 00000000..3c2d8a6e --- /dev/null +++ b/peers-lib/src/main/java/net/sourceforge/peers/stream/MediaPipedInputStream.java @@ -0,0 +1,462 @@ +/* + * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package net.sourceforge.peers.stream; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A piped input stream should be connected + * to a piped output stream; the piped input + * stream then provides whatever data bytes + * are written to the piped output stream. + * Typically, data is read from a PipedInputStream + * object by one thread and data is written + * to the corresponding MediaPipedOutputStream + * by some other thread. Attempting to use + * both objects from a single thread is not + * recommended, as it may deadlock the thread. + * The piped input stream contains a buffer, + * decoupling read operations from write operations, + * within limits. + * A pipe is said to be broken if a + * thread that was providing data bytes to the connected + * piped output stream is no longer alive. + * + * @author James Gosling + * @see java.io.PipedOutputStream + * @since JDK1.0 + */ +public class MediaPipedInputStream extends InputStream { + + + boolean closedByWriter = false; + volatile boolean closedByReader = false; + boolean connected = false; + + /* REMIND: identification of the read and write sides needs to be + more sophisticated. Either using thread groups (but what about + pipes within a thread?) or using finalization (but it may be a + long time until the next GC). */ + Thread readSide; + Thread writeSide; + + private static final int DEFAULT_PIPE_SIZE = 1024; + + /** + * The default size of the pipe's circular input buffer. + * @since JDK1.1 + */ + // This used to be a constant before the pipe size was allowed + // to change. This field will continue to be maintained + // for backward compatibility. + protected static final int PIPE_SIZE = DEFAULT_PIPE_SIZE; + + /** + * The circular buffer into which incoming data is placed. + * @since JDK1.1 + */ + protected byte buffer[]; + + /** + * The index of the position in the circular buffer at which the + * next byte of data will be stored when received from the connected + * piped output stream. in<0 implies the buffer is empty, + * in==out implies the buffer is full + * @since JDK1.1 + */ + protected int in = -1; + + /** + * The index of the position in the circular buffer at which the next + * byte of data will be read by this piped input stream. + * @since JDK1.1 + */ + protected int out = 0; + + /** + * Creates a PipedInputStream so + * that it is connected to the piped output + * stream src. Data bytes written + * to src will then be available + * as input from this stream. + * + * @param src the stream to connect to. + * @exception IOException if an I/O error occurs. + */ + public MediaPipedInputStream(MediaPipedOutputStream src) throws IOException { + this(src, DEFAULT_PIPE_SIZE); + } + + /** + * Creates a PipedInputStream so that it is + * connected to the piped output stream + * src and uses the specified pipe size for + * the pipe's buffer. + * Data bytes written to src will then + * be available as input from this stream. + * + * @param src the stream to connect to. + * @param pipeSize the size of the pipe's buffer. + * @exception IOException if an I/O error occurs. + * @exception IllegalArgumentException if {@code pipeSize <= 0}. + * @since 1.6 + */ + public MediaPipedInputStream(MediaPipedOutputStream src, int pipeSize) + throws IOException { + initPipe(pipeSize); + connect(src); + } + + /** + * Creates a PipedInputStream so + * that it is not yet {@linkplain #connect(cn.com.autohome.aaa.aidcc.robot.soft.phone.peers.stream.MediaPipedOutputStream) + * connected}. + * It must be {@linkplain java.io.PipedOutputStream#connect( + * java.io.PipedInputStream) connected} to a + * PipedOutputStream before being used. + */ + public MediaPipedInputStream() { + initPipe(DEFAULT_PIPE_SIZE); + } + + /** + * Creates a PipedInputStream so that it is not yet + * {@linkplain #connect(cn.com.autohome.aaa.aidcc.robot.soft.phone.peers.stream.MediaPipedOutputStream) connected} and + * uses the specified pipe size for the pipe's buffer. + * It must be {@linkplain java.io.PipedOutputStream#connect( + * java.io.PipedInputStream) + * connected} to a PipedOutputStream before being used. + * + * @param pipeSize the size of the pipe's buffer. + * @exception IllegalArgumentException if {@code pipeSize <= 0}. + * @since 1.6 + */ + public MediaPipedInputStream(int pipeSize) { + initPipe(pipeSize); + } + + private void initPipe(int pipeSize) { + if (pipeSize <= 0) { + throw new IllegalArgumentException("Pipe Size <= 0"); + } + buffer = new byte[pipeSize]; + } + + /** + * Causes this piped input stream to be connected + * to the piped output stream src. + * If this object is already connected to some + * other piped output stream, an IOException + * is thrown. + *

+ * If src is an + * unconnected piped output stream and snk + * is an unconnected piped input stream, they + * may be connected by either the call: + * + *

snk.connect(src) 
+ *

+ * or the call: + * + *

src.connect(snk) 
+ *

+ * The two calls have the same effect. + * + * @param src The piped output stream to connect to. + * @exception IOException if an I/O error occurs. + */ + public void connect(MediaPipedOutputStream src) throws IOException { + src.connect(this); + } + + /** + * Receives a byte of data. This method will block if no input is + * available. + * @param b the byte being received + * @exception IOException If the pipe is broken, + * {@link #connect(cn.com.autohome.aaa.aidcc.robot.soft.phone.peers.stream.MediaPipedOutputStream) unconnected}, + * closed, or if an I/O error occurs. + * @since JDK1.1 + */ + protected synchronized void receive(int b) throws IOException { + checkStateForReceive(); + writeSide = Thread.currentThread(); + if (in == out) + awaitSpace(); + if (in < 0) { + in = 0; + out = 0; + } + buffer[in++] = (byte)(b & 0xFF); + if (in >= buffer.length) { + in = 0; + } + } + + /** + * Receives data into an array of bytes. This method will + * block until some input is available. + * @param b the buffer into which the data is received + * @param off the start offset of the data + * @param len the maximum number of bytes received + * @exception IOException If the pipe is broken, + * {@link #connect(cn.com.autohome.aaa.aidcc.robot.soft.phone.peers.stream.MediaPipedOutputStream) unconnected}, + * closed,or if an I/O error occurs. + */ + synchronized void receive(byte b[], int off, int len) throws IOException { + checkStateForReceive(); + writeSide = Thread.currentThread(); + int bytesToTransfer = len; + while (bytesToTransfer > 0) { + if (in == out) + awaitSpace(); + int nextTransferAmount = 0; + if (out < in) { + nextTransferAmount = buffer.length - in; + } else if (in < out) { + if (in == -1) { + in = out = 0; + nextTransferAmount = buffer.length - in; + } else { + nextTransferAmount = out - in; + } + } + if (nextTransferAmount > bytesToTransfer) + nextTransferAmount = bytesToTransfer; + assert(nextTransferAmount > 0); + System.arraycopy(b, off, buffer, in, nextTransferAmount); + bytesToTransfer -= nextTransferAmount; + off += nextTransferAmount; + in += nextTransferAmount; + if (in >= buffer.length) { + in = 0; + } + } + } + + private void checkStateForReceive() throws IOException { + if (!connected) { + throw new IOException("Pipe not connected"); + } else if (closedByWriter || closedByReader) { + throw new IOException("Pipe closed"); + } else if (readSide != null && !readSide.isAlive()) { + throw new IOException("Read end dead"); + } + } + + private void awaitSpace() throws IOException { + while (in == out) { + checkStateForReceive(); + + /* full: kick any waiting readers */ + notifyAll(); + try { + // 语音播放,不太适合等待1s + wait(20); + } catch (InterruptedException ex) { + throw new java.io.InterruptedIOException(); + } + } + } + + /** + * Notifies all waiting threads that the last byte of data has been + * received. + */ + synchronized void receivedLast() { + closedByWriter = true; + notifyAll(); + } + + /** + * Reads the next byte of data from this piped input stream. The + * value byte is returned as an int in the range + * 0 to 255. + * This method blocks until input data is available, the end of the + * stream is detected, or an exception is thrown. + * + * @return the next byte of data, or -1 if the end of the + * stream is reached. + * @exception IOException if the pipe is + * {@link #connect(cn.com.autohome.aaa.aidcc.robot.soft.phone.peers.stream.MediaPipedOutputStream) unconnected}, + * broken, closed, + * or if an I/O error occurs. + */ + public synchronized int read() throws IOException { + if (!connected) { + throw new IOException("Pipe not connected"); + } else if (closedByReader) { + throw new IOException("Pipe closed"); + } else if (writeSide != null && !writeSide.isAlive() + && !closedByWriter && (in < 0)) { + throw new IOException("Write end dead"); + } + + readSide = Thread.currentThread(); + int trials = 2; + while (in < 0) { + if (closedByWriter) { + /* closed by writer, return EOF */ + return -1; + } + if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) { + throw new IOException("Pipe broken"); + } + /* might be a writer waiting */ + notifyAll(); + try { + // 语音播放,不太适合等待1s + wait(20); + } catch (InterruptedException ex) { + throw new java.io.InterruptedIOException(); + } + } + int ret = buffer[out++] & 0xFF; + if (out >= buffer.length) { + out = 0; + } + if (in == out) { + /* now empty */ + in = -1; + } + + return ret; + } + + /** + * Reads up to len bytes of data from this piped input + * stream into an array of bytes. Less than len bytes + * will be read if the end of the data stream is reached or if + * len exceeds the pipe's buffer size. + * If len is zero, then no bytes are read and 0 is returned; + * otherwise, the method blocks until at least 1 byte of input is + * available, end of the stream has been detected, or an exception is + * thrown. + * + * @param b the buffer into which the data is read. + * @param off the start offset in the destination array b + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * -1 if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If b is null. + * @exception IndexOutOfBoundsException If off is negative, + * len is negative, or len is greater than + * b.length - off + * @exception IOException if the pipe is broken, + * {@link #connect(cn.com.autohome.aaa.aidcc.robot.soft.phone.peers.stream.MediaPipedOutputStream) unconnected}, + * closed, or if an I/O error occurs. + */ + public synchronized int read(byte b[], int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + + /* possibly wait on the first character */ + int c = read(); + if (c < 0) { + return -1; + } + b[off] = (byte) c; + int rlen = 1; + while ((in >= 0) && (len > 1)) { + + int available; + + if (in > out) { + available = Math.min((buffer.length - out), (in - out)); + } else { + available = buffer.length - out; + } + + // A byte is read beforehand outside the loop + if (available > (len - 1)) { + available = len - 1; + } + System.arraycopy(buffer, out, b, off + rlen, available); + out += available; + rlen += available; + len -= available; + + if (out >= buffer.length) { + out = 0; + } + if (in == out) { + /* now empty */ + in = -1; + } + } + return rlen; + } + + /** + * Returns the number of bytes that can be read from this input + * stream without blocking. + * + * @return the number of bytes that can be read from this input stream + * without blocking, or {@code 0} if this input stream has been + * closed by invoking its {@link #close()} method, or if the pipe + * is {@link #connect(cn.com.autohome.aaa.aidcc.robot.soft.phone.peers.stream.MediaPipedOutputStream) unconnected}, or + * broken. + * + * @exception IOException if an I/O error occurs. + * @since JDK1.0.2 + */ + public synchronized int available() throws IOException { + if(in < 0) + return 0; + else if(in == out) + return buffer.length; + else if (in > out) + return in - out; + else + return in + buffer.length - out; + } + + /** + * Closes this piped input stream and releases any system resources + * associated with the stream. + * + * @exception IOException if an I/O error occurs. + */ + public void close() throws IOException { + closedByReader = true; + synchronized (this) { + in = -1; + } + } + + @Override + public synchronized void reset() throws IOException { + this.out = 0; + this.in = -1; + this.notifyAll(); + } +} diff --git a/peers-lib/src/main/java/net/sourceforge/peers/stream/MediaPipedOutputStream.java b/peers-lib/src/main/java/net/sourceforge/peers/stream/MediaPipedOutputStream.java new file mode 100644 index 00000000..152ea400 --- /dev/null +++ b/peers-lib/src/main/java/net/sourceforge/peers/stream/MediaPipedOutputStream.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package net.sourceforge.peers.stream; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * A piped output stream can be connected to a piped input stream + * to create a communications pipe. The piped output stream is the + * sending end of the pipe. Typically, data is written to a + * PipedOutputStream object by one thread and data is + * read from the connected PipedInputStream by some + * other thread. Attempting to use both objects from a single thread + * is not recommended as it may deadlock the thread. + * The pipe is said to be broken if a + * thread that was reading data bytes from the connected piped input + * stream is no longer alive. + * + * @author James Gosling + * @see java.io.PipedInputStream + * @since JDK1.0 + */ +public class MediaPipedOutputStream extends OutputStream { + + /* REMIND: identification of the read and write sides needs to be + more sophisticated. Either using thread groups (but what about + pipes within a thread?) or using finalization (but it may be a + long time until the next GC). */ + private MediaPipedInputStream sink; + + /** + * Creates a piped output stream connected to the specified piped + * input stream. Data bytes written to this stream will then be + * available as input from snk. + * + * @param snk The piped input stream to connect to. + * @exception IOException if an I/O error occurs. + */ + public MediaPipedOutputStream(MediaPipedInputStream snk) throws IOException { + connect(snk); + } + + /** + * Creates a piped output stream that is not yet connected to a + * piped input stream. It must be connected to a piped input stream, + * either by the receiver or the sender, before being used. + * + * @see java.io.PipedInputStream#connect(java.io.PipedOutputStream) + * @see java.io.PipedOutputStream#connect(java.io.PipedInputStream) + */ + public MediaPipedOutputStream() { + } + + /** + * Connects this piped output stream to a receiver. If this object + * is already connected to some other piped input stream, an + * IOException is thrown. + *

+ * If snk is an unconnected piped input stream and + * src is an unconnected piped output stream, they may + * be connected by either the call: + *

+     * src.connect(snk)
+ * or the call: + *
+     * snk.connect(src)
+ * The two calls have the same effect. + * + * @param snk the piped input stream to connect to. + * @exception IOException if an I/O error occurs. + */ + public synchronized void connect(MediaPipedInputStream snk) throws IOException { + if (snk == null) { + throw new NullPointerException(); + } else if (sink != null || snk.connected) { + throw new IOException("Already connected"); + } + sink = snk; + snk.in = -1; + snk.out = 0; + snk.connected = true; + } + + /** + * Writes the specified byte to the piped output stream. + *

+ * Implements the write method of OutputStream. + * + * @param b the byte to be written. + * @exception IOException if the pipe is broken, + * {@link #connect(java.io.PipedInputStream) unconnected}, + * closed, or if an I/O error occurs. + */ + public void write(int b) throws IOException { + if (sink == null) { + throw new IOException("Pipe not connected"); + } + sink.receive(b); + } + + /** + * Writes len bytes from the specified byte array + * starting at offset off to this piped output stream. + * This method blocks until all the bytes are written to the output + * stream. + * + * @param b the data. + * @param off the start offset in the data. + * @param len the number of bytes to write. + * @exception IOException if the pipe is broken, + * {@link #connect(java.io.PipedInputStream) unconnected}, + * closed, or if an I/O error occurs. + */ + public void write(byte b[], int off, int len) throws IOException { + if (sink == null) { + throw new IOException("Pipe not connected"); + } else if (b == null) { + throw new NullPointerException(); + } else if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) > b.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + sink.receive(b, off, len); + } + + /** + * Flushes this output stream and forces any buffered output bytes + * to be written out. + * This will notify any readers that bytes are waiting in the pipe. + * + * @exception IOException if an I/O error occurs. + */ + public synchronized void flush() throws IOException { + if (sink != null) { + synchronized (sink) { + sink.notifyAll(); + } + } + } + + /** + * Closes this piped output stream and releases any system resources + * associated with this stream. This stream may no longer be used for + * writing bytes. + * + * @exception IOException if an I/O error occurs. + */ + public void close() throws IOException { + if (sink != null) { + sink.receivedLast(); + } + } +} diff --git a/pom.xml b/pom.xml index a1bd43f6..d1566281 100644 --- a/pom.xml +++ b/pom.xml @@ -1,24 +1,39 @@ - - 4.0.0 + + 4.0.0 - net.sourceforge.peers - peers - 0.5.1-SNAPSHOT - pom + net.sourceforge.peers + peers + 0.5.1-SNAPSHOT + pom - - UTF-8 - + + UTF-8 + - - peers-demo - peers-doc - peers-gui - peers-javaxsound - peers-js - peers-jws - peers-lib - + + peers-demo + peers-doc + peers-gui + peers-javaxsound + peers-js + peers-jws + peers-lib + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + \ No newline at end of file diff --git a/upgrade.sh b/upgrade.sh new file mode 100644 index 00000000..1913f79f --- /dev/null +++ b/upgrade.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +cd ${DIR} +mvn -e versions:set \ + -DgroupId=net.sourceforge.peers \ + -DartifactId=peers \ + -DnewVersion=0.5.2-SNAPSHOT \ + -DgenerateBackupPoms=false +mvn -e clean compile deploy -DskipTests