1414 */
1515public class FrameReader implements AutoCloseable {
1616
17- private static final int BUFFER_SIZE = 100 ;
18-
1917 private static final int HEADER_SIZE = 8 ;
2018
2119 private final InputStream inputStream ;
2220
23- private boolean rawDetected = false ;
21+ private boolean rawStreamDetected = false ;
22+
23+ private final byte [] rawBuffer = new byte [1000 ];
2424
2525 public FrameReader (InputStream inputStream ) {
2626 this .inputStream = inputStream ;
@@ -35,7 +35,7 @@ private static StreamType streamType(byte streamType) {
3535 case 2 :
3636 return StreamType .STDERR ;
3737 default :
38- throw new IllegalArgumentException ( "invalid streamType" ) ;
38+ return StreamType . RAW ;
3939 }
4040 }
4141
@@ -44,34 +44,55 @@ private static StreamType streamType(byte streamType) {
4444 */
4545 public Frame readFrame () throws IOException {
4646
47- byte [] buffer = new byte [ BUFFER_SIZE ];
47+ if ( rawStreamDetected ) {
4848
49- int readBytes = inputStream .read (buffer );
5049
51- if (readBytes == -1 ) {
52- return null ;
53- }
50+ int read = inputStream .read (rawBuffer );
5451
55- if (rawDetected || readBytes != HEADER_SIZE ) {
56- rawDetected = true ;
52+ return new Frame (StreamType .RAW , Arrays .copyOf (rawBuffer , read ));
5753
58- byte [] read = Arrays .copyOfRange (buffer , 0 , readBytes );
59-
60- return new Frame (StreamType .RAW , read );
6154 } else {
6255
63- int payloadSize = ((buffer [4 ] & 0xff ) << 24 ) + ((buffer [5 ] & 0xff ) << 16 ) + ((buffer [6 ] & 0xff ) << 8 )
64- + (buffer [7 ] & 0xff );
56+ byte [] header = new byte [HEADER_SIZE ];
6557
66- byte [] payload = new byte [payloadSize ];
67- int actualPayloadSize = inputStream .read (payload );
68- if (actualPayloadSize != payloadSize ) {
69- throw new IOException (String .format ("payload must be %d bytes long, but was %d" , payloadSize ,
70- actualPayloadSize ));
58+ int actualHeaderSize = 0 ;
59+
60+ do {
61+ int headerCount = inputStream .read (header , actualHeaderSize , HEADER_SIZE - actualHeaderSize );
62+
63+ if (headerCount == -1 ) {
64+ return null ;
65+ }
66+ actualHeaderSize += headerCount ;
67+ } while (actualHeaderSize < HEADER_SIZE );
68+
69+ StreamType streamType = streamType (header [0 ]);
70+
71+ if (streamType .equals (StreamType .RAW )) {
72+ rawStreamDetected = true ;
73+ return new Frame (StreamType .RAW , Arrays .copyOf (header , HEADER_SIZE ));
7174 }
7275
73- return new Frame (streamType (buffer [0 ]), payload );
76+ int payloadSize = ((header [4 ] & 0xff ) << 24 ) + ((header [5 ] & 0xff ) << 16 ) + ((header [6 ] & 0xff ) << 8 )
77+ + (header [7 ] & 0xff );
7478
79+ byte [] payload = new byte [payloadSize ];
80+ int actualPayloadSize = 0 ;
81+
82+ do {
83+ int count = inputStream .read (payload , actualPayloadSize , payloadSize - actualPayloadSize );
84+
85+ if (count == -1 ) {
86+ if (actualPayloadSize != payloadSize ) {
87+ throw new IOException (String .format ("payload must be %d bytes long, but was %d" , payloadSize ,
88+ actualPayloadSize ));
89+ }
90+ break ;
91+ }
92+ actualPayloadSize += count ;
93+ } while (actualPayloadSize < payloadSize );
94+
95+ return new Frame (streamType , payload );
7596 }
7697 }
7798
0 commit comments