Added event-driven server.
[jagi.git] / src / jagi / scgi / Scgi.java
1 package jagi.scgi;
2
3 import jagi.*;
4 import java.util.*;
5 import java.io.*;
6 import java.nio.*;
7 import java.nio.channels.*;
8
9 public class Scgi {
10     public static ByteBuffer readns(ReadableByteChannel sk) throws IOException {
11         int hln = 0;
12         while(true) {
13             int c = Utils.read(sk);
14             if(c == ':')
15                 break;
16             else if((c >= '0') && (c <= '9'))
17                 hln = (hln * 10) + (c - '0');
18             else if(c < 0)
19                 throw(new IOException("unexpected eof in netstring header"));
20             else
21                 throw(new IOException("invalid netstring length byte: " + (c & 0xff)));
22         }
23         ByteBuffer data = Utils.readall(sk, ByteBuffer.allocate(hln));
24         if(Utils.read(sk) != ',')
25             throw(new IOException("non-terminated netstring"));
26         return(data);
27     }
28
29     public static Map<ByteBuffer, ByteBuffer> splithead(ByteBuffer ns) {
30         Map<ByteBuffer, ByteBuffer> ret = new HashMap<>();
31         ByteBuffer k = null;
32         for(int i = 0, p = 0; i < ns.limit(); i++) {
33             if(ns.get(i) == 0) {
34                 ByteBuffer s = ns.duplicate();
35                 s.position(p).limit(i);
36                 if(k == null) {
37                     k = s;
38                 } else {
39                     ret.put(k, s);
40                     k = null;
41                 }
42                 p = i + 1;
43             }
44         }
45         return(ret);
46     }
47
48     public static Map<ByteBuffer, ByteBuffer> readhead(ReadableByteChannel sk) throws IOException {
49         return(splithead(readns(sk)));
50     }
51 }