Overview

The RoseInputStream utility class generalizes data sources for the file format parsing code in the ROSE library. It does block reads, maintains a data buffer and calls the virtual refill() function to get more data when full. A loop around get() processes data a character at a time, returning EOF when no more data is available. Characters can be pushed back onto the stream with unget(), and you can configure how many characters of pushback to support.

The RoseInputFile subclass wraps FILE* and is most common, but other subtypes exist to read from a memory string, a Gzip compressed source, or a member of a Zip archive.

Typical use is to create one of the specific subtypes and then pass around a reference cast as this supertype. Strings are written with the put() function. A put_sprintf() function is also available, which allocates an intermediate buffer, does sprintf(), and then put().

RoseInputStream * stream,
int c;

while ((c=stream->get()) != EOF)
{
    // do something with each char
}

as_file()

virtual FILE * as_file();

The as_file() function is a convenience function for transitioning legacy code that can only work on a FILE*. By default this returns null, but will return the underlying file pointer if the stream is a RoseInputFile.

buffer()

unsigned char * buffer()

The buffer() function returns the start of the I/O memory buffer used to hold a block of character data for reading plus extra space for pushback characters. The io_size() plus pushback_size() give the size of the buffer.

RoseInputStream * s;

// first and last chars in a block read
unsigned char first_char = s->buffer()[s->curpos()];
unsigned char last_char =  s->buffer()[s->endpos()];

// note that this could change every refill
size_t num_chars = s->endpos() - s->curpos(); 

curpos()

size_t curpos();
void curpos (size_t v);

The curpos() function returns or sets the offset within the I/O memory buffer of the next character to read. Note that the buffer has space for pushback characters so this value is not zero when the buffer has just been refilled. Instead it starts at pushback_size() characters in.

endpos()

size_t endpos();

The endpos() function returns the offset of the last character in the I/O memory buffer. Depending on the underlying stream source, the refill() function might not fill the entire block when called.

get()

int get()

The get() function returns a one character and advances the curpos(), refilling the buffer if needed. The function returns EOF when no more data is available. Use ungetc() to push a character back to the stream.

If you prefer to access an entire block of data at once, you can use buffer() from curpos() to endpos() and then manually call refill() when done.

RoseInputStream * f;
int c;

/* consume characters from a stream until  
 * see a c-style close comment
 */
for (c=f->get(); c != EOF; c=f->get()) 
{
    if (c == '*') {
	/* Lookahead for the closing slash. */
	int c2 = f->get();
	if (c2 == EOF) break;
	if (c2 == '/') {
	    /* got star slash */
	}
	else {
	    /* pushback and continue */
	    f->unget(c2);
	}
    }
}

io_size()

size_t io_size();
void io_size(size_t sz);

The io_size() function gets and set the target size for filling the I/O memory buffer. The actual allocation size of the buffer includes space for pushbacks so it will be larger.

Changing the size of the buffer in the middle of reading will lose any data not yet processed.

name()

void name (const char * s);
const char * name();

The name() function gets and sets a description for the stream. This could be filename or any other appropriate value.

pushback_size()

size_t pushback_size();
void pushback_size(size_t p);

The pushback_size() function gets and set the maximum number of pushback characters that the stream will support. The default is one character.

Changing the size of the buffer in the middle of reading will lose any data not yet processed.

refill()

virtual size_t refill();

The refill() function reads new data from the stream and copies them into the I/O memory buffer. It returns the number of characters read.

This is called automatically by get() when it reaches the end of the buffer. This is a virtual function that is overridden by each stream subtype.

unget()

int unget (int c);

The unget() function pushes back a character to the stream so that it will be returned by the next call to get()

The function returns EOF on failure as per stdio unget. On success, it returns the character pushed back.