Streams

The framework StreamI interface offers a portable stream definition. The BufferedStreamI complements the StreamI interface by offering an interface to buffered operations (e.g. Printf and GetToken).

Warning

Some operations (e.g. Read, Printf, …) might change the stream cursor position. Always remember to Seek to the appropriate position (e.g. Seek(0)).

StreamString

The StreamString is the framework string implementation and allows to read and write to an underlying unbounded string that can grow dynamically.

StreamString s1 = "Hello";
//The cursor of s1 will be pointing at the end. As a consequence an empty string will be printed.
REPORT_ERROR_STATIC(ErrorManagement::Information, "s1 = %s", s1);
s1.Seek(0);
REPORT_ERROR_STATIC(ErrorManagement::Information, "{After seek} s1 = %s", s1);
//The buffer will return the pointer to the start of the string.
REPORT_ERROR_STATIC(ErrorManagement::Information, "{Buffer()} s1 = %s", s1.Buffer());

StreamString s3 = s1;
s3.Seek(0);
s3.Printf("%s", "Hi");
//This will print Hillo....
REPORT_ERROR_STATIC(ErrorManagement::Information, "{After Printf} s3 = %s", s3.Buffer());
//Reset the string
s3 = "";
s3.Printf("%s", "Hi");
REPORT_ERROR_STATIC(ErrorManagement::Information, "{After =\"\"} s3 = %s", s3.Buffer());

Basic streams

The Basic streams implementation allow to access the underlying media (e.g. file, socket, …) using the StreamI interface, but do not allow more advanced operations (e.g. Printf, GetToken, …) which require buffered support.

The following basic streams are available: BasicConsole, BasicFile, BasicTCPSocket and BasicUDPSocket.

BasicUDPSocket sock;
bool ok = sock.Open();
...
ok = sock.Listen(port);
...
BasicConsole bc;
...
bc.Open(BasicConsoleMode::EnablePaging);
bc.SetSceneSize(ncols, nrows);
...
BasicFile f;
ok = f.Open(TEST_FILENAME, BasicFile::FLAG_CREAT | BasicFile::ACCESS_MODE_W);
...
MARTe::uint32 writeSize = str.Size();
stream.Write(str.Buffer(), writeSize);

Buffered streams

The buffered streams complement the basic streams with buffered operations.

The following buffered streams are available: StreamString, File, TCPSocket and UDPSocket.

UDPSocket sock;
bool ok = sock.Open();
...
ok = sock.Listen(port);
...
File f;
ok = f.Open(TEST_FILENAME, BasicFile::FLAG_CREAT | BasicFile::ACCESS_MODE_W);
...
stream.GetLine(line);
while (line.GetToken(token, ":", term)) {
   ...
   token = "";
}
line = "";

Warning

When using the GetLine and GetToken methods, always remember to reset the output parameters (e.g. line = ""; token = "";).

Examples

StreamString

The following example shows some typical use-cases of the strings.

StreamString example (StreamStringExample1)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
 * @file StreamStringExample1.cpp
 * @brief Source file for class StreamStringExample1
 * @date 30/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class StreamStringExample1 (public, protected, and private). Be aware that some
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "ErrorLoggerExample.h"
#include "StreamString.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/

int main(int argc, char *argv[]) {
    using namespace MARTe;
    SetErrorProcessFunction(&ErrorProcessExampleFunction);

    StreamString s1 = "Hello";
    //The cursor of s1 will be pointing at the end. As a consequence an empty string will be printed.
    REPORT_ERROR_STATIC(ErrorManagement::Information, "s1 = %s", s1);
    s1.Seek(0);
    REPORT_ERROR_STATIC(ErrorManagement::Information, "{After seek} s1 = %s", s1);
    //The buffer will return the pointer to the start of the string.
    REPORT_ERROR_STATIC(ErrorManagement::Information, "{Buffer()} s1 = %s", s1.Buffer());

    StreamString s2 = s1;
    //The cursor of s2 will also be pointing at the end. As a consequence an empty string will be printed.
    REPORT_ERROR_STATIC(ErrorManagement::Information, "s2 = %s", s2);
    s2.Seek(1);
    REPORT_ERROR_STATIC(ErrorManagement::Information, "{After seek:1} s2 = %s", s2);

    StreamString s3 = s1;
    s3.Seek(0);
    s3.Printf("%s", "Hi");
    REPORT_ERROR_STATIC(ErrorManagement::Information, "{After Printf} s3 = %s", s3.Buffer());

    //Reset the string
    s3 = "";
    s3.Printf("%s", "Hi");
    REPORT_ERROR_STATIC(ErrorManagement::Information, "{After =\"\"} s3 = %s", s3.Buffer());

    return 0;
}

Basic streams

The following is an example which highlights the usage of the basic streams.

Basic streams example (BasicStreamsExample1)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
 * @file BasicStreamsExample1.cpp
 * @brief Source file for class BasicStreamsExample1
 * @date 30/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class BasicStreamsExample1 (public, protected, and private). Be aware that some
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "Directory.h"
#include "ErrorLoggerExample.h"
#include "BasicConsole.h"
#include "BasicFile.h"
#include "BasicUDPSocket.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/

/**
 * @brief Writes to the specified stream
 */
static void WriteToBasicStream(MARTe::StreamI &stream, MARTe::StreamString &str) {
    MARTe::uint32 writeSize = str.Size();
    stream.Write(str.Buffer(), writeSize);
}

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/

