New version
diff --git a/src/README b/src/README
new file mode 100644
index 0000000..b7407d9
--- /dev/null
+++ b/src/README
@@ -0,0 +1,9 @@
+Limitations:
+1)The CONNECT and CONNECTED messages does not escape the \n and \r characters,
+ hence it is not advised to use these in the header_name or header_value
+ of CONNECT and CONNECTED messages because during decoding they can confuse the parser.
+2)If a connect-length with wrong value is inserted in the STOMPFrame to be encoded,
+ the wrong value will not be corrected by the encoder.
+ If no content-length header is present and there is a body, the codec will automatically insert
+ the content-length header with the right value.
+3) The codec will not check for validity of presence or absence of headers in messages.
diff --git a/src/STOMP_EncDec.cc b/src/STOMP_EncDec.cc
new file mode 100644
index 0000000..95d783b
--- /dev/null
+++ b/src/STOMP_EncDec.cc
@@ -0,0 +1,390 @@
+/******************************************************************************
+* Copyright (c) 2017 Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Bence Janos Szabo - initial implementation
+******************************************************************************/
+//
+// File: STOMP_EncDec.cc
+// Rev:
+// Prodnr:
+
+#include "STOMP_Types.hh"
+
+namespace STOMP__Types {
+
+void encode_utf8_stomp(TTCN_Buffer& stream, const UNIVERSAL_CHARSTRING &value, const bool escape);
+void decode_utf8_stomp(UNIVERSAL_CHARSTRING &value, const bool escape);
+
+INTEGER f__STOMP__dec(const OCTETSTRING &str, STOMPFrame &msg)
+{
+ if (TTCN_Logger::log_this_event(TTCN_DEBUG)) {
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event("Decoding STOMP message: ");
+ str.log();
+ TTCN_Logger::end_event();
+ }
+
+ msg.clean_up();
+
+ TTCN_Buffer stream;
+ const int length = str.lengthof();
+ int prev_pos = 0;
+ int pos = 0;
+ int delta;
+
+ // Find the [\r]\n to identify the frame type
+ while (pos < length) {
+ if (str[pos].get_octet() == '\n') {
+ delta = 1;
+ break;
+ } else if (str[pos].get_octet() == '\r' && pos + 1 < length && str[pos+1].get_octet() == '\n') {
+ delta = 2;
+ break;
+ }
+ pos++;
+ }
+
+ CHARSTRING frame_type(pos, reinterpret_cast<const char*>((const unsigned char*)str));
+ pos += delta;
+
+ bool escape = true;
+
+ if (frame_type == "SEND") {
+ msg.command() = Command::SEND;
+ } else if (frame_type == "SUBSCRIBE") {
+ msg.command() = Command::SUBSCRIBE;
+ } else if (frame_type == "UNSUBSCRIBE") {
+ msg.command() = Command::UNSUBSCRIBE;
+ } else if (frame_type == "BEGIN") {
+ msg.command() = Command::BEGIN;
+ } else if (frame_type == "COMMIT") {
+ msg.command() = Command::COMMIT;
+ } else if (frame_type == "ABORT") {
+ msg.command() = Command::ABORT;
+ } else if (frame_type == "ACK") {
+ msg.command() = Command::ACK;
+ } else if (frame_type == "NACK") {
+ msg.command() = Command::NACK;
+ } else if (frame_type == "DISCONNECT") {
+ msg.command() = Command::DISCONNECT;
+ } else if (frame_type == "CONNECTED") {
+ msg.command() = Command::CONNECTED;
+ escape = false;
+ } else if (frame_type == "CONNECT") {
+ msg.command() = Command::CONNECT;
+ escape = false;
+ } else if (frame_type == "STOMP") {
+ msg.command() = Command::STOMP;
+ } else if (frame_type == "MESSAGE") {
+ msg.command() = Command::MESSAGE;
+ } else if (frame_type == "RECEIPT") {
+ msg.command() = Command::RECEIPT;
+ } else if (frame_type == "ERROR") {
+ msg.command() = Command::ERROR_;
+ } else {
+ TTCN_error("f_STOMP_dec error: Unexpected frame type received: %s.", (const char*)frame_type);
+ }
+
+ size_t index = 0;
+ bool found_payload_length = false;
+ int payload_length;
+ while (true) {
+ prev_pos = pos;
+ while (pos < length) {
+ if (str[pos].get_octet() == '\n') {
+ delta = 1;
+ break;
+ } else if (str[pos].get_octet() == '\r' && pos + 1 < length && str[pos+1].get_octet() == '\n') {
+ delta = 2;
+ break;
+ }
+ pos++;
+ }
+
+ // There are some headers
+ if (pos - prev_pos > 0) {
+ UNIVERSAL_CHARSTRING header;
+ header.decode_utf8(pos-prev_pos, &((const unsigned char*)str)[prev_pos]);
+ const int header_len = header.lengthof();
+ for (int i = 0; i < header_len; i++) {
+ if (header[i].get_uchar().is_char() && header[i].get_uchar().uc_cell == ':') {
+ msg.headers()[index].header__name() = UNIVERSAL_CHARSTRING(i, (const universal_char*)header);
+ msg.headers()[index].header__value() = UNIVERSAL_CHARSTRING(header_len-i-1, ((const universal_char*)header)+i+1);
+ decode_utf8_stomp(msg.headers()[index].header__name(), escape);
+ decode_utf8_stomp(msg.headers()[index].header__value(), escape);
+ if (found_payload_length == false && msg.headers()[index].header__name() == "content-length") {
+ found_payload_length = true;
+ TTCN_Buffer tmp_buff;
+ msg.headers()[index].header__value().encode_utf8(tmp_buff);
+ CHARSTRING cs(tmp_buff.get_len(), (const char*)tmp_buff.get_data());
+ payload_length = str2int(cs);
+ }
+ index++;
+ break;
+ }
+ }
+ } else {
+ pos += delta;
+ break;
+ }
+ pos += delta;
+ }
+
+ if (msg.headers().is_bound() == false) {
+ msg.headers().set_size(0);
+ }
+
+ prev_pos = pos;
+ if (found_payload_length == true) {
+ pos += payload_length;
+ if (pos >= length) {
+ TTCN_error("f_STOMP_dec error: Not enough bytes in the bytestream.");
+ }
+ } else {
+ // Read until closing NULL
+ const unsigned char* payload = ((const unsigned char*)str)+pos;
+ while (pos < length && *payload != 0) {
+ payload++;
+ pos++;
+ }
+ }
+
+ if (pos-prev_pos > 0) {
+ msg.payload() = OCTETSTRING(pos-prev_pos, ((const unsigned char*)str)+prev_pos);
+ } else {
+ msg.payload() = OMIT_VALUE;
+ }
+
+ // Skip NULL
+ pos++;
+ // read remaining [\r]\n
+ while (pos < length) {
+ if (str[pos].get_octet() == '\n') {
+ pos += 1;
+ } else if (str[pos].get_octet() == '\r') {
+ if (pos + 1 < length ) {
+ if (str[pos+1].get_octet() == '\n') {
+ pos += 2;
+ } else {
+ TTCN_error("f_STOMP_dec error: Extra non endline characters after the end of frame: %c.", str[pos+1].get_octet());
+ }
+ } else {
+ TTCN_error("f_STOMP_dec error: \r character found but no \n.");
+ }
+ } else {
+ TTCN_error("f_STOMP_dec error: Extra non endline characters after the end of frame: %c.", str[pos].get_octet());
+ }
+ }
+
+ if (TTCN_Logger::log_this_event(TTCN_DEBUG)) {
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event("Decoded STOMP message: ");
+ msg.log();
+ TTCN_Logger::end_event();
+ }
+
+ return 0;
+}
+
+
+INTEGER f__STOMP__enc(const STOMPFrame &msg, OCTETSTRING &str)
+{
+ static const char EOL = '\n';
+ TTCN_Buffer stream;
+
+ if (TTCN_Logger::log_this_event(TTCN_DEBUG)) {
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event("Encoding STOMP message: ");
+ msg.log();
+ TTCN_Logger::end_event();
+ }
+
+ bool escape = true;
+
+ // Commands
+ if (msg.command().is_bound()) {
+ switch (msg.command()) {
+ case Command::SEND:
+ stream.put_cs("SEND");
+ break;
+ case Command::SUBSCRIBE:
+ stream.put_cs("SUBSCRIBE");
+ break;
+ case Command::UNSUBSCRIBE:
+ stream.put_cs("UNSUBSCRIBE");
+ break;
+ case Command::BEGIN:
+ stream.put_cs("BEGIN");
+ break;
+ case Command::COMMIT:
+ stream.put_cs("COMMIT");
+ break;
+ case Command::ABORT:
+ stream.put_cs("ABORT");
+ break;
+ case Command::ACK:
+ stream.put_cs("ACK");
+ break;
+ case Command::NACK:
+ stream.put_cs("NACK");
+ break;
+ case Command::DISCONNECT:
+ stream.put_cs("DISCONNECT");
+ break;
+ case Command::CONNECTED:
+ stream.put_cs("CONNECTED");
+ escape = false;
+ break;
+ case Command::CONNECT:
+ stream.put_cs("CONNECT");
+ escape = false;
+ break;
+ case Command::STOMP:
+ stream.put_cs("STOMP");
+ break;
+ case Command::MESSAGE:
+ stream.put_cs("MESSAGE");
+ break;
+ case Command::RECEIPT:
+ stream.put_cs("RECEIPT");
+ break;
+ case Command::ERROR_:
+ stream.put_cs("ERROR");
+ break;
+ default:
+ TTCN_error("f_STOMP_enc error: Unrecognized command.");
+ }
+ } else {
+ TTCN_error("f_STOMP_enc error: Unbound command field.");
+ }
+
+ stream.put_c(EOL); // End of line signals that the headers are coming
+
+ // We put in automatically the content-length if it is not present
+ // and the payload field is present.
+ bool found_content_length = false;
+
+ // Header names and values with escaping if needed
+ if (msg.headers().is_bound()) {
+ const int nof_headers = msg.headers().size_of();
+ for (int i = 0; i < nof_headers; i++) {
+ if (msg.headers()[i].header__name() == "content-length") {
+ found_content_length = true;
+ }
+ encode_utf8_stomp(stream, msg.headers()[i].header__name(), escape);
+ stream.put_c(':');
+ encode_utf8_stomp(stream, msg.headers()[i].header__value(), escape);
+ stream.put_c(EOL); // End of line separates the headers from each other
+ }
+ } else {
+ TTCN_error("f_STOMP_enc error: Unbound headers field.");
+ }
+
+ if (msg.payload().is_bound()) {
+ if (msg.payload().ispresent()) {
+ // Automatically add content-length header
+ if (found_content_length == false) {
+ encode_utf8_stomp(stream, "content-length", escape);
+ stream.put_c(':');
+ CHARSTRING cs = int2str(msg.payload()().lengthof());
+ encode_utf8_stomp(stream, cs, escape);
+ stream.put_c(EOL);
+ }
+
+ stream.put_c(EOL); // An empty line signals that the payload may come
+ stream.put_string(msg.payload());
+ } else {
+ stream.put_c(EOL); // An empty line signals that the payload may come, but it wont.
+ }
+ } else {
+ TTCN_error("f_STOMP_enc error: Unbound payload field.");
+ }
+
+ stream.put_c(0); // End of frame
+
+ if (TTCN_Logger::log_this_event(TTCN_DEBUG)) {
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event("Encoded STOMP message: ");
+ stream.log();
+ TTCN_Logger::end_event();
+ }
+
+ stream.get_string(str);
+ return 0;
+}
+
+
+void encode_utf8_stomp(TTCN_Buffer& stream, const UNIVERSAL_CHARSTRING &value, const bool escape) {
+ if (escape) {
+ TTCN_Buffer tmp_buff;
+ value.encode_utf8(tmp_buff);
+ const unsigned char* ustr = tmp_buff.get_data();
+ const size_t pos = tmp_buff.get_len();
+ for (size_t j = 0; j < pos; j++) {
+ switch (ustr[j]) {
+ case '\r':
+ stream.put_cs("\\r");
+ break;
+ case '\n':
+ stream.put_cs("\\n");
+ break;
+ case ':':
+ stream.put_cs("\\c");
+ break;
+ case '\\':
+ stream.put_cs("\\\\");
+ break;
+ default:
+ stream.put_c(ustr[j]);
+ break;
+ }
+ }
+ } else {
+ value.encode_utf8(stream);
+ }
+}
+
+void decode_utf8_stomp(UNIVERSAL_CHARSTRING &value, const bool escape) {
+ if (escape) {
+ UNIVERSAL_CHARSTRING result = "";
+ const int length = value.lengthof();
+ for (int i = 0; i < length; i++) {
+ if (i+1 < length && value[i].get_uchar().is_char() && value[i+1].get_uchar().is_char()) {
+ if (value[i].get_uchar().uc_cell == '\\') {
+ i++;
+ const universal_char& uchar_value = value[i].get_uchar();
+ switch (uchar_value.uc_cell) {
+ case 'r':
+ result = result + "\r";
+ break;
+ case 'n':
+ result = result + "\n";
+ break;
+ case 'c':
+ result = result + ":";
+ break;
+ case '\\':
+ result = result + "\\";
+ break;
+ default:
+ TTCN_error("f_STOMP_dec error: Undefined escape sequence: \\%c", uchar_value.uc_cell);
+ break;
+ }
+ } else {
+ result = result + value[i].get_uchar();
+ }
+ } else {
+ result = result + value[i].get_uchar();
+ }
+ }
+ value = result;
+ }
+}
+
+
+}
diff --git a/src/STOMP_Types.ttcn b/src/STOMP_Types.ttcn
index 1a5c616..653118c 100644
--- a/src/STOMP_Types.ttcn
+++ b/src/STOMP_Types.ttcn
@@ -1,24 +1,22 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2017 Ericsson Telecom AB
-//
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// which accompanies this distribution, and is available at
-// http://www.eclipse.org/legal/epl-v10.html
-///////////////////////////////////////////////////////////////////////////////
-//
-// Contributors:
-// Elemer Lelik-initial implementation
-//
-//
+
+/******************************************************************************
+* Copyright (c) 2017 Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Bence Janos Szabo - initial implementation
+******************************************************************************/
/*
+
https://stomp.github.io/stomp-specification-1.2.html
-Augmented BNF
+
NULL = <US-ASCII null (octet 0)>
LF = <US-ASCII line feed (aka newline) (octet 10)>
@@ -61,71 +59,120 @@
*/
+//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 enc_STOMP(in STOMPFrame frame) return charstring
-with { extension "prototype(convert) encode(TEXT)" };
-external function dec_STOMP(in charstring stream) return STOMPFrame
-with { extension "prototype(convert) decode(TEXT)" };
+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_enc_stomp(in STOMPFrame frame) return octetstring
-{
- var octetstring v_os:=char2oct(enc_STOMP(frame));
- v_os:=substr(v_os,0,lengthof(v_os)-2)&'000D0A'O;//cut @@ and add NULL EOL;
+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;
- //log("v_os :",v_os)
- return v_os
-}
+ // 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;
+ }
+ }
-function f_dec_stomp(in octetstring stream) return STOMPFrame
-{
+ // 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;
+ }
+ }
- var STOMPFrame v_frame;
- var octetstring v_os;
- var integer v_l:=lengthof(stream);
+ // Count untill the closing NULL
+ for (i := result; i < str_len; i := i + 1) {
+ if (str[i] == '00'O) {
+ break;
+ }
+ }
+ result := i;
+ }
- for(var integer i:=v_l-1;i>=0;i:=i-1)
+ 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;
+ }
+ }
- if(stream[i]=='00'O) {
- v_os:=substr(stream,0,i)&'4040'O;//add @
- }//endif
- }//endfor
-
- //log("v_os :",v_os)
-
- v_frame:=dec_STOMP(oct2char(v_os));
-
- return v_frame;
+ return result;
}
-type charstring HeaderCharstringType ( pattern "(([\q{0,0,0,14}-9]|[;-}])#(1,))" );
+type universal charstring HeaderCharstringType;
+type HeaderCharstringType HeaderType //with { encode "UTF-8"}
type record Header {
- HeaderCharstringType header_name,
- HeaderCharstringType header_value
-}with {
- variant "SEPARATOR(':',,)"
- variant "END('\r\n','(\r)#(0,1)\n',)" //EOL
+ HeaderType header_name,
+ HeaderType header_value
}
-type set of Header Headers with {
- variant "END('\r\n','(\r)#(0,1)\n',)" //EOL
-}
+type set of Header Headers ;
type record STOMPFrame {
Command command,
Headers headers,
- charstring payload optional
+ octetstring payload optional
-}with {
- variant "END('@@','[\q{0,0,0,64}]#(2,2)',)"
-}
+}
type enumerated Command {
SEND,
@@ -144,11 +191,8 @@
RECEIPT,
ERROR
}
-with {
- variant "END('\r\n','(\r)#(0,1)\n',)" //EOL
-}
-}with { encode "TEXT" }
+}
diff --git a/src/STOMP_common.ttcn b/src/STOMP_common.ttcn
deleted file mode 100644
index 5c88bc0..0000000
--- a/src/STOMP_common.ttcn
+++ /dev/null
@@ -1,29 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2017 Ericsson Telecom AB
-//
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// which accompanies this distribution, and is available at
-// http://www.eclipse.org/legal/epl-v10.html
-///////////////////////////////////////////////////////////////////////////////
-//
-// Contributors:
-// Elemer Lelik-initial implementation
-//
-//
-//This function permits extracting JSON messages from a TCP stream by calculating the message length
-//
-
-module STOMP_common
-{
-
-//-----------------------------------------------------------------------------
-//External functions
-//-----------------------------------------------------------------------------
-
-external function f_calc_STOMP_length( in octetstring data) return integer;
-
-}
-
-
diff --git a/src/STOMP_slicer.cc b/src/STOMP_slicer.cc
deleted file mode 100644
index 8b81427..0000000
--- a/src/STOMP_slicer.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2017 Ericsson Telecom AB
-//
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// which accompanies this distribution, and is available at
-// http://www.eclipse.org/legal/epl-v10.html
-///////////////////////////////////////////////////////////////////////////////
-//
-// Contributors:
-// Elemer Lelik-initial implementation
-//
-//
-//This function permits extracting JSON messages from a TCP stream by calculating the message length
-//
-
-#include "STOMP_common.hh"
-#include <ctype.h>
-#include <string.h>
-#include <iostream>
-
-namespace STOMP__common {
-//returns length of first STOMP string in the input stream, calculated from index 0, or -1 in case of unsuccessful match
-INTEGER f__calc__STOMP__length(const OCTETSTRING& data){
- int data_length=data.lengthof();
- const unsigned char* ptr=(const unsigned char*)data;
-
-
- for(int i=0; i<data_length; i++){
-
- if (ptr[i] == '\0')
- {
- if( (ptr[i+1] != '\n') && (ptr[i+1] != '\r') ) return i+1;
- else {
-
-
- for(int j=i+1; j<data_length; j++){
-
- if ( (ptr[j+1] != '\n') && (ptr[j+1] != '\r') ) return j+1;
-
- }//endfor
-
-
- }//endelse
-
- }//endif
-
- }//endfor
-
- return -1;
-}//endfunction
-
-}//end ns
-
diff --git a/test/Makefile b/test/Makefile
index 39703c3..ddd8865 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,6 +1,6 @@
# This Makefile was generated by the Makefile Generator
# of the TTCN-3 Test Executor version CRL 113 200/6 R2A
-# for Elemer Lelik (ethlel@esekilxxen1844) on Tue Jun 27 13:27:38 2017
+# for Elemer Lelik (ethlel@esekilxxen1844) on Wed Aug 2 13:36:01 2017
# Copyright (c) 2000-2017 Ericsson Telecom AB
@@ -52,8 +52,7 @@
COMPILER_FLAGS = -L
# Execution mode: (either ttcn3 or ttcn3-parallel)
-TTCN3_LIB = ttcn3
-#-parallel
+TTCN3_LIB = ttcn3-parallel
# The path of your OpenSSL installation:
# If you do not have your own one, leave it unchanged.
@@ -72,34 +71,34 @@
#
# TTCN-3 modules of this project:
-TTCN3_MODULES = STOMP_Types.ttcn STOMP_test.ttcn
+TTCN3_MODULES = STOMPTest.ttcn STOMP_Types.ttcn
# ASN.1 modules of this project:
ASN1_MODULES =
# C++ source & header files generated from the TTCN-3 & ASN.1 modules of
# this project:
-GENERATED_SOURCES = STOMP_Types.cc STOMP_test.cc
-GENERATED_HEADERS = STOMP_Types.hh STOMP_test.hh
+GENERATED_SOURCES = STOMPTest.cc STOMP_Types.cc
+GENERATED_HEADERS = STOMPTest.hh STOMP_Types.hh
# C/C++ Source & header files of Test Ports, external functions and
# other modules:
-USER_SOURCES =
+USER_SOURCES = STOMP_EncDec.cc
USER_HEADERS =
# Object files of this project that are needed for the executable test suite:
OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS)
-GENERATED_OBJECTS = STOMP_Types.o STOMP_test.o
+GENERATED_OBJECTS = STOMPTest.o STOMP_Types.o
-USER_OBJECTS =
+USER_OBJECTS = STOMP_EncDec.o
# Other files of the project (Makefile, configuration files, etc.)
# that will be added to the archived source files:
OTHER_FILES = Makefile
# The name of the executable test suite:
-EXECUTABLE = stomp
+EXECUTABLE = STOMPTest
diff --git a/test/STOMPTest.ttcn b/test/STOMPTest.ttcn
new file mode 100644
index 0000000..6b72976
--- /dev/null
+++ b/test/STOMPTest.ttcn
@@ -0,0 +1,1116 @@
+module STOMPTest {
+
+ import from STOMP_Types all;
+
+ type component EmptyCT {
+
+ }
+
+
+//*******************************************************************************************
+//Templates
+
+
+template STOMPFrame t_message:=
+{
+
+ command:=MESSAGE,
+ headers:={ {header_name:="foo", header_value:="Hello"}, {header_name:="foo", header_value:="World"}},
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_send:=
+{
+
+ command:=SEND,
+ headers:={ {header_name:="destination", header_value:="/queue/a"}, {header_name:="receipt", header_value:="message-12345"}},
+ payload:=char2oct("hello queue a")
+
+
+}
+
+
+template STOMPFrame t_connect:=
+{
+
+ command:=CONNECT,
+ headers:={ {header_name:="accept-version", header_value:="1.2"}, {header_name:="host", header_value:="stomp.github.org"}},
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_connected:=
+{
+
+ command:=CONNECTED,
+ headers:={ {header_name:="version", header_value:="1.2"}},
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_error:=
+{
+
+ command:=ERROR,
+ headers:={ {header_name:="version", header_value:="1.2,2.1"},{header_name:="content-type", header_value:="text/plain"} },
+ payload:=char2oct("Supported protocol versions are 1.2 2.1")
+
+
+}
+
+
+template STOMPFrame t_subscribe:=
+{
+
+ command:=SUBSCRIBE,
+ headers:={ {header_name:="id", header_value:="0"},{header_name:="destination", header_value:="/queue/foo"},{header_name:="ack", header_value:="client"} },
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_unsubscribe:=
+{
+
+ command:=UNSUBSCRIBE,
+ headers:={ {header_name:="id", header_value:="0"} },
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_begin:=
+{
+
+ command:=BEGIN,
+ headers:={ {header_name:="transaction", header_value:="tx1"} },
+ payload:=omit
+
+
+}
+
+template STOMPFrame t_ack:=
+{
+
+ command:=ACK,
+ headers:={{header_name:="id", header_value:="0"}, {header_name:="transaction", header_value:="tx1"} },
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_nack:=
+{
+
+ command:=NACK,
+ headers:={{header_name:="id", header_value:="0"}, {header_name:="transaction", header_value:="tx1"} },
+ payload:=omit
+
+
+}
+
+template STOMPFrame t_commit:=
+{
+
+ command:=COMMIT,
+ headers:={ {header_name:="transaction", header_value:="tx1"} },
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_abort:=
+{
+
+ command:=ABORT,
+ headers:={ {header_name:="transaction", header_value:="tx1"} },
+ payload:=omit
+
+
+}
+
+template STOMPFrame t_disconnect:=
+{
+
+ command:=DISCONNECT,
+ headers:={ {header_name:="receipt", header_value:="77"} },
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_receipt:=
+{
+
+ command:=RECEIPT,
+ headers:={ {header_name:="receipt-id", header_value:="77"} },
+ payload:=omit
+
+
+}
+
+
+template STOMPFrame t_message1:=
+{
+
+ command:=MESSAGE,
+ headers:={ {header_name:="subscription", header_value:="0"}, {header_name:="message-id", header_value:="007"},{header_name:="destination", header_value:="/queue/a"}, {header_name:="content-type", header_value:="text/plain"}},
+ payload:=char2oct("hello queue a")
+
+
+}
+
+
+
+template STOMPFrame t_error1:=
+{
+
+ command:=ERROR,
+ headers:={ {header_name:="receipt-id", header_value:="message@12345"},{header_name:="content-type", header_value:="text/plain"}, /*{header_name:="content-length", header_value:="171"},*/{header_name:="message", header_value:="malformed frame received"} },
+ payload:=char2oct("The message:
+ -----
+ MESSAGE
+ destined:/queue/a
+ receipt:message@12345
+
+ Hello queue a!
+ -----
+ Did not contain a destination header, which is REQUIRED
+ for message propagation.")
+
+
+}
+
+ testcase tc_encdec() runs on EmptyCT {
+
+ var octetstring v_oct
+ var STOMPFrame v_stomp
+ var integer v_ret
+
+v_ret:=f_STOMP_enc(valueof(t_message), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+
+ v_ret:=f_STOMP_enc(valueof(t_send), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_ret:=f_STOMP_enc(valueof(t_connect), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_ret:=f_STOMP_enc(valueof(t_connected), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+
+ v_ret:=f_STOMP_enc(valueof(t_error), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_ret:=f_STOMP_enc(valueof(t_subscribe), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+
+ v_ret:=f_STOMP_enc(valueof(t_unsubscribe), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_ret:=f_STOMP_enc(valueof(t_begin), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_ret:=f_STOMP_enc(valueof(t_ack), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+v_ret:=f_STOMP_enc(valueof(t_nack), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+
+ v_ret:=f_STOMP_enc(valueof(t_commit), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+
+ v_ret:=f_STOMP_enc(valueof(t_abort), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+
+ v_ret:=f_STOMP_enc(valueof(t_disconnect), v_oct)
+
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_ret:=f_STOMP_enc(valueof(t_receipt), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_ret:=f_STOMP_enc(valueof(t_message1), v_oct)
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_ret:=f_STOMP_enc(valueof(t_error1), v_oct)
+
+log(v_oct)
+log(char2oct("The message:
+ -----
+ MESSAGE
+ destined:/queue/a
+ receipt:message@12345
+
+ Hello queue a!
+ -----
+ Did not contain a destination header, which is REQUIRED
+ for message propagation."))
+
+v_ret:=f_STOMP_dec(v_oct,v_stomp )
+log(v_stomp)
+ v_oct:=char2oct("MESSAGE\nsubscription:0\nmessage-id:007\r\ndestination:/queue/a\ncontent-type:text/plain\n\r\nhello queue a")
+
+ log(f_STOMP_dec(v_oct, v_stomp))
+
+log(v_stomp)
+
+
+}
+
+
+
+
+ testcase tc_test() runs on EmptyCT {
+ var STOMPFrame frame1, result;
+ var octetstring os;
+ var integer res;
+
+
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "a ", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SUBSCRIBE,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := UNSUBSCRIBE,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := BEGIN,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := COMMIT,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := ABORT,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := ACK,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := NACK,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := DISCONNECT,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := CONNECTED,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := CONNECT,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := STOMP,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := MESSAGE,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := RECEIPT,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := ERROR,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "abc", header_value := "def"},
+ { header_name := "ñ\n\r\\:ñ\t", header_value := "ñ\n\r\\:ñ\t"},
+ { header_name := "A, Á, B, C, Cs, D, Dz, Dzs, E, É, F, G, Gy, H, I, Í, J, K, L, Ly, M, N, Ny, O, Ó, Ö, Ő, P, R, S, Sz, T, Ty, U, Ú, Ü, Ű, V, Z, Zs", header_value := "A, Á, B, C, Cs, D, Dz, Dzs, E, É, F, G, Gy, H, I, Í, J, K, L, Ly, M, N, Ny, O, Ó, Ö, Ő, P, R, S, Sz, T, Ty, U, Ú, Ü, Ű, V, Z, Zs"}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "abc", header_value := "def"},
+ { header_name := "content-length", header_value := "4"}
+ },
+ payload := 'AAAA00AA'O
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "abc", header_value := "def"},
+ { header_name := "content-length", header_value := "4"},
+ { header_name := "content-length", header_value := "8"}
+ },
+ payload := 'AAAA00AA'O
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "", header_value := ""}
+ },
+ payload := 'AAAAAAAAAA'O
+ }
+
+ var STOMPFrame frame6 := {
+ command := SEND,
+ headers := {
+ { header_name := "", header_value := ""},
+ { header_name := "content-length", header_value := "5" }
+ },
+ payload := 'AAAAAAAAAA'O
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame6)) {
+ setverdict(fail, match(result, frame6));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "", header_value := ""}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "", header_value := ""}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "", header_value := ""}
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ },
+ payload := omit
+ }
+
+ res := f_STOMP_enc(frame1, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ var STOMPFrame frame2 := {
+ headers := {
+ { header_name := "", header_value := ""}
+ },
+ payload := omit
+ }
+
+ var boolean errors := false;
+ @try {
+ res := f_STOMP_enc(frame2, os);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+
+ /////////////////////////////////////////////////////////////
+
+ var STOMPFrame frame3 := {
+ command := SEND,
+ payload := omit
+ }
+
+ errors := false;
+ @try {
+ res := f_STOMP_enc(frame3, os);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+
+ /////////////////////////////////////////////////////////////
+
+ var STOMPFrame frame4 := {
+ command := SEND,
+ headers := {
+
+ }
+ }
+
+ errors := false;
+ @try {
+ res := f_STOMP_enc(frame4, os);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+
+ /////////////////////////////////////////////////////////////
+
+ os := '53AA454E440A613A620A0AAAAAAAAA00'O;
+ errors := false;
+ @try {
+ res := f_STOMP_dec(os, result);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := 'AAAAAAAA'O
+ }
+ os := '53454E440A613A620A0AAAAAAAAA000A'O;
+ errors := false;
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := 'AAAAAAAA'O
+ }
+ os := '53454E440A613A620A0AAAAAAAAA000D0A'O;
+ errors := false;
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := 'AAAAAAAA'O
+ }
+ os := '53454E440A613A620A0AAAAAAAAA000D0A0A0A0D0A0D0A'O;
+ errors := false;
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame1)) {
+ setverdict(fail, match(result, frame1));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ os := '53454E440A613A620A0AAAAAAAAA00AA'O;
+ errors := false;
+ @try {
+ res := f_STOMP_dec(os, result);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ os := '53454E440A613A620A0AAAAAAAAA000D0A0A0A0D0A0D0A11'O;
+ errors := false;
+ @try {
+ res := f_STOMP_dec(os, result);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+
+ /////////////////////////////////////////////////////////////
+
+ os := '53454E440A613A620A0AAAAAAAAA000D0A0A0A0D0A0D150A'O;
+ errors := false;
+ @try {
+ res := f_STOMP_dec(os, result);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ os := '53454E440A613A620A0AAAAAAAAA000D0A0A0A0D0A0D0A0D'O;
+ errors := false;
+ @try {
+ res := f_STOMP_dec(os, result);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ os := '53454E440A613A625C740A0AAAAAAAAA00'O;
+ errors := false;
+ @try {
+ res := f_STOMP_dec(os, result);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame2 := {
+ command := CONNECT,
+ headers := {
+ { header_name := "a\\\ra", header_value := "a\\\ra" }
+ },
+ payload := 'AAAAAAAA'O
+ }
+
+ frame6 := {
+ command := CONNECT,
+ headers := {
+ { header_name := "a\\\ra", header_value := "a\\\ra" },
+ { header_name := "content-length", header_value := "4" }
+ },
+ payload := 'AAAAAAAA'O
+ }
+
+ res := f_STOMP_enc(frame2, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame6)) {
+ setverdict(fail, match(result, frame6));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame2 := {
+ command := CONNECTED,
+ headers := {
+ { header_name := "a\\\ra", header_value := "a\\\ra" }
+ },
+ payload := 'AAAAAAAA'O
+ }
+
+ frame6 := {
+ command := CONNECTED,
+ headers := {
+ { header_name := "a\\\ra", header_value := "a\\\ra" },
+ { header_name := "content-length", header_value := "4" }
+ },
+ payload := 'AAAAAAAA'O
+ }
+
+ res := f_STOMP_enc(frame2, os);
+ res := f_STOMP_dec(os, result);
+ if (not match(result, frame6)) {
+ setverdict(fail, match(result, frame6));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "abc", header_value := "def"},
+ { header_name := "content-length", header_value := "5"}
+ },
+ payload := 'AAAA00AA'O
+ }
+ errors := false;
+ res := f_STOMP_enc(frame1, os);
+ @try {
+ res := f_STOMP_dec(os, result);
+ } @catch(e) {
+ setverdict(pass);
+ errors := true;
+ }
+ if (errors == false) {
+ setverdict(fail, "No error");
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ os := '53454E440A613A620A0AAAAAAAAA00'O;
+ res := f_STOMP_dec(os, result);
+ frame6 := {
+ command := SEND,
+ headers := {
+ { header_name := "a", header_value := "b"}
+ },
+ payload := 'AAAAAAAA'O
+ }
+
+ if (not match(result, frame6)) {
+ setverdict(fail, match(result, frame6));
+ }
+
+
+ /////////////////////////////////////////////////////////////
+
+ frame1 := {
+ command := SEND,
+ headers := {
+ { header_name := "abc", header_value := "def"},
+ { header_name := "content-length", header_value := "5"}
+ },
+ payload := 'AAAA00AA'O
+ }
+ res := f_STOMP_enc(frame1, os);
+ var integer len := f_GetSTOMPmsgLength(os);
+ if (len != 36) {
+ setverdict(fail, match(len, 36));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A6162633A6465660A636F6E74656E742D6C656E6774683A350A0AAAAA00AA000A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 37) {
+ setverdict(fail, match(len, 37));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A6162633A6465660A636F6E74656E742D6C656E6774683A350A0AAAAA00AA000D0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 38) {
+ setverdict(fail, match(len, 38));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A6162633A6465660A636F6E74656E742D6C656E6774683A350A0AAAAA00AA000D0A0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 39) {
+ setverdict(fail, match(len, 39));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A6162633A6465660A636F6E74656E742D6C656E6774683A350D0A0AAAAA00AA000D0A0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 40) {
+ setverdict(fail, match(len, 40));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A6162633A6465660A636F6E74656E742D6C656E6774683A350D0A0D0AAAAA00AA000D0A0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 41) {
+ setverdict(fail, match(len, 41));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A6162633A6465660D0A636F6E74656E742D6C656E6774683A350A6162633A6465660D0A0D0AAAAA00AA000D0A0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 50) {
+ setverdict(fail, match(len, 50));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A6162633A6465660D0A636F6E74656E742D6C656E6774683A350D0A6162633A6465660D0A0D0AAAAA00AA000D0A0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 51) {
+ setverdict(fail, match(len, 51));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A6162633A6465660D0A636F6E74656E742D6C656E6774683A350D0A6162633A6465660D0A0D0AAAAA00AA000D0A0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 51) {
+ setverdict(fail, match(len, 51));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440A613A620A0AAAAAAAAA00'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 15) {
+ setverdict(fail, match(len, 15));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440D0A613A620A0AAAAAAAAA00'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 16) {
+ setverdict(fail, match(len, 16));
+ }
+
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440D0A613A620A0AAAAAAAAA000A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 17) {
+ setverdict(fail, match(len, 17));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440D0A613A620A0AAAAAAAAA000D0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 18) {
+ setverdict(fail, match(len, 18));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440D0A613A620D0A0AAAAAAAAA000D0A0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 20) {
+ setverdict(fail, match(len, 20));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440D0A613A620D0A0D0AAAAAAAAA000D0A0A'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 21) {
+ setverdict(fail, match(len, 21));
+ }
+
+ /////////////////////////////////////////////////////////////
+
+
+ os := '53454E440D0A613A620D0A0D0AAAAAAAAA000D0A0A1231BB'O;
+ len := f_GetSTOMPmsgLength(os);
+ if (len != 21) {
+ setverdict(fail, match(len, 21));
+ }
+
+ setverdict(pass);
+ }
+
+
+
+
+ control {
+ execute(tc_test());
+ execute(tc_encdec());
+ }
+}
diff --git a/test/STOMP_test.ttcn b/test/STOMP_test.ttcn
deleted file mode 100644
index 474973c..0000000
--- a/test/STOMP_test.ttcn
+++ /dev/null
@@ -1,247 +0,0 @@
-module STOMP_test
-{
-
-
-import from STOMP_Types all;
-
-
-
-
-//*******************************************************************************************
-//Templates
-
-
-template STOMPFrame t_message:=
-{
-
- command:=MESSAGE,
- headers:={ {header_name:="foo", header_value:="Hello"}, {header_name:="foo", header_value:="World"}},
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_send:=
-{
-
- command:=SEND,
- headers:={ {header_name:="destination", header_value:="/queue/a"}, {header_name:="receipt", header_value:="message-12345"}},
- payload:="hello queue a"
-
-
-}
-
-
-template STOMPFrame t_connect:=
-{
-
- command:=CONNECT,
- headers:={ {header_name:="accept-version", header_value:="1.2"}, {header_name:="host", header_value:="stomp.github.org"}},
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_connected:=
-{
-
- command:=CONNECTED,
- headers:={ {header_name:="version", header_value:="1.2"}},
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_error:=
-{
-
- command:=ERROR,
- headers:={ {header_name:="version", header_value:="1.2,2.1"},{header_name:="content-type", header_value:="text/plain"} },
- payload:="Supported protocol versions are 1.2 2.1"
-
-
-}
-
-
-template STOMPFrame t_subscribe:=
-{
-
- command:=SUBSCRIBE,
- headers:={ {header_name:="id", header_value:="0"},{header_name:="destination", header_value:="/queue/foo"},{header_name:="ack", header_value:="client"} },
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_unsubscribe:=
-{
-
- command:=UNSUBSCRIBE,
- headers:={ {header_name:="id", header_value:="0"} },
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_begin:=
-{
-
- command:=BEGIN,
- headers:={ {header_name:="transaction", header_value:="tx1"} },
- payload:=omit
-
-
-}
-
-template STOMPFrame t_ack:=
-{
-
- command:=ACK,
- headers:={{header_name:="id", header_value:="0"}, {header_name:="transaction", header_value:="tx1"} },
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_nack:=
-{
-
- command:=NACK,
- headers:={{header_name:="id", header_value:="0"}, {header_name:="transaction", header_value:="tx1"} },
- payload:=omit
-
-
-}
-
-template STOMPFrame t_commit:=
-{
-
- command:=COMMIT,
- headers:={ {header_name:="transaction", header_value:="tx1"} },
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_abort:=
-{
-
- command:=ABORT,
- headers:={ {header_name:="transaction", header_value:="tx1"} },
- payload:=omit
-
-
-}
-
-template STOMPFrame t_disconnect:=
-{
-
- command:=DISCONNECT,
- headers:={ {header_name:="receipt", header_value:="77"} },
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_receipt:=
-{
-
- command:=RECEIPT,
- headers:={ {header_name:="receipt-id", header_value:="77"} },
- payload:=omit
-
-
-}
-
-
-template STOMPFrame t_message1:=
-{
-
- command:=MESSAGE,
- headers:={ {header_name:="subscription", header_value:="0"}, {header_name:="message-id", header_value:="007"},{header_name:="destination", header_value:="/queue/a"}, {header_name:="content-type", header_value:="text/plain"}},
- payload:="hello queue a"
-
-
-}
-
-
-
-template STOMPFrame t_error1:=
-{
-
- command:=ERROR,
- headers:={ {header_name:="receipt-id", header_value:="message@12345"},{header_name:="content-type", header_value:="text/plain"}, {header_name:="content-length", header_value:="171"},{header_name:="message", header_value:="malformed frame received"} },
- payload:="The message:
- -----
- MESSAGE
- destined:/queue/a
- receipt:message@12345
-
- Hello queue a!
- -----
- Did not contain a destination header, which is REQUIRED
- for message propagation."
-
-
-}
-
-
-
-
-control {
-
- var charstring v_char
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_message))))
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_send))))
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_connect))))
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_connected))))
-
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_error))))
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_subscribe))))
-
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_unsubscribe))))
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_begin))))
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_ack))))
- log(f_dec_stomp(f_enc_stomp(valueof(t_nack))))
-
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_commit))))
- log(f_dec_stomp(f_enc_stomp(valueof(t_abort))))
-
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_disconnect))))
- log(f_dec_stomp(f_enc_stomp(valueof(t_receipt))))
- log(f_dec_stomp(f_enc_stomp(valueof(t_message1))))
-
- log(f_dec_stomp(f_enc_stomp(valueof(t_error1))))
-
- v_char:="MESSAGE\nsubscription:0\nmessage-id:007\r\ndestination:/queue/a\ncontent-type:text/plain\n\r\nhello queue a@@"
-
- log(dec_STOMP(v_char))
-
-
-
-
-
-
-}
-
-
-}