Personal tools
You are here: Home Projects C++ Cfront releases Release 3.0.3 source libSC Strstream Strstream.c
Document Actions

Strstream.c

by Michael L Powell last modified 2007-01-26 03:24

Click here to get the file

Size 6.2 kB - File type text/plain

File contents

/*ident	"@(#)Strstream:Strstream.c	3.1" */
/******************************************************************************
*
* C++ Standard Components, Release 3.0.
*
* Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc.
* Copyright (c) 1988, 1989, 1990 AT&T.  All Rights Reserved.
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System
* Laboratories, Inc.  The copyright notice above does not evidence
* any actual or intended publication of such source code.
*
******************************************************************************/

#include <iostream.h>
#include <Strstream.h>

static char sccs_id[] = "@(#)Strstream version, 082096";
#ifdef __GNUG__
#define zapeof(x) ((x)&0377)
#endif

/*
 * There are three basic kinds of Strstreambuf objects:
 *
 *   - created with the default constructor (this kind uses
 *     the "String s" private data member in Strstreambuf as
 *     the internal buffer)
 *   - created with the Strstreambuf(String&) constructor
 *     (this kind of Strstreambuf permits both reading and
 *     writing -- reading the Strstreambuf causes characters
 *     to be deleted from the beginning of the String, writing
 *     to the Strstreambuf causes characters to be added to
 *     the end of the String)
 *   - created with the Strstreambuf(const String&) constructor
 *     (this kind of Strstreambuf is "read-only" -- all writing
 *     operations will fail and reading operations don't change
 *     the value in the String [they just update the
 *     chars_consumed private data member])
 */
Strstreambuf::Strstreambuf()
{
	p = &s ;
#ifndef L5_COMPATIBLE
	chars_consumed = 0;
	output_flag = 1;
#endif
	setb(array, array+sizeof(array)) ;
	setp(0,0) ;
	setg(0,0,0) ;
}

Strstreambuf::Strstreambuf(String& ss) : p(&ss)
{
#ifndef L5_COMPATIBLE
	chars_consumed = 0;
	output_flag = 1;
#endif
	setb(array, array+sizeof(array)) ;
	setp(0,0) ;
	setg(0,0,0) ;
}

#ifndef L5_COMPATIBLE
Strstreambuf::Strstreambuf(const String& ss) : p((String *)&ss)
{
	chars_consumed = 0;
	output_flag = 0;
	setb(array, array+sizeof(array)) ;
	setp(0,0) ;
	setg(0,0,0) ;
}
#endif

Strstreambuf::~Strstreambuf() { }

/*
 *  The Strstreambuf class will append characters to
 *  the end of the String in batches rather than one
 *  at a time.  The size of the batch is usually the
 *  length of Strstreambuf::array.
 */
int Strstreambuf::overflow(int c)
{
#ifndef L5_COMPATIBLE
	if (output_flag == 0) return EOF;
#endif

	if ( gptr() ) sync() ;
	
	if ( pbase() < pptr()) {
		*p += String(pbase(),pptr()-pbase()) ;
	}
	if ( c != EOF ) *p += (char)c ;
	setp(base(),ebuf()) ;
	return zapeof(c) ;
}

/*
 *  If the current supply of input characters has been
 *  exhausted, the underflow() function will copy the
 *  next len characters from the String into the array.
 */
int Strstreambuf::underflow()
{
#ifndef L5_COMPATIBLE
	if (in_avail() > 0) {
		return ((int) *gptr());
	}
#endif
	if ( pptr() ) sync() ;
#ifndef L5_COMPATIBLE
	int len = p->length() - chars_consumed;
#else
	int len = p->length() ;
#endif

	if ( len <= 0 ) {
		setg(0,0,0) ;
		return EOF ;
	}

	if ( len > blen() ) len = blen() ;
	
	/* len is now set to the minimum of the length
	   of the remaining part of the String and the
	   size of the holding area. */
	
	if ( unbuffered() ) {
		setg(array,array,array+1) ;
		len = 1;
	}
	else {
		setg(base(),base(),base()+len) ;
	}

	register char* pc = gptr() ;
	register const char *lclptr = (const char *) *p;
#ifndef L5_COMPATIBLE
	memcpy(pc, lclptr + chars_consumed, len);
	chars_consumed += len;
#else
	memcpy(pc, lclptr, len);
#endif
	
#ifdef L5_COMPATIBLE
	*p = p->chunk(len); // delete the first "len" characters from
			    // the Strstreambuf
#endif
	return zapeof(*gptr()) ;
}