int main(int argc, char *argv[]) {
    using namespace MARTe;
    SetErrorProcessFunction(&ErrorProcessExampleFunction);

    BasicUDPSocket sock;
    bool ok = sock.Open();
    uint16 port = 24680;
    if (ok) {
        REPORT_ERROR_STATIC(ErrorManagement::Information, "Going to listen in port = %d", port);
        ok = sock.Listen(port);
    }
    if (!ok) {
        REPORT_ERROR_STATIC(ErrorManagement::FatalError, "Failed to listen in port = %d", port);
    }

    StreamString recStream;
    if (ok) {
        const uint32 MAX_BUFFER_SIZE = 512;
        char8 buffer[MAX_BUFFER_SIZE];
        uint32 bufferSize = MAX_BUFFER_SIZE;
        ok = sock.Read(buffer, bufferSize);
        if (bufferSize == MAX_BUFFER_SIZE) {
            bufferSize = (MAX_BUFFER_SIZE - 1);
        }
        buffer[bufferSize] = '\0';
        if (ok) {
            recStream = buffer;
            REPORT_ERROR_STATIC(ErrorManagement::Information, "Read from UDP: %s", recStream.Buffer());
        }
        ok = sock.Close();
    }
    if (ok) {
        BasicConsole bc;
        uint32 ncols = 24;
        uint32 nrows = 8;
        bc.Open(BasicConsoleMode::EnablePaging);
        bc.SetSceneSize(ncols, nrows);
        StreamString str;
        str.Printf("BasicConsole: %s", recStream.Buffer());
        REPORT_ERROR_STATIC(ErrorManagement::Information, "Writing into console: %s", str.Buffer());
        WriteToBasicStream(bc, str);
        bc.Close();
    }

    const char8 * const TEST_FILENAME = "BasicStreamTestExample1.out";
    if (ok) {
        BasicFile f;
        ok = f.Open(TEST_FILENAME, BasicFile::FLAG_CREAT | BasicFile::ACCESS_MODE_W);
        if (ok) {
            StreamString str;
            str.Printf("BasicFile: %s", recStream.Buffer());
            REPORT_ERROR_STATIC(ErrorManagement::Information, "Writing into file: %s", str.Buffer());
            WriteToBasicStream(f, str);
            f.Close();
        }
    }
    if (ok) {
        const uint32 MAX_BUFFER_SIZE = 512;
        char8 buffer[MAX_BUFFER_SIZE];
        uint32 bufferSize = MAX_BUFFER_SIZE;
        BasicFile f;
        ok = f.Open(TEST_FILENAME, BasicFile::ACCESS_MODE_R);
        if (ok) {
            ok = f.Read(&buffer[0], bufferSize);
            f.Close();
        }
        if (ok) {
            StreamString readStr = buffer;
            REPORT_ERROR_STATIC(ErrorManagement::Information, "Read from File: %s", readStr.Buffer());
            Directory d(TEST_FILENAME);
            d.Delete();
        }
    }
    return 0;
}

Start the application and, in another console, type echo -e "HELLO" | nc 127.0.0.1 24680 -w0.

Basic streams

The following is an example that shows the usage of the buffered streams (including the GetLine, GetToken and Printf methods).

Buffered streams example (BufferedStreamsExample1)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
/**
 * @file BufferedStreamsExample1.cpp
 * @brief Source file for class BufferedStreamsExample1
 * @date 30/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class BufferedStreamsExample1 (public, protected, and private). Be aware that some
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "BufferedStreamI.h"
#include "Directory.h"
#include "ErrorLoggerExample.h"
#include "File.h"
#include "UDPSocket.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/

/**
 * @brief Parses tokens from a given stream
 */
static void GetTokensFromStream(MARTe::BufferedStreamI &stream) {
    using namespace MARTe;
    StreamString line = "";
    bool end = false;
    while (!end) {
        stream.GetLine(line);
        StreamString token = "";
        char8 term;
        line.Seek(0u);
        REPORT_ERROR_STATIC(ErrorManagement::Information, "Line: %s", line.Buffer());
        while (line.GetToken(token, ":", term)) {
            REPORT_ERROR_STATIC(ErrorManagement::Information, "Token: %s", token.Buffer());
            end = (token == "END");
            token = "";
        }
        line = "";
    }
}

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/

int main(int argc, char *argv[]) {
    using namespace MARTe;
    SetErrorProcessFunction(&ErrorProcessExampleFunction);

    UDPSocket sock;
    bool ok = sock.Open();
    uint16 port = 24680;
    if (ok) {
        REPORT_ERROR_STATIC(ErrorManagement::Information, "Going to listen in port = %d", port);
        ok = sock.Listen(port);
    }
    if (!ok) {
        REPORT_ERROR_STATIC(ErrorManagement::FatalError, "Failed to listen in port = %d", port);
    }

    if (ok) {
        GetTokensFromStream(sock);
        sock.Close();
    }

    const char8 * const TEST_FILENAME = "BufferedStreamTestExample1.out";
    if (ok) {
        File f;
        ok = f.Open(TEST_FILENAME, BasicFile::FLAG_CREAT | BasicFile::ACCESS_MODE_W);
        if (ok) {
            f.Printf("%s", "FILE\nA1:B1:C1\nD2:E2:F2\nEND");
            f.Flush();
            f.Close();
        }
    }
    if (ok) {
        File f;
        ok = f.Open(TEST_FILENAME, BasicFile::ACCESS_MODE_R);
        if (ok) {
            GetTokensFromStream(f);
            f.Close();
            Directory d(TEST_FILENAME);
            d.Delete();
        }
    }
    return 0;
}

Start the application and, in another console, type echo -e "SOCKET\nA1:B1:C1\nD2:E2:F2\nEND" | nc -u 127.0.0.1 24680 -w0.

Instructions on how to compile and execute the example can be found here.