313ea932413b63b36c5d20cc6cb1a9570205ab2a
[controller.git] / opendaylight / netconf / netconf-util / src / main / java / org / opendaylight / controller / netconf / util / handler / ssh / virtualsocket / ChannelInputStream.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
10
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.Unpooled;
13 import io.netty.channel.ChannelHandlerContext;
14 import io.netty.channel.ChannelInboundHandler;
15
16 import java.io.IOException;
17 import java.io.InputStream;
18
19 /**
20  * Class provides {@link InputStream} functionality to users of virtual socket.
21  */
22 public class ChannelInputStream extends InputStream implements ChannelInboundHandler {
23     private final Object lock = new Object();
24     private final ByteBuf bb = Unpooled.buffer();
25
26     @Override
27     public int read(byte b[], int off, int len) throws IOException {
28         if (b == null) {
29             throw new NullPointerException();
30         } else if (off < 0 || len < 0 || len > b.length - off) {
31             throw new IndexOutOfBoundsException();
32         } else if (len == 0) {
33             return 0;
34         }
35
36         int bytesRead = 1;
37         synchronized (lock) {
38             int c = read();
39
40             b[off] = (byte)c;
41
42             if(this.bb.readableBytes() == 0) {
43                 return bytesRead;
44             }
45
46             int ltr = len-1;
47             ltr = (ltr <= bb.readableBytes()) ? ltr : bb.readableBytes();
48
49             bb.readBytes(b, 1, ltr);
50             bytesRead += ltr;
51         }
52         return bytesRead;
53     }
54
55     @Override
56     public int read() throws IOException {
57         synchronized (lock) {
58             while (this.bb.readableBytes() == 0) {
59                 try {
60                     lock.wait();
61                 } catch (InterruptedException e) {
62                     Thread.currentThread().interrupt();
63                     throw new RuntimeException(e);
64                 }
65             }
66             return this.bb.readByte() & 0xFF;
67         }
68     }
69
70     @Override
71     public int available() throws IOException {
72         synchronized (lock) {
73             return this.bb.readableBytes();
74         }
75     }
76
77     public void channelRegistered(ChannelHandlerContext ctx) {
78         ctx.fireChannelRegistered();
79     }
80
81     public void channelUnregistered(ChannelHandlerContext ctx) {
82         ctx.fireChannelUnregistered();
83     }
84
85     public void channelActive(ChannelHandlerContext ctx) {
86         ctx.fireChannelActive();
87     }
88
89     public void channelInactive(ChannelHandlerContext ctx) {
90         ctx.fireChannelInactive();
91     }
92
93     public void channelRead(ChannelHandlerContext ctx, Object o) {
94         synchronized(lock) {
95             this.bb.discardReadBytes();
96             this.bb.writeBytes((ByteBuf) o);
97             lock.notifyAll();
98         }
99     }
100
101     public void channelReadComplete(ChannelHandlerContext ctx) {
102         ctx.fireChannelReadComplete();
103     }
104
105     public void userEventTriggered(ChannelHandlerContext ctx, Object o) {
106         ctx.fireUserEventTriggered(o);
107     }
108
109     public void channelWritabilityChanged(ChannelHandlerContext ctx) {
110         ctx.fireChannelWritabilityChanged();
111     }
112
113     public void handlerAdded(ChannelHandlerContext ctx) {
114     }
115
116     public void handlerRemoved(ChannelHandlerContext ctx) {
117     }
118
119     public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {
120         ctx.fireExceptionCaught(throwable);
121     }
122 }
123