Initial work on Java library.
authorFredrik Tolf <fredrik@dolda2000.com>
Sat, 17 Nov 2007 05:37:34 +0000 (06:37 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Sat, 17 Nov 2007 05:37:34 +0000 (06:37 +0100)
lib/java/dolda/dolcon/ConnectException.java [new file with mode: 0644]
lib/java/dolda/dolcon/Connection.java [new file with mode: 0644]
lib/java/dolda/dolcon/Response.java [new file with mode: 0644]

diff --git a/lib/java/dolda/dolcon/ConnectException.java b/lib/java/dolda/dolcon/ConnectException.java
new file mode 100644 (file)
index 0000000..ee3c794
--- /dev/null
@@ -0,0 +1,7 @@
+package dolda.dolcon;
+
+public class ConnectException extends Exception {
+    public ConnectException(String msg, Exception cause) {
+       super(msg, cause);
+    }
+}
diff --git a/lib/java/dolda/dolcon/Connection.java b/lib/java/dolda/dolcon/Connection.java
new file mode 100644 (file)
index 0000000..0d85f76
--- /dev/null
@@ -0,0 +1,173 @@
+package dolda.dolcon;
+
+import java.io.*;
+import java.net.Socket;
+import java.util.*;
+
+public class Connection {
+    Socket s;
+    Reader reader;
+    LinkedList<Response> resps = new LinkedList<Response>();
+    
+    public Connection(String aspec) throws ConnectException {
+       try {
+           s = new Socket(aspec, 1500);
+       } catch(java.net.UnknownHostException e) {
+           throw(new ConnectException("Could not resolve host " + aspec, e));
+       } catch(IOException e) {
+           throw(new ConnectException("Could not connect to host " + aspec, e));
+       }
+       reader = new Reader(s, resps);
+       reader.start();
+    }
+    
+    static private class Reader extends Thread {
+       Exception error = null;
+       Socket s;
+       Collection<Response> resps;
+       
+       public Reader(Socket s, Collection<Response> resps) {
+           this.s = s;
+           this.resps = resps;
+           setDaemon(true);
+       }
+       
+       public void run() {
+           java.io.Reader r;
+           try {
+               r = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
+           } catch(IOException e) {
+               synchronized(resps) {
+                   resps.notifyAll();
+                   error = e;
+               }
+               return;
+           }
+           String state = "start";
+           StringBuilder ct = new StringBuilder();
+           int code = -1;
+           boolean last = true;
+           List<List<String>>lines = new LinkedList<List<String>>();
+           List<String>tokens = new LinkedList<String>();
+           while(true) {
+               char c;
+               {
+                   int i;
+                   try {
+                       if((i = r.read()) < 0) {
+                           throw(new IOException("The server closed the connection"));
+                       }
+                   } catch(IOException e) {
+                       synchronized(resps) {
+                           resps.notifyAll();
+                           error = e;
+                       }
+                       return;
+                   }
+                   c = (char)i;
+               }
+               eat: do {
+                   if(state == "start") {
+                       if(c == '\r') {
+                           state = "nl";
+                       } else if(Character.isWhitespace(c)) {
+                       } else {
+                           if(code == -1)
+                               state = "code";
+                           else
+                               state = "token";
+                           continue eat;
+                       }
+                   } else if(state == "nl") {
+                       if(c == '\n') {
+                           if(code == -1) {
+                               synchronized(resps) {
+                                   resps.notifyAll();
+                                   try {
+                                       throw(new IOException("Illegal response code " + code + " from the server"));
+                                   } catch(IOException e) {
+                                       error = e;
+                                   }
+                               }
+                               return;
+                           }
+                           lines.add(tokens);
+                           tokens = new LinkedList<String>();
+                           if(last) {
+                               synchronized(resps) {
+                                   resps.add(new Response(code, lines));
+                                   resps.notifyAll();
+                               }
+                               lines = new LinkedList<List<String>>();
+                           }
+                           state = "start";
+                       } else {
+                           state = "start";
+                           continue eat;
+                       }
+                   } else if(state == "code") {
+                       if((c == '-') || Character.isWhitespace(c)) {
+                           last = c != '-';
+                           code = Integer.parseInt(ct.toString());
+                           ct.setLength(0);
+                           state = "start";
+                           continue eat;
+                       } else {
+                           ct.append(c);
+                       }
+                   } else if(state == "token") {
+                       if(Character.isWhitespace(c)) {
+                           tokens.add(ct.toString());
+                           ct.setLength(0);
+                           state = "start";
+                           code = -1;
+                           continue eat;
+                       } else if(c == '\\') {
+                           state = "bs";
+                       } else if(c == '"') {
+                           state = "cited";
+                       } else {
+                           ct.append(c);
+                       }
+                   } else if(state == "bs") {
+                       ct.append(c);
+                       state = "token";
+                   } else if(state == "cited") {
+                       if(c == '\\')
+                           state = "cbs";
+                       else if(c == '"')
+                           state = "token";
+                       else
+                           ct.append(c);
+                   } else if(state == "cbs") {
+                       ct.append(c);
+                       state = "cited";
+                   } else {
+                       throw(new Error("invalid state " + state));
+                   }
+                   break;
+               } while(true);
+           }
+       }
+    }
+
+    protected void finalize() {
+       try {
+           s.close();
+       } catch(IOException e) {
+       }
+       reader.interrupt();
+    }
+
+    public static void main(String[] args) throws Exception {
+       Connection c = new Connection("pc18");
+       while(true) {
+           while(c.resps.size() > 0) {
+               System.out.println(c.resps.remove(0));
+           }
+           synchronized(c.resps) {
+               c.resps.wait();
+           }
+       }
+    }
+}
diff --git a/lib/java/dolda/dolcon/Response.java b/lib/java/dolda/dolcon/Response.java
new file mode 100644 (file)
index 0000000..5ce1115
--- /dev/null
@@ -0,0 +1,17 @@
+package dolda.dolcon;
+
+import java.util.*;
+
+public class Response {
+    List<List<String>>lines;
+    int code;
+    
+    public Response(int code, List<List<String>>lines) {
+       this.code = code;
+       this.lines = lines;
+    }
+    
+    public String toString() {
+       return("Response " + code + ": " + lines.toString());
+    }
+}