Vyoms OneStopTesting.com - Testing EBooks, Tutorials, Articles, Jobs, Training Institutes etc.
OneStopGate.com - Gate EBooks, Tutorials, Articles, FAQs, Jobs, Training Institutes etc.
OneStopMBA.com - MBA EBooks, Tutorials, Articles, FAQs, Jobs, Training Institutes etc.
OneStopIAS.com - IAS EBooks, Tutorials, Articles, FAQs, Jobs, Training Institutes etc.
OneStopSAP.com - SAP EBooks, Tutorials, Articles, FAQs, Jobs, Training Institutes etc.
OneStopGRE.com - of GRE EBooks, Tutorials, Articles, FAQs, Jobs, Training Institutes etc.
Bookmark and Share Rss Feeds

Extending the Basic Streams in C++ | Articles | Recent Articles | News Article | Interesting Articles | Technology Articles | Articles On Education | Articles On Corporate | Company Articles | College Articles | Articles on Recession
Sponsored Ads
Hot Jobs
Fresher Jobs
Experienced Jobs
Government Jobs
Walkin Jobs
Placement Section
Company Profiles
Interview Questions
Placement Papers
Resources @ VYOMS
Companies In India
Consultants In India
Colleges In India
Exams In India
Latest Results
Notifications In India
Call Centers In India
Training Institutes In India
Job Communities In India
Courses In India
Jobs by Keyskills
Jobs by Functional Areas
Learn @ VYOMS
GATE Preparation
GRE Preparation
GMAT Preparation
IAS Preparation
SAP Preparation
Testing Preparation
MBA Preparation
News @ VYOMS
Freshers News
Job Articles
Latest News
India News Network
Interview Ebook
Get 30,000+ Interview Questions & Answers in an eBook.
Interview Success Kit - Get Success in Job Interviews
  • 30,000+ Interview Questions
  • Most Questions Answered
  • 5 FREE Bonuses
  • Free Upgrades

VYOMS TOP EMPLOYERS

Wipro Technologies
Tata Consultancy Services
Accenture
IBM
Satyam
Genpact
Cognizant Technologies

Home » Articles » Extending the Basic Streams in C++

Extending the Basic Streams in C++








Article Posted On Date : Monday, April 5, 2010


Extending the Basic Streams in C++
Advertisements

The basic stream library (iostream) is designed to resolve most of the general problems you may run into during your programming endeavors. However, sometimes it simply isn't enough, and you need to extend it to suit your application—your special situation. This article will show you how to do that.

The key area in the streams is the buffer area that is included in the streambuff class. Most of the time this function works in the background, accomplishing  tasks that are a little more complex. Perceive this as an internal class that does the heavy work, while the rest of the classes that you declare when working with streams are just specializations of this one.

For a start, let's see how the buffer area works and how it is constructed to assure an efficient build up of the streams. Before we move on, let me specify that although this article is part of my series about streams, it will be a little more advanced. At least a good knowledge of C and a strong OOP background are required if you aim to completely understand and grasp my words. 

This content of this article may not even be useful to you unless you care about a specific mode for performance. The polymorphic power of C++ gives you the possibility to use it in a multitude of ways, and you may find a different approach paired with a good solution using the already-defined streams. Nevertheless, this article will give you a greater insight into how it works behind the scene. If you are interested, just read on and be amazed.

Read my introduction to streams; once you're done we can move on. As mentioned during the previous article of this series (Basic I/O), the ofstream, ifstream are just typedefs of the basic_isftream/basic_ofstream with the template parameter "char." Those were made to attract newcomers to the library and so that you will write less.

So in fact, this brings us to the point that we can declare the basic_ifstream to any type: for example, on a Car Type. The compiler might not even complain about it (this is subject to how that specific class is constructed). However, once you start calling functions around, serious errors will pop up.

The problem is simply that there is no trait_type structure declared for a Car Type. In the basic package of the library, the C++ programming guide defined only the wide and narrow characters. This you will find in the iosfwd file input. Writing a specialization for the Car Type can also be troublesome; it will prove to be simpler to go even further in the derivation list of the basic_ifstream and find that the road leads to the filebuffer.

