| |
| /****************************************************************************** |
| * Copyright (c) 2000-2018 Ericsson Telecom AB AB |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html |
| * |
| * Contributors: |
| * Bence Janos Szabo - initial implementation |
| * version R1B |
| ******************************************************************************/ |
| |
| /* |
| |
| |
| https://stomp.github.io/stomp-specification-1.2.html |
| |
| |
| |
| |
| NULL = <US-ASCII null (octet 0)> |
| LF = <US-ASCII line feed (aka newline) (octet 10)> |
| CR = <US-ASCII carriage return (octet 13)> |
| EOL = [CR] LF |
| OCTET = <any 8-bit sequence of data> |
| |
| frame-stream = 1*frame |
| |
| frame = command EOL |
| *( header EOL ) |
| EOL |
| *OCTET |
| NULL |
| *( EOL ) |
| |
| command = client-command | server-command |
| |
| client-command = "SEND" |
| | "SUBSCRIBE" |
| | "UNSUBSCRIBE" |
| | "BEGIN" |
| | "COMMIT" |
| | "ABORT" |
| | "ACK" |
| | "NACK" |
| | "DISCONNECT" |
| | "CONNECT" |
| | "STOMP" |
| |
| server-command = "CONNECTED" |
| | "MESSAGE" |
| | "RECEIPT" |
| | "ERROR" |
| |
| header = header-name ":" header-value |
| header-name = 1*<any OCTET except CR or LF or ":"> |
| header-value = *<any OCTET except CR or LF or ":"> |
| |
| */ |
| |
| |
| //Note1: The header names and header values cannot contain LF, CR and ":" characters |
| //Note2: Encoding of header names and header values is ASCII |
| |
| |
| |
| |
| |
| module STOMP_Types { |
| |
| external function f_STOMP_enc(in STOMPFrame msg, out octetstring str) return integer; |
| external function f_STOMP_dec(in octetstring str, out STOMPFrame msg) return integer; |
| |
| function f_GetSTOMPmsgLength(in octetstring str) return integer { |
| var integer str_len := lengthof(str); |
| var integer result := 0; |
| var octetstring content_len_os := char2oct("\ncontent-length:"); |
| var integer max := lengthof(str)-lengthof(content_len_os); |
| var boolean found := false; |
| var integer i := 0,j := 0; |
| |
| // Find the position of "\ncontent_length:" to get the length of payload if any |
| for (i := 0; i < max; i := i + 1) { |
| found := true; |
| for (j := 0; j < lengthof(content_len_os) and found; j := j + 1) { |
| found := str[i+j] == content_len_os[j]; |
| } |
| if (found == true) { |
| break; |
| } |
| } |
| |
| // There is a content_length header |
| if (found == true) { |
| var integer start_of_length := i + j; |
| // Find the closing [\r]\n to get the end_of_length |
| for (i := start_of_length; i < str_len; i := i + 1) { |
| if (str[i] == char2oct("\n")) { // todo \r before \n |
| break; |
| } else if (str[i] == char2oct("\r") and i+1 < str_len and str[i+1] == char2oct("\n")) { |
| break; |
| } |
| } |
| var integer end_of_length := i; |
| // Calculate the length of payload |
| var octetstring octlen := substr(str, start_of_length, end_of_length-start_of_length); |
| var integer len := str2int(oct2char(octlen)); |
| // Find the beginning of payload: after \n[\r]\n |
| for (i := end_of_length; i < str_len-3; i := i + 1) { |
| if (str[i] == char2oct("\n") and str[i+1] == char2oct("\n")) { |
| result := i + len + 1; |
| break; |
| } else if (str[i] == char2oct("\n") and str[i+1] == char2oct("\r") and str[i+2] == char2oct("\n")) { |
| result := i + len + 2; |
| break; |
| } |
| } |
| } else { |
| // Find the beginning of payload: after \n[\r]\n |
| for (i := i + j; i < str_len-3; i := i + 1) { |
| if (str[i] == char2oct("\n") and str[i+1] == char2oct("\n")) { |
| result := i + 1; |
| break; |
| } else if (str[i] == char2oct("\n") and str[i+1] == char2oct("\r") and str[i+2] == char2oct("\n")) { |
| result := i + 2; |
| break; |
| } |
| } |
| |
| // Count untill the closing NULL |
| for (i := result; i < str_len; i := i + 1) { |
| if (str[i] == '00'O) { |
| break; |
| } |
| } |
| result := i; |
| } |
| |
| result := result + 1; // Closing NULL |
| |
| // Read the rest of the optional [\r]\n[\r]\n-s |
| for (i := result; i < str_len; i := i + 1) { |
| if (str[i] == char2oct("\r") and i+1 < str_len and str[i+1] == char2oct("\n")) { |
| result := result + 2; |
| i := i + 1; |
| } else if (str[i] == char2oct("\n")) { |
| result := result + 1; |
| } else { |
| break; |
| } |
| } |
| |
| return result; |
| } |
| |
| |
| type universal charstring HeaderCharstringType; |
| |
| type HeaderCharstringType HeaderType //with { encode "UTF-8"} |
| |
| type record Header { |
| HeaderType header_name, |
| HeaderType header_value |
| } |
| |
| |
| type set of Header Headers ; |
| |
| type record STOMPFrame { |
| |
| Command command, |
| Headers headers, |
| octetstring payload optional |
| |
| } |
| |
| type enumerated Command { |
| SEND, |
| SUBSCRIBE, |
| UNSUBSCRIBE, |
| BEGIN, |
| COMMIT, |
| ABORT, |
| ACK, |
| NACK, |
| DISCONNECT, |
| CONNECTED, |
| CONNECT, |
| STOMP, |
| MESSAGE, |
| RECEIPT, |
| ERROR |
| } |
| |
| |
| } |
| |
| |