Mercurial Hosting > luan
diff src/goodjava/rpc/RpcCon.java @ 1402:27efb1fcbcb5
move luan.lib to goodjava
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 17 Sep 2019 01:35:01 -0400 |
parents | src/luan/lib/rpc/RpcCon.java@e8fc6712b468 |
children | 59fd2e8b1b9d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/goodjava/rpc/RpcCon.java Tue Sep 17 01:35:01 2019 -0400 @@ -0,0 +1,132 @@ +package goodjava.rpc; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; +import java.io.EOFException; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.util.List; +import goodjava.parser.ParseException; +import goodjava.json.JsonParser; +import goodjava.json.JsonToString; + + +public class RpcCon { + final Socket socket; + final InputStream in; + final OutputStream out; + InputStream inBinary = null; + long lenBinary = -1; + boolean readSome = false; + + RpcCon(Socket socket) + throws RpcError + { + try { + this.socket = socket; + this.in = socket.getInputStream(); + this.out = socket.getOutputStream(); + } catch(IOException e) { + close(); + throw new RpcError(e); + } + } + + public void close() + throws RpcError + { + try { + socket.close(); + } catch(IOException e) { + throw new RpcError(e); + } + } + + public boolean isClosed() { + return socket.isClosed(); + } + + void write(InputStream in,long lenIn,List list) + throws RpcError + { + if( in != null ) + list.add(0,lenIn); + String json = JsonToString.toString(list); + byte[] aJson = json.getBytes(StandardCharsets.UTF_8); + int len = aJson.length; + byte[] a = new byte[4+len]; + a[0] = (byte)(len >>> 24); + a[1] = (byte)(len >>> 16); + a[2] = (byte)(len >>> 8); + a[3] = (byte)(len >>> 0); + System.arraycopy(aJson,0,a,4,len); + try { + out.write(a); + if( in != null ) { + a = new byte[8192]; + long total = 0; + int n; + while( (n=in.read(a)) != -1 ) { + out.write(a,0,n); + total += n; + } + if( total != lenIn ) { + close(); + throw new RpcError("InputStream wrong length "+total+" when should be "+lenIn); + } + } + } catch(IOException e) { + close(); + throw new RpcError(e); + } + } + + List readJson() + throws RpcError + { + try { + if( inBinary != null ) { + inBinary.close(); + inBinary = null; + lenBinary = -1; + } + readSome = false; + byte[] a = new byte[4]; + readAll(a); + int len = 0; + for( byte b : a ) { + len <<= 8; + len |= b&0xFF; + } + a = new byte[len]; + readAll(a); + String json = new String(a,StandardCharsets.UTF_8); + List list = (List)JsonParser.parse(json); + if( list.get(0) instanceof Long ) { + lenBinary = (Long)list.remove(0); + inBinary = new FixedLengthInputStream(in,lenBinary); + } + return list; + } catch(IOException e) { + close(); + throw new RpcError(e); + } catch(ParseException e) { + close(); + throw new RpcError(e); + } + } + + private void readAll(final byte[] a) throws IOException { + int total = 0; + int n; + while( total < a.length ){ + n = in.read( a, total, a.length-total ); + if( n == -1 ) + throw new EOFException(); + readSome = true; + total += n; + } + } + +}