This is mostly for Rick, posted here for other's that may be interested.

I worked my way through the new stream library about as far as I can go.  I
have a list of the things I found for when you get back to it.

Hopefully, each one will save you a few minutes of investigation.  <grin>

Many of the places I wasn't really sure of the proper fix, I just fixed it
enough to continue.

I was using the m_oodcls.rex, trying to get it complete.  The list is sort
of in the order I found them.

SysFile::flush()  There is the comment about invalidating the buffer, but no
code.

            // update the real output position
            filePointer += written;
            // and invalidate the buffer
I added:
            bufferPosition = 0;
            bufferedInput = 0;

SysFile::getStreamTypeInfo  there is this test:

        if ((fileInfo.st_mode & _S_IFREG) != 0)
        {
            device = true;
            transient = true;
        }
which marks persistent streams as transient.  I think you meant it to be
this test:

        if ((fileInfo.st_mode & _S_IFCHR) != 0)
        {
            device = true;
            transient = true;
        }
Well, now I forget the order.

StreamInfo::checkEof()   There is this code:

      // if this is an eof condition, raise that not ready
    if (fileInfo.atEof())
    {
        eof();
    }
    else
    {
        // must be an error, so raise that using the file error information
        notreadyError();
    }
which always generates an error and causes setPosition() to always fail.  I
took out the else.

StreamInfo::setPosition()  The position value is decremented, than also has
1 subtracted from it in the call to seek().

    position--;      // convert to system position type
    // seek to the target position, if possible.  The request position
    // is a 1-based character number.  We need to convert this into
    // a zero-based one before moving.
    if (fileInfo.seek(position - 1, SEEK_SET, newPosition))
    {
        checkEof();
    }
I just took out the position--; line

With the rest, I'm even less sure what a good fix is.

bool SysFile::getChar()

In several places in with loops using getChar(), the check is done for a
return of false to fall out of the loop.  But getChar() returns true when it
hits end of file.

 bool SysFile::getChar(char &ch)
 {
    size_t len;

    return read(&ch, 1, len);
 }
read() returns true at eof, and looks like it is intended to return true for
that condition.  So, I changed getChar() to only return true if it actually
got a new char:

 bool SysFile::getChar(char &ch)
 {
    size_t len = 0;

    return (read(&ch, 1, len) && len == 1);
 }

Then there is a basic problem with ~linein() in that the position variables
don't get updated so that linein() in a loop returns the first line over and
over.  This one I really kind of hacked.  Since the code path I was
producing was going through StreamInfo::readVariableLine(), I did the
position update there.

        // If we have a new line character in the last position, we have
        // a line.  The gets() function has translated crlf sequences into
        // single lf characters.
        if (buffer[bytesRead - 1] == '\n')
        {
            charReadPosition += currentLength + bytesRead + (collapsed ? 1 :
0);
            lineReadPosition++;
            lineReadCharPosition = charReadPosition;
            last_op_was_read = true;
            return context->NewString(buffer, currentLength + bytesRead -
1);
        }

However, since gets() may have collapsed a /r/n into a single byte, I added
in an extra arg that would report if /r/n was collapsed into /n.

fileInfo.gets(readPosition, bufferSize - currentLength, bytesRead,
collapsed)

Not pretty, but it worked.  I really wasn't sure what you intended to do
with reads.

The last thing is eof checking when using buffered reads.  With a file where
the last bytes only partially fills the buffer, the file is at eof, but
there are still bytes in the buffer that need to be processed.

        // hit end of file reading this?  This will be the entire line then
        if (fileInfo.atEof())
        {
            ...
        }

The last read may have read 300 bytes into the buffer.  _eof() will return
true, so atEof() returns true.  But this line is not really the last line.
I hacked this into:

        // hit end of file reading this?  This will be the entire line then
        if (fileInfo.atEof() && !fileInfo.hasBufferedInput())
        {
            charReadPosition += currentLength + bytesRead + 1;
            lineReadPosition++;
            lineReadCharPosition = charReadPosition;
            last_op_was_read = true;
            return context->NewString(bufferAddress, currentLength +
bytesRead);
        }

where I added to SysFile

    inline bool hasBufferedInput() { return bufferedInput > bufferPosition;
}

As I said, I didn't mean these to be the correct fixes, just to point out
the areas that need something.

All of the above got m_oodcls.rex working enough to read and write out
several of the input files.  But then I get a crash where:

    size_t bufferSize;
    char  *buffer = getDefaultBuffer(bufferSize);

getDefaultBuffer() returns a pointer with the value of: 0x20200a0d

So it looks like the bufferAddress member of StreamInfo has gotten
overwritten.  I still get baffled trying to figure those out, so that's
where I quit.

--
Mark Miesfeld
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to