internal Msg(MsgArg arg, byte[] payload, long length) { _subject = arg.subject; _reply = arg.reply; _sid = arg.sid; // make a deep copy of the bytes for this message. _data = new byte[length]; Array.Copy(payload, _data, (int)length); }
internal MsgArg processMsgArgs(byte[] buffer, long length) { string s = convertToString(buffer, length); string[] args = s.Split(' '); MsgArg msgArgs = new MsgArg(); switch (args.Length) { case 3: msgArgs.subject = args[0]; msgArgs.sid = LongParseFast(args[1]); msgArgs.reply = null; msgArgs.size = IntParseFast(args[2]); break; case 4: msgArgs.subject = args[0]; msgArgs.sid = LongParseFast(args[1]); msgArgs.reply = args[2]; msgArgs.size = IntParseFast(args[3]); break; default: throw new FastNATSException("Unable to parse message arguments: " + s); } if (msgArgs.size < 0) { throw new FastNATSException("Invalid Message - Bad or Missing Size: " + s); } if (msgArgs.sid < 0) { throw new FastNATSException("Invalid Message - Bad or Missing Sid: " + s); } return(msgArgs); }
internal void parse(byte[] buffer, int len) { MsgArg msgArgs = null; int i; char b; for (i = 0; i < len; i++) { b = (char)buffer[i]; switch (state) { case OP_START: switch (b) { case 'M': case 'm': state = OP_M; break; case 'C': case 'c': state = OP_C; break; case 'P': case 'p': state = OP_P; break; case '+': state = OP_PLUS; break; case '-': state = OP_MINUS; break; case 'i': case 'I': state = OP_I; break; default: parseError(buffer, i); break; } break; case OP_M: switch (b) { case 'S': case 's': state = OP_MS; break; default: parseError(buffer, i); break; } break; case OP_MS: switch (b) { case 'G': case 'g': state = OP_MSG; break; default: parseError(buffer, i); break; } break; case OP_MSG: switch (b) { case ' ': case '\t': state = OP_MSG_SPC; break; default: parseError(buffer, i); break; } break; case OP_MSG_SPC: switch (b) { case ' ': break; case '\t': break; default: state = MSG_ARG; i--; break; } break; case MSG_ARG: switch (b) { case '\r': break; case '\n': msgArgs = processMsgArgs(_argBufBase, _argBufStream.Position); _argBufStream.Position = 0; if (msgArgs.size > _msgBufBase.Length) { // Add 2 to account for the \r\n _msgBufBase = new byte[msgArgs.size + 2]; _msgBufStream = new MemoryStream(_msgBufBase); } state = MSG_PAYLOAD; break; default: _argBufStream.WriteByte((byte)b); break; } break; case MSG_PAYLOAD: int msgSize = msgArgs.size; if (msgSize == 0) { processMsg(_msgBufBase, msgSize); state = MSG_END; } else { long position = _msgBufStream.Position; int writeLen = msgSize - (int)position; int avail = len - i; if (avail < writeLen) { writeLen = avail; } _msgBufStream.Write(buffer, i, writeLen); i += (writeLen - 1); if ((position + writeLen) >= msgSize) { processMsg(_msgBufBase, msgSize); _msgBufStream.Position = 0; state = MSG_END; } } break; case MSG_END: switch (b) { case '\n': state = OP_START; break; default: continue; } break; case OP_PLUS: switch (b) { case 'O': case 'o': state = OP_PLUS_O; break; default: parseError(buffer, i); break; } break; case OP_PLUS_O: switch (b) { case 'K': case 'k': state = OP_PLUS_OK; break; default: parseError(buffer, i); break; } break; case OP_PLUS_OK: switch (b) { case '\n': //conn.processOK(); state = OP_START; break; } break; case OP_MINUS: switch (b) { case 'E': case 'e': state = OP_MINUS_E; break; default: parseError(buffer, i); break; } break; case OP_MINUS_E: switch (b) { case 'R': case 'r': state = OP_MINUS_ER; break; default: parseError(buffer, i); break; } break; case OP_MINUS_ER: switch (b) { case 'R': case 'r': state = OP_MINUS_ERR; break; default: parseError(buffer, i); break; } break; case OP_MINUS_ERR: switch (b) { case ' ': case '\t': state = OP_MINUS_ERR_SPC; break; default: parseError(buffer, i); break; } break; case OP_MINUS_ERR_SPC: switch (b) { case ' ': case '\t': state = OP_MINUS_ERR_SPC; break; default: state = MINUS_ERR_ARG; i--; break; } break; case MINUS_ERR_ARG: switch (b) { case '\r': break; case '\n': //TODO:Error raised OnErrorRaised(""); //conn.processErr(argBufStream); _argBufStream.Position = 0; state = OP_START; break; default: _argBufStream.WriteByte((byte)b); break; } break; case OP_P: switch (b) { case 'I': case 'i': state = OP_PI; break; case 'O': case 'o': state = OP_PO; break; default: parseError(buffer, i); break; } break; case OP_PO: switch (b) { case 'N': case 'n': state = OP_PON; break; default: parseError(buffer, i); break; } break; case OP_PON: switch (b) { case 'G': case 'g': state = OP_PONG; break; default: parseError(buffer, i); break; } break; case OP_PONG: switch (b) { case '\r': break; case '\n': //TODO:implement pong //conn.processPong(); state = OP_START; break; } break; case OP_PI: switch (b) { case 'N': case 'n': state = OP_PIN; break; default: parseError(buffer, i); break; } break; case OP_PIN: switch (b) { case 'G': case 'g': state = OP_PING; break; default: parseError(buffer, i); break; } break; case OP_PING: switch (b) { case '\r': break; case '\n': OnPingReceived(); state = OP_START; break; default: parseError(buffer, i); break; } break; case OP_I: switch (b) { case 'N': case 'n': state = OP_IN; break; default: parseError(buffer, i); break; } break; case OP_IN: switch (b) { case 'F': case 'f': state = OP_INF; break; default: parseError(buffer, i); break; } break; case OP_INF: switch (b) { case 'O': case 'o': state = OP_INFO; break; default: parseError(buffer, i); break; } break; case OP_INFO: switch (b) { case ' ': case '\t': state = OP_INFO_SPC; break; default: parseError(buffer, i); break; } break; case OP_INFO_SPC: switch (b) { case ' ': case '\t': break; default: _argBufStream.Position = 0; state = INFO_ARG; i--; break; } break; case INFO_ARG: switch (b) { case '\r': break; case '\n': //TODO:implement info //conn.processAsyncInfo(argBufBase, (int)argBufStream.Position); state = OP_START; break; default: _argBufStream.WriteByte((byte)b); break; } break; default: throw new FastNATSException("Unable to parse."); } // switch(state) } // for } // parse