TITLE: custom text stream processing (Newsgroups: comp.lang.c++.moderated, 4 Mar 1998) PARAKH: Phiroze Parakh > I would like to create an ostream class that recognizes indentation. > > basically, I want to be able to do this: > > dbg << "{ item " << data << "{ item " << data << " } }"; > and have it output: > > { item > data > { item > data } } > > Any ideas? DEROCCO: "Paul D. DeRocco" Invent your own class derived from streambuf that redefines the virtual overflow(int) and sync() functions. Design it so that it passes its output on to a previously existing streambuf. Then, to use it, create a regular streambuf (typically a filebuf), create your new streambuf feeding into it, and then create an ostream feeding into your new streambuf: filebuf fb(); fb.open(...); mystreambuf sb(&fb); ostream os(&sb); The overflow(int) function processes a single character, so you can do the necessary column counting and interpretation, and pass the results on to the target streambuf by invoking its overflow function. The sync() function (which should be called from the destructor) simply flushes any characters still sitting in your algorithm's buffers. KANZE: jkanze@otelo.ibmmail.com You need a filtering streambuf. Basically, you define a new streambuf which takes an existing streambuf as argument, and forwards the data, after filtering, to it. Your streambuf then keeps enough state to know about insertion, etc., and generates the extra blanks at the beginning of each line, along the lines of: int IndentingStreambuf::overflow( int ch ) { int result = EOF ; if ( ch == EOF ) result = sync() ; else { switch ( ch ) { case '{' : ++ myCurrentIndent ; break ; case '}' : if ( myCurrentIndent > 0 ) -- myCurrentIndent ; break ; } if ( ch == '\n' ) myIsAtStartOfLine = true ; else { if ( myIsAtStartOfLine ) { for ( int cnt = indent ; cnt > 0 ; -- cnt ) myDest->sputn( " " , 4 ) ; } myIsAtStartOfLine = false ; } result = myDest->sputc( ch ) ; } return result ; } This supposes that you've taken the appropriate measures to ensure that the output is unbuffered. (Normally, the only measure that should be necessary is to not set a buffer yourself, i.e. don't call setp.)