streamsize StreamBuf::xsgetn(char *buf, streamsize nChars)
{
    size_t toRead = nChars;
    size_t nRead = 0;

    while (toRead)
    {
        size_t avail = egptr() - gptr();    // available buffer space

                                            // no or empty memory buffer
                                            // but no more readable chars
        if (avail == 0 and underflow() == EOF)
            return nRead;

        avail = min(getend, bufend) - offset;
        size_t next = min(avail, toRead);   // next #bytes to write

        memcpy(buf, gptr(), next);          // write to the buffer
        gbump(next);                        // update gptr

        buf += next;                        // update the buf location
        toRead -= next;                     // and update the counters
        nRead += next;
        offset += next;
    }

    d_last = READ;                  // now reading: also if underflow
                                    // wasn't called.
    return nRead;
}
