| 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> readhead(ReadableByteChannel sk) throws IOException { |
| 30 | Map<ByteBuffer, ByteBuffer> ret = new HashMap<>(); |
| 31 | ByteBuffer ns = readns(sk); |
| 32 | ByteBuffer k = null; |
| 33 | for(int i = 0, p = 0; i < ns.limit(); i++) { |
| 34 | if(ns.get(i) == 0) { |
| 35 | ByteBuffer s = ns.duplicate(); |
| 36 | s.position(p).limit(i); |
| 37 | if(k == null) { |
| 38 | k = s; |
| 39 | } else { |
| 40 | ret.put(k, s); |
| 41 | k = null; |
| 42 | } |
| 43 | p = i + 1; |
| 44 | } |
| 45 | } |
| 46 | return(ret); |
| 47 | } |
| 48 | } |