First, let me tell you that there are three types of streams in C++, namely the fstream (for file I/O), the sstream (for C type character sequences - char*- however this is a leftover from the days of C++ standardization for compatibility reasons and should not be used, as support for this in the future may be removed; this isn't a template class) and strstream (for the string type of the STL library). Now all of these will have in common the fact that the text stored eventually is a text. That is why the following code snippet succeeds in execution:



#include <iostream>

#include <sstream>

#include <strstream>


using namespace std;


char alfa = 'A';


template < typename _S>

std::basic_ostream<_S>& fillWithText (std::basic_ostream<_S>& stream)

{

stream << "Filled with text the " << alfa++ << "Stream"<< std::endl;

return stream;

}


int main()

{

wostringstream A;

wostream& B = std::wcout;

 

fillWithText<wchar_t>(A);

std::wcout << A.str();

 

fillWithText<wchar_t>(B);


}


Moreover, the result is:


Filled with text the A Stream

Filled with text the B Stream

Press any key to continue . . .


First, let's point out that you can assign a string to the standard input/output, and in the future thread it just as the cout stream class. Second, look at the way we printed the A stream. The str() function returns a pointer to the character sequence inside the stream itself, though it will print all that we put inside it in the meantime.

The existence of this pointer can be reduced to the inside representation of a stream. The streambuff class handles this. A schematic representation looks like the figure below.


The streambuffer has the following definition once you open up the streambuf header:


class basic_streambuf

{ // control read/write buffers

/...

protected:

basic_streambuf()

: _Plocale(_NEW_CRT(locale))

{ // construct with no buffers

_Init();

}

/...

protected:

_Elem *eback() const;

_Elem *gptr() const;

_Elem *pbase() const;

_Elem *pptr() const;

_Elem *egptr() const;

void gbump(int _Off);

void setg(_Elem *_First, _Elem *_Next, _Elem *_Last)

 

_Elem *epptr() const;

_Elem *_Gndec();

_Elem *_Gninc();

_Elem *_Gnpreinc();

void pbump(int _Off);

void setp(_Elem *_First, _Elem *_Last);

void setp(_Elem *_First, _Elem *_Next, _Elem *_Last);

_Elem *_Pninc();

 

void _Init()

{ // initialize buffer parameters for no buffers

_IGfirst = &_Gfirst, _IPfirst = &_Pfirst;

_IGnext = &_Gnext, _IPnext = &_Pnext;

_IGcount = &_Gcount, _IPcount = &_Pcount;

setp(0, 0), setg(0, 0, 0);

}


void _Init(_Elem **_Gf, _Elem **_Gn, int *_Gc,

_Elem **_Pf, _Elem **_Pn, int *_Pc)

{ // initialize buffer parameters as specified

_IGfirst = _Gf, _IPfirst = _Pf;

_IGnext = _Gn, _IPnext = _Pn;

_IGcount = _Gc, _IPcount = _Pc;

}


private:

_Elem *_Gfirst; // beginning of read buffer

_Elem *_Pfirst; // beginning of write buffer

_Elem **_IGfirst; // pointer to beginning of read buffer

_Elem **_IPfirst; // pointer to beginning of write buffer

_Elem *_Gnext; // current position in read buffer

_Elem *_Pnext; // current position in write buffer

_Elem **_IGnext; // pointer to current position in read

_Elem **_IPnext; // pointer to current position in write

int _Gcount; // length of read buffer

int _Pcount; // length of write buffer

int *_IGcount; // pointer to length of read buffer

int *_IPcount; // pointer to length of write buffer

};


This is, of course, a simpler version; I have omitted a lot of functions as these alone are the ones on which we want to focus. The figure at the end of the previous page already gave a hint as to how this is built up, and the code should make that crystal clear.

Any I/O stream will have two buffers: a get area and a put area. An ifstream will have a get, an ofstream will have a put and of course, the iostream will have both of them. The buffers may be overlapped also, as is the case with files(filebuffer).

The base() and ebuf() functions will return the pointers within which the stream buffer holds its data. Inside these, you will find two areas: one for the input data and one for the output streams (get/put).

These on their own are delimited into an area and have a pointer for the current position inside them. On the get area the eback () and egptr () functions delimit the boarders, while the gptr () handles the current positions pointer.

The same rules apply for the put area, delimited by the pbase () and epptr () functions. Returned pointers are separate; pointers returned by the function pptr () will show the current position.

There exist two _Init() functions to handle the initialization of this pointer. The default will just assign each pointer to NULL and will make the stream unbuffered.

Unbuffered streams will not save any of the input directly; rather, they will just push on further for each character. The second function has four pointers to delimit the borders for the put and get area, and in addition, two int* pointers that correspond to the size of the areas.

The two areas are different from each other, and while the one of them is buffered, the other can be unbuffered -- or any other combination you can imagine. When choosing between buffered and unbuffered versions, keep in mind that the buffered version can have many advantages of performance improvement, as it will minimize the number of system calls, as I explained in the Introduction to Streams article.

The determination of the stream you use, whether they are buffered or not, is reduced to checking if the corresponding pointers are or are not null. Of course, putting/reading data from either of the areas is allowed only if the pointers are valid, and they are in the corresponding sequence. For instance, if gptr() < egptr() you are free to read the data, and with it, move after each char and read the current position pointer.

The gbump(), _Gndec(), _Gninc(), _Gnpreinc(), _Pninc(), pbump() functions are for handling these pointers by increasing/decreasing them or more exactly moving the current position pointer in the areas. Here you should notice the lack of the decrease function for the put area.

This is because the developer team thought that this can lead to unexpected errors and did not want to encourage this. You see, this can lead to data being overwritten, and with it, corrupted data for a stream introduced earlier. Reading old data will cause no harm to anyone, but producing data corruption is certainly going to do so.


With this, you know enough about the class that you should already have a sharp idea in mind of how you can use it. Let me also mention that other points of interest in this class are two more functions. The get and put xsgetn() [inside it will be called a secure version the _Xsgetn_s()] and the xsputn(). The creators and further developers of the STL will put in front of the functions the character x to distinguish it from the ones you write.

This will treat every aspect of your stream and get or put char into areas accordingly. If you break down the code, you will see that in the case of an unbuffered stream you will get an uflow () for the get area and the overflow() in the case of the put area. The same is true for a buffered stream, but in addition, now we need to worry about more characters.

For this, I will not insert the code directly here, as it is rather long and you can find it inside the streambuff class of your compiler. Now only one more unanswered question remains: how do we transform the data from the put area to the consumer?

Just like the proper print on the screen in the case of the console window, the function that is responsible for doing this even in the case of the iostream classes is the virtual function sync() inside the stream buffer.

This will handle the job, but the question is, do you need to call this function after every time you work on the buffer? This can turn out to be a quite annoying and boring job, so the developers came up with a better idea that you can observe in the iostream library.

Each time the buffer is touched, a so-called basic_ostream<>::sentry is created. When the function terminates on the sentry's destructor inside the osfx() function, the flush() is called if the unitbuf flag bit is on.

Unitbuf is one of the many format flags of the Iostream Library. This explicitly points out that the buffer should be flushed after each output. It is highly recommended to leave this one on, but you may turn it off if you are in pursuit of a great performance and you know that you do not need up to date synchronization. Be aware if you turn this off, only one output will be synchronized at a time.


cout << " Developer Shed";


This would result in only Developer output; however, in a future output operation, the Shed will also be printed, as it was put inside the buffer.

The basic_istream::sentry does the same work on the constructor, as you need to synchronize up before the reading starts. In the end, you are free to implement this in whatever way you find best; the presented solution is just an example of how it can be done following the standards. The streams used for the file handling (including the cin/cout) are not overwriting the xsgetn() and xsputn() functions as they follow the basic conventions.

Of course, the list of the existing functions is still large, and many more can be done, but you rarely use them and this will give you a basic idea as to how the streams are built a little more explicitly than my Introduction to Streams article pointed out. The basic implementation for other virtual functions will all return _Tr::eof() so it will not produce eventual unexpected errors.

Deriving from the streambuff class allows you to create an Input/output system based on your personal needs and starting from steady ground. The possibilities where this can be used are endless; all you need is to put your neurons to work.

Network communication can profit from streams the most. Making communication a piece of cake is perfectly achievable. Writing a game inside the communication can have many input endpoints and output endpoints, while all of them stay synchronized, allowing the players to maintain a conference.

With a little coding patience and commitment, much can be achieved. You may use this article as a starting point for that, or just to comprehend the buildup of the I/O feature of the C++ via the streams a little more. Feel free to ask the people around (including me) additional questions here in the blog section or over at the DevHardware Forums.

Live with passion!

DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.






Sponsored Ads



Interview Questions
HR Interview Questions
Testing Interview Questions
SAP Interview Questions
Business Intelligence Interview Questions
Call Center Interview Questions

Databases

Clipper Interview Questions
DBA Interview Questions
Firebird Interview Questions
Hierarchical Interview Questions
Informix Interview Questions
Microsoft Access Interview Questions
MS SqlServer Interview Questions
MYSQL Interview Questions
Network Interview Questions
Object Relational Interview Questions
PL/SQL Interview Questions
PostgreSQL Interview Questions
Progress Interview Questions
Relational Interview Questions
SQL Interview Questions
SQL Server Interview Questions
Stored Procedures Interview Questions
Sybase Interview Questions
Teradata Interview Questions

Microsof Technologies

.Net Database Interview Questions
.Net Deployement Interview Questions
ADO.NET Interview Questions
ADO.NET 2.0 Interview Questions
Architecture Interview Questions
ASP Interview Questions
ASP.NET Interview Questions
ASP.NET 2.0 Interview Questions
C# Interview Questions
Csharp Interview Questions
DataGrid Interview Questions
DotNet Interview Questions
Microsoft Basics Interview Questions
Microsoft.NET Interview Questions
Microsoft.NET 2.0 Interview Questions
Share Point Interview Questions
Silverlight Interview Questions
VB.NET Interview Questions
VC++ Interview Questions
Visual Basic Interview Questions

Java / J2EE

Applet Interview Questions
Core Java Interview Questions
Eclipse Interview Questions
EJB Interview Questions
Hibernate Interview Questions
J2ME Interview Questions
J2SE Interview Questions
Java Interview Questions
Java Beans Interview Questions
Java Patterns Interview Questions
Java Security Interview Questions
Java Swing Interview Questions
JBOSS Interview Questions
JDBC Interview Questions
JMS Interview Questions
JSF Interview Questions
JSP Interview Questions
RMI Interview Questions
Servlet Interview Questions
Socket Programming Interview Questions
Springs Interview Questions
Struts Interview Questions
Web Sphere Interview Questions

Programming Languages

C Interview Questions
C++ Interview Questions
CGI Interview Questions
Delphi Interview Questions
Fortran Interview Questions
ILU Interview Questions
LISP Interview Questions
Pascal Interview Questions
Perl Interview Questions
PHP Interview Questions
Ruby Interview Questions
Signature Interview Questions
UML Interview Questions
VBA Interview Questions
Windows Interview Questions
Mainframe Interview Questions


Copyright © 2001-2020 Vyoms.com. All Rights Reserved. Home | About Us | Advertise With Vyoms.com | Jobs | Contact Us | Feedback | Link to Us | Privacy Policy | Terms & Conditions
Placement Papers | Get Your Free Website | IAS Preparation | C++ Interview Questions | C Interview Questions | Report a Bug | Romantic Shayari | CAT 2020

Fresher Jobs | Experienced Jobs | Government Jobs | Walkin Jobs | Company Profiles | Interview Questions | Placement Papers | Companies In India | Consultants In India | Colleges In India | Exams In India | Latest Results | Notifications In India | Call Centers In India | Training Institutes In India | Job Communities In India | Courses In India | Jobs by Keyskills | Jobs by Functional Areas

Testing Articles | Testing Books | Testing Certifications | Testing FAQs | Testing Downloads | Testing Interview Questions | Testing Jobs | Testing Training Institutes

Gate Articles | Gate Books | Gate Colleges | Gate Downloads | Gate Faqs | Gate Jobs | Gate News | Gate Sample Papers | Gate Training Institutes

MBA Articles | MBA Books | MBA Case Studies | MBA Business Schools | MBA Current Affairs | MBA Downloads | MBA Events | MBA Notifications | MBA FAQs | MBA Jobs
MBA Job Consultants | MBA News | MBA Results | MBA Courses | MBA Sample Papers | MBA Interview Questions | MBA Training Institutes

GRE Articles | GRE Books | GRE Colleges | GRE Downloads | GRE Events | GRE FAQs | GRE News | GRE Training Institutes | GRE Sample Papers

IAS Articles | IAS Books | IAS Current Affairs | IAS Downloads | IAS Events | IAS FAQs | IAS News | IAS Notifications | IAS UPSC Jobs | IAS Previous Question Papers
IAS Results | IAS Sample Papers | IAS Interview Questions | IAS Training Institutes | IAS Toppers Interview

SAP Articles | SAP Books | SAP Certifications | SAP Companies | SAP Study Materials | SAP Events | SAP FAQs | SAP Jobs | SAP Job Consultants
SAP Links | SAP News | SAP Sample Papers | SAP Interview Questions | SAP Training Institutes |


Copyright ©2001-2020 Vyoms.com, All Rights Reserved.
Disclaimer: VYOMS.com has taken all reasonable steps to ensure that information on this site is authentic. Applicants are advised to research bonafides of advertisers independently. VYOMS.com shall not have any responsibility in this regard.