PrevNextUpHome BREW C++ Class Library & GUI Framework & XML Middleware : SophiaFramework 4.1

17.2. Storage Classes

The Storage classes are for inputting from or outputting to file, network, or memory using the stream.

Table 17.2. Storage Classes

Class Name Description
SFXFile Class for operating a file.
SFXHTTPConnection Class for the HTTP/HTTPS communication.
SFXTCPSocket Class for the TCP socket communication.
SFXSSLSocket Class for the SSL socket communication.
SFXMemory Storage class for the memory stream.
SFXSource Storage class for reading data from the ISource interface.
SFXZIPDecoder Storage class for decompressing the DEFLATE compressed data by gzip.

Since the input/output method using the stream is almost same with all storages except the following differences, generic programming independent of storage devices can be implemented in the SophiaFramework environment.

Table 17.3. Table for Read/Write Function with or without Callback Function on Storage Classes

  read without callback function read with callback function write without callback function write with callback function
SFXFile O O O X
SFXHTTPConnection X O X O
SFXTCPSocket X O X O
SFXSSLSocket X O X O
SFXMemory O X O X
SFXSource Depend on the BREW ISource O X X
SFXZIPDecoder Depend on the registered storage O X X
[Note] Note
In the SFXSource and SFXZIPDecoder class, read function without callback function is not available for some kinds of source and registered storage. For instance, since read function without callback function on SFXTCPSocket is not available, gzipped data from SFXTCPSocket cannot be decompressed by registering it in SFXZIPDecoder without callback function.

17.2.1. File Class

Create the SFXFile instance, and then open the file.

There are two modes to open the file: read only mode and read/write mode.

Example 17.21. Initiate

SFXFile file;

// open in read only mode
file.OpenReadOnly(SFXPath("/dir1/data.txt"));

// open in read/write mode
file.OpenReadWrite(SFXPath("/dir1/data.txt"));

// get stream
file.GetStreamReader(&reader);
file.GetStreamWriter(&writer);

// read and write using the stream

Example 17.22. Terminate

// close file
file.Close();

Example 17.23. Input from the file

SFXFile file;                     // input file
SFXAnsiStringStreamReader reader; // input stream
SFXAnsiString string;             // variable to be read

// open file in read only mode
file.OpenReadOnly(SFXPath("/dir1/data.txt"));

// get input stream
file.GetStreamReader(&reader);

// read data from file into stream buffer
reader.Fetch();

// read data from stream buffer into specified variable
reader.ReadSFXAnsiString(&string);

In the stream, there is a buffer for data I/O.

The Fetch function reads data from the file storage and stores them to the stream buffer.

And the ReadSFXAnsiString function reads data from the stream buffer and stores them to the specified variable.

[Note] Size of Stream Buffer

In the code above, the memory size of allocated stream buffer is same as the file size. Memory for the "string" variable is also allocated with the same memory size as the stream buffer.

[Note] The method to divide data into several segments and read each segment separately

Input from the file with the buffer of fixed length

Example 17.24. Write to the file

SFXFile file;                     // output file
SFXAnsiStringStreamWriter writer; // output stream
SFXAnsiString string("abcdefg");  // variable to be written

// open file in read/write mode
file.OpenReadWrite(SFXPath("/dir1/data.txt"));

// get output stream
file.GetStreamWriter(&writer);

// write specified variable to stream buffer
writer.WriteSFXAnsiString(string);

// write stream buffer to file actually
writer.Flush();

The WriteSFXAnsiString function writes data of specified variable to the stream buffer.

And the Flush function writes data in the stream buffer to the file storage actually.

[Caution] If the Flush function is not called ...

Data will not be written when the file is closed without calling the Flush function.

[Note] Size of Stream Buffer

In the code above, the memory size of allocated stream buffer is same as the allocated memory size for the "string" variable.

[Note] The method to divide data into several segments and write them separately

Every time after writting a divided data segment to the stream buffer using the Write function, call the Flush function to write data segment in the stream buffer to the file actually. And call the Write and Flush functions by turns repeatedly until there is no data segment to be written.

17.2.2. Class for the TCP Socket Communication

In the TCP Socket communication using the SFXTCPSocket class, data can be sent or received through the streams.

To send and receive data through the TCP socket communication, take the following procedures using the stream and the callback function after creating and openning the TCP socket, and connecting the TCP server.

Sending

  1. Get the output stream for sending data from the TCP socket.
  2. Write data to the output stream.
  3. Send the data actually and register the callback function, which will receive the notification of sending data.
  4. The callback function above is called after sending data.
  5. In the callback function, execute the processing after sending data.

Receiving

  1. Get the input stream for receiving data from the TCP socket.
  2. Receive data actually and register the callback function, which will receive the notification of receiving data.
  3. The callback function above is called after receiving data.
  4. In the callback function, read data from the input stream.

Related Information: Network: Socket Communication

Example 17.25. TCP Socket Communication through the stream

// SFXTCPSocket instance is defined as class member variable for the callback function
class MyClass {
private:
    SFXTCPSocket _socket;                // SFXTCPSocket instance
    SFXAnsiStringStreamReader  _reader;  // input stream
    SFXAnsiStringStreamWriter  _writer;  // output stream
public:
    Void Start(Void);
    CALLBACK_DECLARE_SFXTCPSOCKET(OnConnect)
    CALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch)
    CALLBACK_DECLARE_SFXANSISTRINGSTREAMWRITER(OnFlush)
};

Void MyClass::Start(Void)
{
    // initiation
    _socket.Open();
    
    // start to connect (connection establishment will be notified to OnConnect function)
    _socket.Connect(SFXSocketAddress("www.example.com:80"), CALLBACK_FUNCTION(OnConnect));
}

