From 1b37400b2268b82e94bbef9d59f25e68f8a512be Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Sat, 17 Nov 2007 06:37:34 +0100 Subject: [PATCH] Initial work on Java library. --- lib/java/dolda/dolcon/ConnectException.java | 7 ++ lib/java/dolda/dolcon/Connection.java | 173 ++++++++++++++++++++++++++++ lib/java/dolda/dolcon/Response.java | 17 +++ 3 files changed, 197 insertions(+) create mode 100644 lib/java/dolda/dolcon/ConnectException.java create mode 100644 lib/java/dolda/dolcon/Connection.java create mode 100644 lib/java/dolda/dolcon/Response.java diff --git a/lib/java/dolda/dolcon/ConnectException.java b/lib/java/dolda/dolcon/ConnectException.java new file mode 100644 index 0000000..ee3c794 --- /dev/null +++ b/lib/java/dolda/dolcon/ConnectException.java @@ -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 index 0000000..0d85f76 --- /dev/null +++ b/lib/java/dolda/dolcon/Connection.java @@ -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 resps = new LinkedList(); + + 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 resps; + + public Reader(Socket s, Collection 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>lines = new LinkedList>(); + Listtokens = new LinkedList(); + 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(); + if(last) { + synchronized(resps) { + resps.add(new Response(code, lines)); + resps.notifyAll(); + } + lines = new LinkedList>(); + } + 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 index 0000000..5ce1115 --- /dev/null +++ b/lib/java/dolda/dolcon/Response.java @@ -0,0 +1,17 @@ +package dolda.dolcon; + +import java.util.*; + +public class Response { + List>lines; + int code; + + public Response(int code, List>lines) { + this.code = code; + this.lines = lines; + } + + public String toString() { + return("Response " + code + ": " + lines.toString()); + } +} -- 2.11.0