Removed native components (now in own repositories)
[guacamole.git] / web / guacamole-common / src / main / java / net / sourceforge / guacamole / GuacamoleClient.java
1
2 package net.sourceforge.guacamole;
3
4 /*
5  *  Guacamole - Clientless Remote Desktop
6  *  Copyright (C) 2010  Michael Jumper
7  *
8  *  This program is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU Affero General Public License as published by
10  *  the Free Software Foundation, either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU Affero General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Affero General Public License
19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 import java.io.IOException;
23 import java.net.InetAddress;
24 import java.net.Socket;
25
26 import java.io.InputStream;
27 import java.io.Reader;
28 import java.io.InputStreamReader;
29
30 import java.io.OutputStream;
31 import java.io.Writer;
32 import java.io.OutputStreamWriter;
33
34 import net.sourceforge.guacamole.GuacamoleException;
35
36 public class GuacamoleClient extends Client {
37
38     private Socket sock;
39     private Reader input;
40     private Writer output;
41
42     public GuacamoleClient(String hostname, int port) throws GuacamoleException {
43
44         try {
45             sock = new Socket(InetAddress.getByName(hostname), port);
46             input = new InputStreamReader(sock.getInputStream());
47             output = new OutputStreamWriter(sock.getOutputStream());
48         }
49         catch (IOException e) {
50             throw new GuacamoleException(e);
51         }
52
53     }
54
55     public void write(char[] chunk, int off, int len) throws GuacamoleException {
56         try {
57             output.write(chunk, off, len);
58             output.flush();
59         }
60         catch (IOException e) {
61             throw new GuacamoleException(e);
62         }
63     }
64
65     public void disconnect() throws GuacamoleException {
66         try {
67             sock.close();
68         }
69         catch (IOException e) {
70             throw new GuacamoleException(e);
71         }
72     }
73
74     private int usedLength = 0;
75     private char[] buffer = new char[20000];
76
77     public char[] read() throws GuacamoleException {
78
79         try {
80
81             // While we're blocking, or input is available
82             for (;;) {
83
84                 // If past threshold, resize buffer before reading
85                 if (usedLength > buffer.length/2) {
86                     char[] biggerBuffer = new char[buffer.length*2];
87                     System.arraycopy(buffer, 0, biggerBuffer, 0, usedLength);
88                     buffer = biggerBuffer;
89                 }
90
91                 // Attempt to fill buffer
92                 int numRead = input.read(buffer, usedLength, buffer.length - usedLength);
93                 if (numRead == -1)
94                     return null;
95
96                 int prevLength = usedLength;
97                 usedLength += numRead;
98
99                 for (int i=usedLength-1; i>=prevLength; i--) {
100
101                     char readChar = buffer[i];
102
103                     // If end of instruction, return it.
104                     if (readChar == ';') {
105
106                         // Get instruction
107                         char[] chunk = new char[i+1];
108                         System.arraycopy(buffer, 0, chunk, 0, i+1);
109
110                         // Reset buffer
111                         usedLength -= i+1;
112                         System.arraycopy(buffer, i+1, buffer, 0, usedLength);
113
114                         // Return instruction string
115                         return chunk;
116                     }
117
118                 }
119
120             } // End read loop
121
122         }
123         catch (IOException e) {
124             throw new GuacamoleException(e);
125         }
126
127     }
128
129 }