// callback function notified of connection establishment
CALLBACK_IMPLEMENT_SFXTCPSOCKET(MyClass, OnConnect, error)
{
    // get input stream for receiving data
    _socket.GetStreamReader(&_reader);
    
    // get output stream for sending data
    _socket.GetStreamWriter(&_writer);
    
    // write data
    _writer.WriteSFXAnsiString("GET / HTTP/1.1\r\n\r\n");
    
    // send data actually (completion of sending data will be notified to OnFlush function actually)
    _writer.Flush(CALLBACK_FUNCTION(OnFlush));
}

// callback function notified of completion of sending data actually actually
CALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMWRITER(MyClass, OnFlush, error)
{
    // receive data

    // receive data acrually (completion of receiving data will be notified to OnFetch function actually)
    _reader.Fetch(CALLBACK_FUNCTION(OnFetch));

    // error will occur if the _reader.Read function is called here
}

// callback function notified of completion of receiving data actually
CALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error)
{
    SFXAnsiString string;

    // store received data in specified variable
    _reader.ReadSFXAnsiString(&string);
}

17.2.3. Class for the HTTP Communication

In the communication using the SFXHTTPConnection class, data can be sent and received through the streams.

Example 17.26. HTTP communication through the stream

SFXHTTPConnection _http;

// initiation
_http.Open();

// start to connect(connection establishment will be notified to OnConnect function)
_http.Connect(SFXSocketAddress("www.example.com:80"), CALLBACK_FUNCTION(OnConnect));

// ...

// close connection
_http.Close();

17.2.4. Class for the SSL Socket Communication

In the SSL Socket communication using the SFXSSLSocket class, data can be sent or received through the streams in the same way as the TCP Socket communication, except one more addition procedure, negotiation, is needed after the connection is established.

Only the difference from the TCP Socket communication is shown.

Example 17.27. SSL Socket communication through the stream

// callback function notified of connection establishment
CALLBACK_IMPLEMENT_SFXSSLSOCKET(MyClass, OnConnect, error)
{
    // register callback function (negotiation completion will be notified to OnNegotiate function)
    _socket.Negotiate(CALLBACK_FUNCTION(OnNegotiate));
}

// callback function notified of negotiation completion
CALLBACK_IMPLEMENT_SFXSSLSOCKET(MyClass, OnNegotiate, error)
{
    // get streams
    _socket.GetStreamReader(&_reader);
    _socket.GetStreamWriter(&_writer);

    // receive and send data through streams
}

17.2.5. Memory Class

Memory class (SFXMemory) is the class that represents memory(buffer), which is used for reading or writing data through the stream.

How to use the SFXMemory class

  1. Create the SFXMemory instance.
  2. Open the memory storage using the SFXMemory::Open function.
  3. Get the input stream for reading data from memory and the output stream for writing data to memory by the SFXMemory::GetStreamReader function and SFXMemory::GetStreamWriter function respectively.
  4. Read data from the input stream and write data to the output stream.
  5. After using the input or output stream, release resources by calling the SFXMemory::Close function.

Example 17.28. Initiate

SFXMemory memory;

// open empty memory (size = 0)
memory.Open();

// open memory that has specified value in internal buffer
memory.Open("data buffer", 11);

// get streams
memory.GetStreamReader(&reader);
memory.GetStreamWriter(&writer);

// read and write data through streams
[Note] Note
There are two methods to create the SFXMemory instance and open the memory.

Example 17.29. Terminate 1

// close memory (internal buffer will be empty)
memory.Close();

When closing memory, its content can be stored into the specified variable as the code below.

Example 17.30. Terminate 2

SFXBuffer buffer;

// close memory(internal buffer will be empty after copying its content to specified variable)
memory.Close(&buffer);

17.2.6. Class for Accessing the BREW ISource Interface

To access the BREW ISource interface through the stream of SophiaFramework, use the SFXSource class.

How to use the SFXSource class

  1. Create the SFBSource instance and prepare the storage for reading data from the ISource interface. And then register the storage using the SFXSource::Open function.
  2. Get the input stream for reading data from the ISource interface using the SFXSource::GetStreamReader function.
  3. Read data from the input stream. Whether or not data is read using the callback function depends on the type of storage.
  4. After using the input stream, release resources by calling the SFXSource::Close function.

Example 17.31. Initiate

// BREW ISource
SFBSourceSmp brewSource;

SFXSource source;

source.Open(brewSource);

source.GetStreamReader(&reader);

// read from reader

Example 17.32. Terminate

source.Close();

Detailed information: Sample Code

17.2.7. Class for Decompressing the gzipped File

SFXZIPDecoder is the class for decompressing the DEFLATE compressed data by gzip which is stored in the SFBSource or SFBAStream instance or in the storage such as SFXFile or SFXTCPSocket.

How to use the SFXZIPDecoder class

  1. Create the SFXZIPDecoder instance.
  2. Register the DEFLATE compressed data of a storage, SFBAStream, or SFBSource class by calling the SFXZIPDecoder::Open function.
  3. Get the input stream for reading data from ZIPDecoder using the SFXZIPDecoder::GetStreamReader function.
  4. Read the decompressed data through the input stream

Example 17.33. Initiate

SFXFile file;
SFXZIPDecoder decoder;
SFXAnsiString string;

// open file
file.Open(SFXPath("/testdata.tar.gz"));

// register specified storage in decoder
// SFBSource or  SFBAStream  instance can also be registered
decoder.Open(file);

// get stream for reading
decoder.GetStreamReader(&reader);

Example 17.34. Terminate

decoder.Close();
file.Close();

Detailed Information: Sample Code