blob: 3fa682114261b2c0308122244c2a780bef577397 [file] [log] [blame]
/******************************************************************************
* 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
}
}