template<>
class rangebuf<char*> : public std::streambuf {
public:
rangebuf(const char* f, const char* l);
protected:
pos_type seekoff(off_type off, std::ios::seekdir way,
std::ios::openmode which);
pos_type seekpos(pos_type pos, std::ios::openmode which);
};
rangebuf<char*>::rangebuf(const char* f, const char* l) {
setg(const_cast<char*>(f),
const_cast<char*>(f),
const_cast<char*>(l));
}
std::streambuf::pos_type
rangebuf<char*>::seekoff(off_type off, std::ios::seekdir way,
std::ios::openmode which) {
switch(way) {
case std::ios::beg:
return seekpos(pos_type(off), which);
case std::ios::cur:
return seekpos(pos_type(off) + (gptr() - eback()), which);
case std::ios::end:
return seekpos(pos_type(off) + (egptr() - eback()), which);
default:
return pos_type(off_type(-1));
}
}
std::streambuf::pos_type
rangebuf<char*>::seekpos(pos_type pos, std::ios::openmode which) {
if (which != std::ios::in)
return pos_type(off_type(-1));
off_type offset = off_type(pos);
if (offset < 0 || offset > egptr() - eback())
return pos_type(off_type(-1));
setg(eback(), eback() + offset, egptr());
return pos;
}