SophiaFramework UNIVERSE 5.3 |
The stream reads / writes data from / into the storage by using the internal buffer(hereafter, "buffer").
There are two types of buffers from the point of the view of the size, i.e., one is fixed and another is variable. The stream with the variable buffer is called as "variable buffer stream", and one with the fixed buffer is called as "fixed buffer stream".
Table 17.6. Fixed Buffer Stream and Variable Buffer Stream
Item | Fixed Buffer Stream | Variable Buffer Stream |
---|---|---|
Feature | The buffer size is fixed. | The buffer size is variable depending on the size of data to read or write. |
Method to Get (or Set) | Specify the buffer size in the size argument of the GetStreamReader / GetStreamWriter function. | Don't specify the size argument of the GetStreamReader / GetStreamWriter function. |
Method to Read or Write | For data bigger than the buffer size, operation completes with reading from / writing into the stream in multiple times. | Operation always completes with reading from / writing into the stream once. |
Tip | |
---|---|
The buffer of the variable buffer stream is automatically expanded depending on data read from / written into the storage. When it is necessary to save memory or the data size cannot be estimated, it is recommended to read / write data in multiple times with the fixed buffer stream. |
SFXElasticStreamReader / SFXElasticStreamWriter Class | |
---|---|
Though the reading / writing through the variable buffer stream is internally performed with the SFXElasticStreamReader / SFXElasticStreamWriter class, you don't have to be aware of this class. |
The variable buffer stream is the stream whose buffer will be automatically expanded depending on the size of data to be read from / written into the storage.
Since all data is stored into the buffer, operation will complete with reading from / writing into the stream one time.
The variable buffer stream can be gotten by calling the GetStreamReader / GetStreamWriter function of the storage class without specifying the size argument to set the buffer size.
Example 17.22. Reading Data from File with Variable Buffer Stream
SFXFile file; // file SFXAnsiStringStreamReader reader; // stream for reading data from the file SFXAnsiString string; // data to read from the file // open the file in the read only mode if ((error = file.OpenReadOnly(SFXPath("/dir/data.txt"))) == SFERR_NO_ERROR) { // get the stream for reading data from the file // * the stream buffer is variable since the size argument is not specified if ((error = file.GetStreamReader(&reader)) == SFERR_NO_ERROR) { // perform fetch: read data from the file into the stream buffer // *1. the stream buffer will be expanded automatically depending on the size of data to be read into // *2. the read operation will finish by calling the Fetch function once if ((error = reader.Fetch()) == SFERR_NO_ERROR) { // read data from the stream buffer into the string variable if ((error = reader.ReadSFXAnsiString(&string)) == SFERR_NO_ERROR) { // succeed to read data from the file! // display the content of the string variable on BREW Output Window TRACE("%s", string.GetCString()); } } // release the stream for reading from the file reader.Release(); } // close the file file.Close(); } if (error != SFERR_NO_ERROR) { // if an error occurs ... }
Reading Data from File with Variable Buffer Stream | |
---|---|
Each stream has its own buffer(stream buffer). Since the stream for reading data from the file is gotten by calling the SFXFile::GetStreamReader function without the size argument, the variable buffer will be used. Therefore, the stream buffer will be expanded to the same size with the input file. The SFXStreamReader::Fetch function reads data from the file into the stream buffer. The SFXAnsiStringStreamReader::ReadSFXAnsiString function reads data from the stream buffer into the specified variable. |
Example 17.23. Writing Data into File with Variable Buffer Stream
SFXFile file; // file SFXAnsiStringStreamWriter writer; // stream for writing data into the file SFXAnsiString string("abcdefg"); // data to write into the file // open the file in the read-write mode if ((error = file.OpenReadWrite(SFXPath("/dir/data.txt"))) == SFERR_NO_ERROR) { // get the stream for writing data into the file // * the stream buffer is variable since the size argument is not specified if ((error = file.GetStreamWriter(&writer)) == SFERR_NO_ERROR) { // write data from the string variable into the stream buffer // * the stream buffer will be expanded automatically depending on the size of data to be written if ((error = writer.WriteSFXAnsiString(string)) == SFERR_NO_ERROR) { // perform flush: write data from the stream buffer into the file // * the write operation will finish by calling the Flush function once error = writer.Flush(); } // release the stream for writing into the file writer.Release(); } // close the file file.Close(); } if (error != SFERR_NO_ERROR) { // if an error occurs ... }
Writing Data into File with Variable Buffer Stream | |
---|---|
Each stream has its own buffer(stream buffer). Since the stream for writing data into the file is gotten by calling the SFXFile::GetStreamWriter function without the size argument, the variable buffer will be used. Therefore, the stream buffer will be expanded to the same size with the output file. The SFXAnsiStringStreamWriter::WriteSFXAnsiString function writes data from the string variable into the stream buffer. The SFXStreamWriter::Flush function writes data from the stream buffer into the file. |
Example 17.24. TCP Socket Communication with Variable Buffer Stream
// The _socket variable is defined as class member variable since used in the callback function class MyClass { private: SFXTCPSocket _socket; // SFXTCPSocket instance SFXAnsiStringStreamReader _reader; // input stream SFXAnsiStringStreamWriter _writer; // output stream public: Void Start(Void); XALLBACK_DECLARE_SFXTCPSOCKET(OnConnect) XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) XALLBACK_DECLARE_SFXANSISTRINGSTREAMWRITER(OnFlush) }; Void MyClass::Start(Void) { SFCError error; SFXSocketAddress host("www.example.com:80"); // open the TCP socket if ((error = _socket.Open()) == SFERR_NO_ERROR) { // connect to the TCP server // *1. the connection result will be notified to the OnConnect function // *2. the host name will be automatically resolved error = _socket.Connect(host, XALLBACK_INTERNAL(OnConnect)); } if (error != SFERR_NO_ERROR) { // if an error occurs // close the socket _socket.Close(); } return; } // callback function notified of the connection result XALLBACK_IMPLEMENT_SFXTCPSOCKET(MyClass, OnConnect, error) { // string to send static AChar message[] = "GET / HTTP/1.0\r\n\r\n"; if (error == SFERR_NO_ERROR) { // get the variable buffer stream for sending data // * the stream buffer is variable since the size argument is not specified if ((error = _socket.GetStreamWriter(&_writer)) == SFERR_NO_ERROR) { // write data from the message variable into the stream buffer // * the stream buffer will be expanded automatically depending on the size of data to be written if ((error = _writer.Write(message, lengthof(message))) == SFERR_NO_ERROR) { // perform flush: send data from the stream buffer to the socket actually // * the flush result will be notified to the OnFlush function error = _writer.Flush(XALLBACK_INTERNAL(OnFlush)); } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release the _writer stream _writer.Release(); // close the socket _socket.Close(); } return; } // callback function notified of the flush result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMWRITER(MyClass, OnFlush, error) { // release the _writer stream since sending data has been done _writer.Release(); if (error == SFERR_NO_ERROR) { // get the variable buffer stream for receiving data // * the stream buffer is variable since the size argument is not specified if ((error = _socket.GetStreamReader(&_reader)) == SFERR_NO_ERROR) { // perform fetch: receive data from the socket into the stream buffer actually // *1. the fetch result will be notified to the OnFetch function // *2. the stream buffer will be expanded automatically depending on the size of data to be received error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch)); } } if (error != SFERR_NO_ERROR) { // if an error occurs // release the _reader stream _reader.Release(); // close the socket _socket.Close(); } return; } // callback function notified of the fetch result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { SFXAnsiString string; if (error == SFERR_NO_ERROR) { // read data from the stream buffer into the string variable _reader >> string; // display the content of the string variable on BREW Output Window TRACE("%s", string.GetCString()); } // release the _reader stream since receiving data has been done _reader.Release(); // close the socket _socket.Close(); return; }
TCP Socket Communication with Variable Buffer Stream | |
---|---|
Each stream has its own buffer(stream buffer). Since the stream for receiving from / sending to the TCP socket is gotten by calling the SFXTCPSocket::GetStreamReader / SFXTCPSocket::GetStreamWriter function with no size argument, the variable buffer will be used. Therefore, the stream buffer will be expanded to the same size with data to receive / send. The SFXAnsiStringStreamWriter::WriteSFXAnsiString function writes data from the string variable into the stream buffer. The SFXAnsiStringStreamReader::ReadSFXAnsiString function reads data from the stream buffer into the string variable. The SFXStreamWriter::Flush function sends data from the stream buffer into the TCP socket. The SFXStreamReader::Fetch function receives data from the TCP socket into the stream buffer. |
The fixed buffer stream is the stream whose buffer size is fixed regardless of the size of data to read from / write into the storage.
If data to read / write is bigger than the buffer size, you will have to read from / write into the stream in multiple times.
The fixed buffer stream can be obtained by calling the GetStreamReader / GetStreamWriter function of the storage class with specifying the size argument to set the buffer size.
Example 17.25. Reading Data from File with Fixed Buffer Stream
SFCError error; // error value SFXFile file; // input file SFXAnsiStringStreamReader reader; // input stream SFXAnsiString stringFromFile; // for storing data SFXAnsiString tempString; // open the file in the read-only mode if ((error = file.OpenReadOnly(SFXPath("/dir1/data.txt"))) == SFERR_NO_ERROR) { // get the input stream for reading data from the file // * since the size argument is specified, the stream buffer size is fixed (buffer size: 1024) if ((error = file.GetStreamReader(1024, &reader)) == SFERR_NO_ERROR) { while ((error == SFERR_NO_ERROR) && !reader.Ends()) { // * repeat the following processing until the end of the file is reached // data greater than the stream buffer size are read by calling the Fetch function in multiple times // perform fetch: read data from the input file into the stream buffer actually // * since the stream buffer size is fixed by 1024 byte, data more than 1024 byte cannot be read per the fetch operation if ((error = reader.Fetch()) == SFERR_NO_ERROR) { // read data from the stream buffer into the tempString variable if ((error = reader.ReadSFXAnsiString(&tempString)) == SFERR_NO_ERROR) { // succeed to read! // append tempString to the end of the stringFromFile variable stringFromFile += tempString; } } } // release the input stream for reading data from the file reader.Release(); } // close the file file.Close(); } if (error != SFERR_NO_ERROR) { // if an error occurs ... }
In the above example, since the buffer size is set to 1024 byte, more than 1024 byte cannot be read per the fetch operation. To read data more than 1024 byte, repeat the fetch operation several times.
Example 17.26. Writing Data into File with Fixed Buffer Stream
SFCError error; // error value SFXFile file; // output file SFXAnsiStringStreamWriter writer; // output stream SFXAnsiString string("abcdefghijklmnopqrstuvwxyz"); // data to write ACharConstPtr _p = string.GetBuffer(); // pointer to string ACharConstPtr _endOfString = _p + string.GetLength(); // end of string SInt32 bufferSize = 1024; // open the file in the read write mode if ((error = file.OpenReadWrite(SFXPath("/dir/data.txt"))) == SFERR_NO_ERROR) { // get the output stream for writing data into the file // * since the size argument is specified, the stream buffer size is fixed (buffer size: 1024) if ((error = file.GetStreamWriter(bufferSize, &writer)) == SFERR_NO_ERROR) { for (; (error == SFERR_NO_ERROR) && (_p < _endOfString) ; _p += bufferSize) { // data greater than the stream buffer size are written by calling the Flush function in multiple times // size of the string to be written into the file SInt32 size = (_endOfString - _p < bufferSize) ? _endOfString - _p : bufferSize; // write the _p string into the stream buffer if ((error = writer.Write(_p, size)) == SFERR_NO_ERROR) { // perform flush: write data from the stream buffer into the file actually error = writer.Flush(); } } // release the output stream for writing data into the file writer.Release(); } // close the file file.Close(); } if (error != SFERR_NO_ERROR) { // if an error occurs ... }
Writing Data into File with Fixed Buffer Stream | |
---|---|
Since the buffer size of 1024 bytes is specified in the size argument when the SFXFile::GetStreamWriter function is called, data will be written into the file using the fixed buffer stream. The maximum size of data that can be written into the stream buffer per calling the SFXStreamWriter::Write function is 1024 bytes. Therefore, The maximum size of data that can be written into the file per calling the SFXStreamWriter::Flush function is also 1024 bytes. To write data greater than 1024 bytes into the file, it is necessary to call the SFXStreamWriter::Write function and the SFXStreamWriter::Flush function in multiple times. |
Example 17.27. TCP Socket Communication with Fixed Buffer Stream
// The _socket variable is defined as class member variable since used in the callback function class MyClass { private: SFXTCPSocket _socket; // TCP Socket instance SFXAnsiStringStreamReader _reader; // input stream SFXAnsiStringStreamWriter _writer; // output stream SFXAnsiString _sendString; // string to send ACharConstPtr _p; ACharConstPtr _end; SInt32 _bufferSize; SFXAnsiString _receiveString; // string to be received public: Void Start(Void); XALLBACK_DECLARE_SFXTCPSOCKET(OnConnect) XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) XALLBACK_DECLARE_SFXANSISTRINGSTREAMWRITER(OnFlush) }; Void MyClass::Start(Void) { SFCError error; SFXSocketAddress host("www.example.com:80"); // string to send _sendString = "GET / HTTP/1.0\r\n\r\n"; // buffer size: 1024 _bufferSize = 1024; // open the socket if ((error = _socket.Open()) == SFERR_NO_ERROR) { // connect to the TCP server // *1. the connection result will be notified to the OnConnect function // *2. the host name will be automatically resolved error = _socket.Connect(host, XALLBACK_INTERNAL(OnConnect)); } if (error != SFERR_NO_ERROR) { // if an error occurs // close the socket _socket.Close(); } return; } // callback function notified of the connection result XALLBACK_IMPLEMENT_SFXTCPSOCKET(MyClass, OnConnect, error) { if (error == SFERR_NO_ERROR) { // get the input stream for receiving data from the socket // * since the size argument is specified, the stream buffer size is fixed (buffer size: 1024) if ((error = _socket.GetStreamWriter(_bufferSize, &_writer)) == SFERR_NO_ERROR) { _p = _sendString.GetBuffer(); _end = _p + _sendString.GetLength(); SInt32 size = (_end - _p < _bufferSize) ? _end - _p : _bufferSize; // write the _p string into the stream buffer if ((error = _writer.Write(_p, size) == SFERR_NO_ERROR) { _p += size; // perform flush: send data from the stream buffer to the socket actually // * the flush result will be notified to the OnFlush function error = _writer.Flush(XALLBACK_INTERNAL(OnFlush)); } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release the output stream for sending data to the socket _writer.Release(); // close the socket _socket.Close(); } return; } // callback function notified of the flush result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMWRITER(MyClass, OnFlush, error) { if (error == SFERR_NO_ERROR) { if (_p < _end) { // when data to send is still remaining: // data greater than the stream buffer size are written by calling the Flush function in multiple times SInt32 size = (_end - _p < _bufferSize) ? _end - _p : _bufferSize; // write the _p string into the stream buffer if ((error = _writer.Write(_p, size) == SFERR_NO_ERROR) { _p += size; // perform flush: send data from the stream buffer to the socket actually // * the flush result will be notified to the OnFlush function error = _writer.Flush(XALLBACK_INTERNAL(OnFlush)); } } else { // when all data has been sent: // release the output stream for sending data to the socket _writer.Release(); // start to receive // get the output stream for sending data to the socket // * since the size argument is specified, the stream buffer size is fixed (buffer size: 1024) if ((error = _socket.GetStreamReader(_bufferSize, &_reader)) == SFERR_NO_ERROR) { // perform fetch: receive data from the socket into the stream buffer actually // * the fetch result will be notified to the OnFetch function error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch)); } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release the input stream for receiving data from the socket _reader.Release(); // release the output stream for sending data to the socket _writer.Release(); // close the socket _socket.Close(); } return; } // callback function notified of the fetch result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { SFXAnsiString string; if (error == SFERR_NO_ERROR) { // read data from the stream buffer into the string variable if ((error = _reader.ReadSFXAnsiString(&string)) != SFERR_NO_ERROR) { _receiveString += string; if (!_reader.Ends()) { // if data to be received is still remaining: // data greater than the stream buffer size are received by calling the Fetch function in multiple times // perform fetch: receive data from the socket into the stream buffer actually // * the fetch result will be notified to the OnFetch function error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch)); } else { // if all data has been received: // display the received data on BREW Output Window TRACE("--------"); TRACE("%s", _receiveString.GetCString()); TRACE("--------"); // release the input stream for receiving data from the socket _reader.Release(); // close the socket _socket.Close(); } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release the input stream for receiving data from the socket _reader.Release(); // close the socket _socket.Close(); } return; }
TCP Socket Communication with Fixed Buffer Stream | |
---|---|
To receive data bigger than the stream buffer size, you have to call the SFXStreamReader::Fetch function and the SFXAnsiStringStreamReader::ReadSFXAnsiString function in multiple times. Every time the SFXStreamReader::Fetch function is called, the OnFetch callback function will be called. On the other hand, to send data bigger than the stream buffer size, you have to call the SFXStreamWriter::Write function and the SFXStreamWriter::Flush function in multiple times. Every time the SFXStreamWriter::Flush function is called, the OnFlush callback function will be booted up. |
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |