Initial work on Java library.
[doldaconnect.git] / lib / java / dolda / dolcon / Connection.java
CommitLineData
1b37400b
FT
1package dolda.dolcon;
2
3import java.io.*;
4import java.net.Socket;
5import java.util.*;
6
7public class Connection {
8 Socket s;
9 Reader reader;
10 LinkedList<Response> resps = new LinkedList<Response>();
11
12 public Connection(String aspec) throws ConnectException {
13 try {
14 s = new Socket(aspec, 1500);
15 } catch(java.net.UnknownHostException e) {
16 throw(new ConnectException("Could not resolve host " + aspec, e));
17 } catch(IOException e) {
18 throw(new ConnectException("Could not connect to host " + aspec, e));
19 }
20 reader = new Reader(s, resps);
21 reader.start();
22 }
23
24 static private class Reader extends Thread {
25 Exception error = null;
26 Socket s;
27 Collection<Response> resps;
28
29 public Reader(Socket s, Collection<Response> resps) {
30 this.s = s;
31 this.resps = resps;
32 setDaemon(true);
33 }
34
35 public void run() {
36 java.io.Reader r;
37 try {
38 r = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
39 } catch(IOException e) {
40 synchronized(resps) {
41 resps.notifyAll();
42 error = e;
43 }
44 return;
45 }
46 String state = "start";
47 StringBuilder ct = new StringBuilder();
48 int code = -1;
49 boolean last = true;
50 List<List<String>>lines = new LinkedList<List<String>>();
51 List<String>tokens = new LinkedList<String>();
52 while(true) {
53 char c;
54 {
55 int i;
56 try {
57 if((i = r.read()) < 0) {
58 throw(new IOException("The server closed the connection"));
59 }
60 } catch(IOException e) {
61 synchronized(resps) {
62 resps.notifyAll();
63 error = e;
64 }
65 return;
66 }
67 c = (char)i;
68 }
69 eat: do {
70 if(state == "start") {
71 if(c == '\r') {
72 state = "nl";
73 } else if(Character.isWhitespace(c)) {
74 } else {
75 if(code == -1)
76 state = "code";
77 else
78 state = "token";
79 continue eat;
80 }
81 } else if(state == "nl") {
82 if(c == '\n') {
83 if(code == -1) {
84 synchronized(resps) {
85 resps.notifyAll();
86 try {
87 throw(new IOException("Illegal response code " + code + " from the server"));
88 } catch(IOException e) {
89 error = e;
90 }
91 }
92 return;
93 }
94 lines.add(tokens);
95 tokens = new LinkedList<String>();
96 if(last) {
97 synchronized(resps) {
98 resps.add(new Response(code, lines));
99 resps.notifyAll();
100 }
101 lines = new LinkedList<List<String>>();
102 }
103 state = "start";
104 } else {
105 state = "start";
106 continue eat;
107 }
108 } else if(state == "code") {
109 if((c == '-') || Character.isWhitespace(c)) {
110 last = c != '-';
111 code = Integer.parseInt(ct.toString());
112 ct.setLength(0);
113 state = "start";
114 continue eat;
115 } else {
116 ct.append(c);
117 }
118 } else if(state == "token") {
119 if(Character.isWhitespace(c)) {
120 tokens.add(ct.toString());
121 ct.setLength(0);
122 state = "start";
123 code = -1;
124 continue eat;
125 } else if(c == '\\') {
126 state = "bs";
127 } else if(c == '"') {
128 state = "cited";
129 } else {
130 ct.append(c);
131 }
132 } else if(state == "bs") {
133 ct.append(c);
134 state = "token";
135 } else if(state == "cited") {
136 if(c == '\\')
137 state = "cbs";
138 else if(c == '"')
139 state = "token";
140 else
141 ct.append(c);
142 } else if(state == "cbs") {
143 ct.append(c);
144 state = "cited";
145 } else {
146 throw(new Error("invalid state " + state));
147 }
148 break;
149 } while(true);
150 }
151 }
152 }
153
154 protected void finalize() {
155 try {
156 s.close();
157 } catch(IOException e) {
158 }
159 reader.interrupt();
160 }
161
162 public static void main(String[] args) throws Exception {
163 Connection c = new Connection("pc18");
164 while(true) {
165 while(c.resps.size() > 0) {
166 System.out.println(c.resps.remove(0));
167 }
168 synchronized(c.resps) {
169 c.resps.wait();
170 }
171 }
172 }
173}