/*Orion Lawlor's Simple STL Examples, olawlor@acm.org
Shows how to implement a simple std::streambuf for input.
The other way to do this is use the "stupid-named pointers"
method, described in truly excruciating detail here: 
	http://www.mr-edd.co.uk/?p=16
*/
#include <iostream>
#include <string>

class myistreambuf : public std::streambuf {
	const char *string, *end;
public:
	myistreambuf(const char *src) :string(src), end(string+strlen(string)) {
		setp(0,0); setg(0,0,0); /* no buffers */
	}
	
	// Peek at the next character from the stream, but don't consume it.
	//  Returns eof if no character is available.
	std::streambuf::int_type underflow(void) {
		if (string==end) return EOF;
		//std::cout<<"Called underflow\n";
		return *string;
	}
	// Read *and consume* one character from the stream.
	//  Returns eof if no character is available.
	std::streambuf::int_type uflow(void) {
		if (string==end) return EOF;
		//std::cout<<"Called uflow\n";
		return *string++;
	}
};

int main()
{
	myistreambuf buf("1234 something else");
	std::istream f(&buf);
	
	int x;
	f>>x;
	std::cout<<"Integer: "<<x<<"\n";
	
	std::string s;
	f>>s;
	std::cout<<"String: "<<s<<"\n";
	
	char c;
	f>>c;
	std::cout<<"streamed character: '"<<c<<"'\n";
	
	f.read(&c,1);
	std::cout<<"read character: '"<<c<<"'\n";
	
	return 0;
}
/*<@>
<@> ******** Program output: ********
<@> Integer: 1234
<@> String: something
<@> streamed character: 'e'
<@> read character: 'l'
<@> */
