Code example for ByteBuffer

Methods: ByteBuffer.position, compact, get, limit, position

0
         /// \todo refactor this for streaming processing, incl. fail fast on invalid UTF-8 within frame already 
 
         // within frame 
 
         // see if we buffered complete frame 
         if (mFrameBuffer.position() >= mFrameHeader.mTotalLen) {
 
            // cut out frame payload 
            byte[] framePayload = null;
            int oldPosition = mFrameBuffer.position();
            if (mFrameHeader.mPayloadLen > 0) {
               framePayload = new byte[mFrameHeader.mPayloadLen];
               mFrameBuffer.position(mFrameHeader.mHeaderLen);
               mFrameBuffer.get(framePayload, 0, (int) mFrameHeader.mPayloadLen);
            } 
            mFrameBuffer.position(mFrameHeader.mTotalLen);
            mFrameBuffer.limit(oldPosition);
            mFrameBuffer.compact();
 
            if (mFrameHeader.mOpcode > 7) {
               // control frame 
 
               if (mFrameHeader.mOpcode == 8) {
 
                  int code = 1005; // CLOSE_STATUS_CODE_NULL : no status code received
                  String reason = null;
 
                  if (mFrameHeader.mPayloadLen >= 2) {
 
                     // parse and check close code 
                     code = (framePayload[0] & 0xff) * 256 + (framePayload[1] & 0xff);
                     if (code < 1000
                           || (code >= 1000 && code <= 2999 &&
                               code != 1000 && code != 1001 && code != 1002 && code != 1003 && code != 1007 && code != 1008 && code != 1009 && code != 1010 && code != 1011)
                           || code >= 5000) {
 
                        throw new WebSocketException("invalid close code " + code);
                     } 
 
                     // parse and check close reason 
                     if (mFrameHeader.mPayloadLen > 2) {
 
                        byte[] ra = new byte[mFrameHeader.mPayloadLen - 2];
                        System.arraycopy(framePayload, 2, ra, 0, mFrameHeader.mPayloadLen - 2);
 
                        Utf8Validator val = new Utf8Validator();
                        val.validate(ra);
                        if (!val.isValid()) {
                           throw new WebSocketException("invalid close reasons (not UTF-8)"); 
                        } else { 
                           reason = new String(ra, "UTF-8");
                        } 
                     } 
                  } 
                  onClose(code, reason);
 
               } else if (mFrameHeader.mOpcode == 9) {
                  // dispatch WS ping 
                  onPing(framePayload);
 
               } else if (mFrameHeader.mOpcode == 10) {
                  // dispatch WS pong 
                  onPong(framePayload);
 
               } else { 
 
                  // should not arrive here (handled before) 
                  throw new Exception("logic error");
               } 
 
            } else { 
               // message frame 
 
               if (!mInsideMessage) {
                  // new message started 
                  mInsideMessage = true;
                  mMessageOpcode = mFrameHeader.mOpcode;
                  if (mMessageOpcode == 1 && mOptions.getValidateIncomingUtf8()) {
                     mUtf8Validator.reset();
                  } 
               } 
 
               if (framePayload != null) {
 
                  // immediately bail out on message too large 
                  if (mMessagePayload.size() + framePayload.length > mOptions.getMaxMessagePayloadSize()) {
                     throw new WebSocketException("message payload too large"); 
                  } 
 
                  // validate incoming UTF-8 
                  if (mMessageOpcode == 1 && mOptions.getValidateIncomingUtf8() && !mUtf8Validator.validate(framePayload)) {
                     throw new WebSocketException("invalid UTF-8 in text message payload"); 
                  } 
 
                  // buffer frame payload for message 
                  mMessagePayload.write(framePayload);
               } 
 
               // on final frame .. 
               if (mFrameHeader.mFin) {
 
                  if (mMessageOpcode == 1) {
 
                     // verify that UTF-8 ends on codepoint 
                     if (mOptions.getValidateIncomingUtf8() && !mUtf8Validator.isValid()) {
                        throw new WebSocketException("UTF-8 text message payload ended within Unicode code point"); 
                     } 
 
                     // deliver text message 
                     if (mOptions.getReceiveTextMessagesRaw()) {
 
                        // dispatch WS text message as raw (but validated) UTF-8 
                        onRawTextMessage(mMessagePayload.toByteArray());
 
                     } else { 
 
                        // dispatch WS text message as Java String (previously already validated) 
                        String s = new String(mMessagePayload.toByteArray(), "UTF-8");
                        onTextMessage(s);
                     } 
 
                  } else if (mMessageOpcode == 2) {
 
                     // dispatch WS binary message 
                     onBinaryMessage(mMessagePayload.toByteArray());
 
                  } else { 
 
                     // should not arrive here (handled before) 
                     throw new Exception("logic error");
                  } 
 
                  // ok, message completed - reset all 
                  mInsideMessage = false;
                  mMessagePayload.reset();
               } 
            } 
 
            // reset frame 
            mFrameHeader = null;
 
            // reprocess if more data left 
            return mFrameBuffer.position() > 0;
 
         } else { 
 
            // need more data 
            return false;