protected boolean parseCommand()

in artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/v11/StompFrameHandlerV11.java [387:577]


      protected boolean parseCommand() throws ActiveMQStompException {
         int offset = 0;
         boolean nextChar = false;

         //check for ping
         // Some badly behaved STOMP clients add a \n *after* the terminating NUL char at the end of the
         // STOMP frame this can manifest as an extra \n at the beginning when the
         // next STOMP frame is read - we need to deal with this.
         // Besides, Stomp 1.2 allows for extra EOLs after NULL (i.e.
         // either "[\r]\n"s or "\n"s)
         while (true) {
            if (workingBuffer[offset] == NEW_LINE) {
               //client ping
               nextChar = false;
            } else if (workingBuffer[offset] == CR) {
               if (nextChar)
                  throw BUNDLE.invalidTwoCRs().setHandler(handler);
               nextChar = true;
            } else {
               break;
            }
            offset++;
            if (offset == data)
               return false; //no more bytes
         }

         if (nextChar) {
            throw BUNDLE.badCRs().setHandler(handler);
         }

         //if some EOLs have been processed, drop those bytes before parsing command
         if (offset > 0) {
            System.arraycopy(workingBuffer, offset, workingBuffer, 0, data - offset);
            data = data - offset;
            offset = 0;
         }

         if (data < 4) {
            // Need at least four bytes to identify the command
            // - up to 3 bytes for the command name + potentially another byte for a leading \n
            return false;
         }

         byte b = workingBuffer[offset];

         switch (b) {
            case A: {
               if (workingBuffer[offset + 1] == StompDecoder.B) {
                  if (!tryIncrement(offset + COMMAND_ABORT_LENGTH + eolLen)) {
                     return false;
                  }

                  // ABORT
                  command = COMMAND_ABORT;
               } else {
                  if (!tryIncrement(offset + COMMAND_ACK_LENGTH + eolLen)) {
                     return false;
                  }

                  // ACK
                  command = COMMAND_ACK;
               }
               break;
            }
            case B: {
               if (!tryIncrement(offset + COMMAND_BEGIN_LENGTH + eolLen)) {
                  return false;
               }

               // BEGIN
               command = COMMAND_BEGIN;

               break;
            }
            case C: {
               if (workingBuffer[offset + 2] == M) {
                  if (!tryIncrement(offset + COMMAND_COMMIT_LENGTH + eolLen)) {
                     return false;
                  }

                  // COMMIT
                  command = COMMAND_COMMIT;
               } else if (workingBuffer[offset + 7] == E) {
                  if (!tryIncrement(offset + COMMAND_CONNECTED_LENGTH + eolLen)) {
                     return false;
                  }

                  // CONNECTED
                  command = COMMAND_CONNECTED;
               } else {
                  if (!tryIncrement(offset + COMMAND_CONNECT_LENGTH + eolLen)) {
                     return false;
                  }

                  // CONNECT
                  command = COMMAND_CONNECT;
               }
               break;
            }
            case D: {
               if (!tryIncrement(offset + COMMAND_DISCONNECT_LENGTH + eolLen)) {
                  return false;
               }

               // DISCONNECT
               command = COMMAND_DISCONNECT;

               break;
            }
            case R: {
               if (!tryIncrement(offset + COMMAND_RECEIPT_LENGTH + eolLen)) {
                  return false;
               }

               // RECEIPT
               command = COMMAND_RECEIPT;

               break;
            }
            case E: {
               if (!tryIncrement(offset + COMMAND_ERROR_LENGTH + eolLen)) {
                  return false;
               }

               // ERROR
               command = COMMAND_ERROR;

               break;
            }
            case M: {
               if (!tryIncrement(offset + COMMAND_MESSAGE_LENGTH + eolLen)) {
                  return false;
               }

               // MESSAGE
               command = COMMAND_MESSAGE;

               break;
            }
            case S: {
               if (workingBuffer[offset + 1] == E) {
                  if (!tryIncrement(offset + COMMAND_SEND_LENGTH + eolLen)) {
                     return false;
                  }

                  // SEND
                  command = COMMAND_SEND;
               } else if (workingBuffer[offset + 1] == U) {
                  if (!tryIncrement(offset + COMMAND_SUBSCRIBE_LENGTH + eolLen)) {
                     return false;
                  }

                  // SUBSCRIBE
                  command = COMMAND_SUBSCRIBE;
               } else {
                  if (!tryIncrement(offset + StompDecoder.COMMAND_STOMP_LENGTH + eolLen)) {
                     return false;
                  }

                  // SUBSCRIBE
                  command = COMMAND_STOMP;
               }
               break;
            }
            case U: {
               if (!tryIncrement(offset + COMMAND_UNSUBSCRIBE_LENGTH + eolLen)) {
                  return false;
               }

               // UNSUBSCRIBE
               command = COMMAND_UNSUBSCRIBE;

               break;
            }
            case N: {
               if (!tryIncrement(offset + COMMAND_NACK_LENGTH + eolLen)) {
                  return false;
               }
               //NACK
               command = COMMAND_NACK;
               break;
            }
            default: {
               throwInvalid();
            }
         }

         checkEol();

         return true;
      }