protected boolean parseCommand()

in artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompDecoder.java [359:539]


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

      // 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 (offset < data) {
         if (workingBuffer[offset] == NEW_LINE) {
            nextChar = false;
         } else if (workingBuffer[offset] == CR) {
            if (nextChar)
               throw BUNDLE.invalidTwoCRs().setHandler(handler);
            nextChar = true;
         } else {
            break;
         }
         offset++;
      }

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

      if (data < 4 + offset) {
         // 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] == B) {
               if (!tryIncrement(offset + COMMAND_ABORT_LENGTH + 1)) {
                  return false;
               }

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

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

            // BEGIN
            command = COMMAND_BEGIN;

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

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

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

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

            // DISCONNECT
            command = COMMAND_DISCONNECT;

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

            // RECEIPT
            command = COMMAND_RECEIPT;

            break;
         }
         /**** added by meddy, 27 april 2011, handle header parser for reply to websocket protocol ****/
         case E: {
            if (!tryIncrement(offset + COMMAND_ERROR_LENGTH + 1)) {
               return false;
            }

            // ERROR
            command = COMMAND_ERROR;

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

            // MESSAGE
            command = COMMAND_MESSAGE;

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

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

               // STOMP
               command = COMMAND_STOMP;
            } else {
               if (!tryIncrement(offset + COMMAND_SUBSCRIBE_LENGTH + 1)) {
                  return false;
               }

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

            // UNSUBSCRIBE
            command = COMMAND_UNSUBSCRIBE;

            break;
         }
         default: {
            throwInvalid();
         }
      }

      // Sanity check
      if (workingBuffer[pos - 1] != NEW_LINE) {
         //give a signal to try other versions
         ActiveMQStompException error = BUNDLE.notValidNewLine(workingBuffer[pos - 1]).setHandler(handler);
         error.setCode(ActiveMQStompException.INVALID_EOL_V10);
         error.setBody(BUNDLE.unexpectedNewLine(workingBuffer[pos - 1]));
         throw error;
      }

      return true;
   }