Click here to Skip to main content
15,908,673 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This has been vexing me all morning.

I have a stream class that keeps a buffer and wraps other streams. (I'd use the STL but I can't for reasons)

The idea is that it wraps an underlying stream and reads from that stream in large chunks which is faster than reading a lot of little chunks. It then keeps a chunk in memory, and pulls from that when the user calls read()

The trouble is, it's corrupting my underlying stream's data somehow. I think I've narrowed it to the read method, as all methods are trivial, with the exception of seek() which clears the buffer.

Anyway I've been staring at this code till I'm cross eyed and I just can't spot where I've got it wrong.

read() takes a buffer and a size, and reads that many bytes from the stream unless the end happens in which case it may read less. In any case, it returns the number of bytes read.

m_buffer_index holds the current offset within the buffer where the next read takes place.

m_buffer_capacity holds the total amount of bytes allocated to the buffer. This may be greater than the actual amount of data in the buffer in the case where the end of the stream was reached.

m_buffer_size indicates the actual count of bytes from the stream that are contained in the buffer. In the case where the end of the stream was reached, this may be less than m_buffer_capacity

Further questions I can cover in the comments

What I have tried:

C++
virtual size_t read(uint8_t* destination,size_t size) {
    if(!initialize()) {
        return 0;
    }
    if(!m_buffer_size || m_buffer_index>=m_buffer_capacity) {
        m_buffer_size = m_stream.read(m_buffer,m_buffer_capacity);
        m_buffer_index = 0;
    }
    int sz = m_buffer_size-m_buffer_index<size?m_buffer_size-m_buffer_index:size;
    if(sz>0) {
        memcpy(destination,m_buffer+m_buffer_index,sz);
        m_buffer_index+=sz;
        if(sz!=size) {
            sz+=read(destination+sz,size-sz);
            
        }
    }
    return sz;
}
Posted
Comments
Greg Utas 31-Jul-22 11:41am    
Is m_stream the underlying stream? If that's what's getting corrupted, the only place this code affects it is in its read call. It looks recursive but I'm guessing it has a different implementation because read is a virtual function.

And is your space bar broken or something?! :)
honey the codewitch 31-Jul-22 12:32pm    
It actually is recursive, but it recurses only in the case where the requested amount is greater than the buffer capacity. m_stream is the underlying stream.
Greg Utas 31-Jul-22 13:16pm    
That function call looks like the only place that affects the underlying buffer, so maybe the problem is in its implementation.
honey the codewitch 31-Jul-22 16:01pm    
The buffer logic implementation is almost all in read(). That's what gets me. That's what does all of the heavy lifting, and as far as the underlying stream, I've tested it. It works flawlessly when I feed it directly to the downstream consumer (a jpg loader) but when I add the buffered stream it croaks. Interestingly, it works for loading TrueType font streams, ***but.. TrueType font streams seek all the time, which resets/clears the buffer, so it's effectively not using the buffer. Just some background.
FreedMalloc 31-Jul-22 11:59am    
Look at this line (Apparently less than symbols are not allowed in comments LT substituted):
int sz = m_buffer_size-m_buffer_index LT size?m_buffer_size-m_buffer_index:size;
C++ operator precedence says it's equivalent to:
int sz = ((m_buffer_size-m_buffer_index) LT size)?m_buffer_size-m_buffer_index:size;
But, is it for your compiler? I've seen some odd behavior when dealing with conditionals in the past.

I suspect this isn't the issue since operator precedence is fairly well understood. But, it was the only line I saw with enough complexity that might explain it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900