Mercurial > ~dholland > hg > ag > index.cgi
view doc/misc/html/oldclasslib/charsink.html @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line source
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <HTML> <HEAD> <TITLE>Character Sink Class Definitions</TITLE> </HEAD> <BODY BGCOLOR="#ffffff" BACKGROUND="tilbl6h.gif" TEXT="#000000" LINK="#0033CC" VLINK="#CC0033" ALINK="#CC0099"> <P> <IMG ALIGN="right" SRC="../images/agrsl6c.gif" ALT="AnaGram" WIDTH=124 HEIGHT=30 > <BR CLEAR="all"> Back to : <A HREF="../index.html">Index</A> | <A HREF="index.html">Class libraries for examples</A> <P> <IMG ALIGN="bottom" SRC="../images/rbline6j.gif" ALT="----------------------" WIDTH=1010 HEIGHT=2 > <P> <H1>Character Sink Class Definitions</H1> <IMG ALIGN="bottom" SRC="../images/rbline6j.gif" ALT="----------------------" WIDTH=1010 HEIGHT=2 > <P> <BR> <H2>Introduction</H2> A character_sink is an abstract class, from which are derived two useful classes, an output_file class and a string_accumulator class. The basic idea of a character sink is that it can be used as the generic output device for a process that generates characters. Other character_sink classes can easily be imagined, in particular, parsers that take character input. <P> Because character_sink is an abstract class, you cannot declare a character_sink. You may however declare a pointer to a character sink: <PRE> character_sink *sink; </PRE> Character sinks overload the "<<" operator for int, (char *) and (unsigned char *) operands and return a reference to the sink so that multiple operations are possible. For example: <PRE> *sink << 'c' << "xyz"; </PRE> The important aspect of a character sink is that a stream of characters can be easily switched from one destination to another. <P> <BR> <H2> The output_file Class </H2> The output_file class is derived from the character sink class. There are two initializers: one with no arguments, which simply sends characters on to stdout; and one which takes a file name as an argument. If the file can be opened, characters are sent to the file, otherwise, they go to stdout. For example: <PRE> output_file out; //sinks characters to stdout output_file out("foo.bar"); //sinks characters to foo.bar output_file out(NULL); //sinks characters to stdout out << "Hello, world" << '!'; character_sink *sink = &out; // sink points to an output_file </PRE> Note, that unlike normal C++ stream I/O, there is no binary to ascii conversion involved. <P> <BR> <H2> The string_accumulator Class </H2> The string_accumulator is derived from the character sink class, so you may use it as a destination for any character stream. Rather than pass characters on, however, a string_accumulator saves them up for later use. A string_accumulator works like a push down stack. Each level of the stack consists of a string. When you add characters to a string_accumulator they are appended to the topmost string on the stack. Operators are provided for the following functions: <UL> <LI> increment the stack level, thus starting a new string </LI> <LI> decrement the stack level, thus discarding the top string </LI> <LI> append a character or string to the top string </LI> <LI> remove the last character from the top string on the stack </LI> <LI> inspect or change characters on the stack. </LI> <LI> obtain a pointer to the top string on the stack </LI> <LI> concatenate the top strings on the stack </LI> <LI> obtain a permanent copy of the top string on the stack </LI> <LI> find the length of a string </LI> <LI> reset the string accumulator </LI> </UL> <P> <BR> <H2> Declaring a string_accumulator </H2> To declare a string_accumulator, you must specify the amount of storage to be reserved for string storage. If you wish you may also specify the maximum number of levels. If you do not specify the number of levels you will get just one level. For example: <PRE> string_accumulator sa(1000, 20); string_accumulator lsa(100); </PRE> provides for 1000 characters and 20 levels in sa but just 100 characters in a single level in lsa. <P> <BR> <H2> Changing Levels </H2> The "++" operator has been overloaded to increment the stack level. You may pre-increment the level to begin accumulating a nested string of characters. For example: <PRE> ++sa; </PRE> To discard the top string on the stack, use the pre-decrement operator "--": <PRE> --sa; </PRE> The pre-increment and pre-decrement operators return a reference to the string_accumulator so that you may combine operations in a single expression: <PRE> ++sa << "Hello, world!"; </PRE> If you store characters on a stack without incrementing the level, they are appended to the string at the current level. In particular, if you declare a string_accumulator with only a single level, you need never increment or decrement it. You may, however, wish to use the reset operator. <P> Post-increment and post-decrement operators are also defined for convenience in use. Instead of returning a reference to the string_accumulator, however, they simply return a copy of the control structure (in its pre-decrement or pre-increment state) which allows read-only access to the content of the string_accumulator. This can nevertheless be quite useful: <PRE> char *top_string = copy(sa--); </PRE> <P> <BR> <H2> Appending Characters to a String </H2> To append characters you may use the overloaded "<<" operator, which also returns a reference to the string accumulator so you may combine operations: <PRE> sa << "Hello, world" << '!'; </PRE> To start a new string and append characters use the pre-increment operator as well: <PRE> ++sa << "Hello, world" << '!'; </PRE> <P> <BR> <H2> Removing Characters from a String </H2> To pop off the last character on the top string: <PFRE> int c; sa << c; </PRE> <P> <BR> <H2> Accessing the Content of a String </H2> To inspect or change the k'th character from the top of the stack: <PRE> int c = sa[k]; sa[k] = '!'; </PRE> If k is zero you get the last character on topmost string in the string_accumulator. <P> To get a pointer to the top string on the stack, use the (char *) cast operator: <PRE> char *p; p = (char *) sa; </PRE> <BR> <H2> Concatenating Strings </H2> To concatenate the top two strings on the stack, use concat(): <PRE> concat(sa); </PRE> <BR> <H2> Making a Permanent Copy of a String </H2> To make a copy of the top string on the stack, use copy(): <PRE> char *p = copy(sa); </PRE> Note that copy differs greatly from (char *), in that copy allocates storage for a new copy of the string. When you are done with it you should delete it: <PRE> delete [] p; </PRE> Note that copy() does not remove the string from the stack. Use "--" to discard the string from the stack. <P> <BR> <H2> Finding the Length of a String </H2> To find the length of the top string on the stack, use size(): <PRE> unsigned n = size(sa); </PRE> Like strlen, size does not count the terminating null character. <P> <BR> <H2> Resetting a string_accumulator </H2> The overloaded function reset() may be applied to a string_accumulator to reset it to its initial state: <PRE> reset(sa); </PRE> reset returns a reference to the string accumulator so that you may reset it and append text in a single statement: <PRE> reset(sa) << "Hello, world!"; </PRE> <P> <BR> <IMG ALIGN="bottom" SRC="../images/rbline6j.gif" ALT="----------------------" WIDTH=1010 HEIGHT=2 > <P> <IMG ALIGN="right" SRC="../images/pslrb6d.gif" ALT="Parsifal Software" WIDTH=181 HEIGHT=25> <BR CLEAR="right"> <P> Back to : <A HREF="../index.html">Index</A> | <A HREF="index.html">Class libraries for examples</A> <P> <ADDRESS><FONT SIZE="-1"> AnaGram parser generator - examples<BR> Class libraries - Character sink class definitions<BR> Copyright © 1993-1999, Parsifal Software. <BR> All Rights Reserved.<BR> </FONT></ADDRESS> </BODY> </HTML>