int Strstreambuf::pbackfail(int c) 
{
#ifndef L5_COMPATIBLE
	if (chars_consumed > 0) chars_consumed--;
#else
	p->unget(c) ;
#endif
	return zapeof(c) ;
}

int Strstreambuf::sync() 
{
	if ( pptr() > pbase() ) overflow(EOF) ;

	setp(0,0) ;
	if ( gptr() < egptr() ) {
#ifndef L5_COMPATIBLE
		chars_consumed -= (egptr()-gptr());
#else
		*p = String(gptr(),egptr()-gptr()) + *p ;
#endif
	}
	setg(0,0,0) ;
#ifndef L5_COMPATIBLE
	if (output_flag == 1 && chars_consumed > 0) {
		/* if this is the buffer for a Strstream that permits
		   reading and writing, then we need to delete the
		   characters that have been read already */
		*p = p->chunk(chars_consumed);
		chars_consumed = 0;
	}
#endif

	return 0 ;
}

streambuf* Strstreambuf::setbuf(char* _p, int len)
{
	if ( _p == 0  || len <= 0 ) unbuffered(1) ;
	else {
		unbuffered(0) ;
		setb(_p,_p+len) ;
	}
	return this ;
}
		
#ifndef L5_COMPATIBLE
streampos Strstreambuf::seekoff(streamoff off_val, ios::seek_dir sdir, int rw) {
	streampos retval = EOF;
	if (output_flag == 0 && rw == ios::in) {
		int newval;
		if (sdir == ios::cur) {
			newval = chars_consumed - (egptr() - gptr()) + off_val;
		}
		else if (sdir == ios::beg) {
			newval = off_val;
		}
		else if (sdir == ios::end) {
			newval = p->length() - 1 + off_val;
		}
		if (newval >= 0 && newval < p->length()) {
			chars_consumed = newval;
			retval = newval;
			setg(0,0,0);
		}
	}
	return retval;
}
streampos Strstreambuf::seekpos(streampos a, int mode) {
	return seekoff(a, ios::beg, mode);
}
int Strstreambuf::xsgetn(char *buf, int n) {
	int n1 = n;
	while (n1 > 0) {
		*buf++ = sbumpc();
		n1--;
	}
	return (n);
}
int Strstreambuf::doallocate() {
	setb(array, array+sizeof(array));
	setp(0,0);
	setg(0,0,0);
	return 0;
}
#endif

String Strstreambuf::str()
{
	sync() ;
	return *p ;
}

Strstreambase::Strstreambase()  { init(&b) ; }

Strstreambase::Strstreambase(String& s) : b(s) { init(&b) ; }
#ifndef L5_COMPATIBLE
Strstreambase::Strstreambase(const String& s) : b(s) { init(&b) ; }
#endif

Strstreambase::~Strstreambase() { }

Strstreambuf* Strstreambase::rdbuf() { return &b ; }

#ifndef L5_COMPATIBLE
iStrstream::iStrstream(const String& s) : Strstreambase(s) { }
#else
iStrstream::iStrstream(String& s) : Strstreambase(s) { }
#endif
iStrstream::~iStrstream() { }

oStrstream::oStrstream(String& s) : Strstreambase(s) { }
oStrstream::oStrstream() { }
oStrstream::~oStrstream() { }
String oStrstream::str() { return rdbuf()->str() ; }

Strstream::Strstream(String& s) : Strstreambase(s) { }
Strstream::Strstream() { }
Strstream::~Strstream() { }
String Strstream::str() { return rdbuf()->str() ; }
« April 2024 »
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: