[haiku-development] Re: Teapot diff

By the way does BeOS/Haiku API have any way of reading line by line from a
file? I'm thinking of continue the playlist save/load and settings
asve/Load. This mailing list gave me something like this along time ago to my other project. Would this do? (after changing it to follow our guide
lines)

bool FileHandeler::getline(BFile *file, BString& string, bool useConvertUTF8)
{
        BString temp;
        static char buffer[4096];
        static off_t positionInBuffer;
        static ssize_t amt_read;
        string = "";  // Clear out old string
        // Fill up the buffer with the first chunk of code
        if (positionInBuffer == 0)
                amt_read = file->Read(&buffer, sizeof(buffer));
        while(amt_read > 0)
        {
                while(positionInBuffer < amt_read)
                {
                        // Return true if we hit a newline or the end of the 
file
                        if (buffer[positionInBuffer] == '\n')
                        {
                                positionInBuffer++;
                                //Convert begin
                                int32 state = 0;
                                int32 bufferLen = string.Length();
                                int32 destBufferLen = bufferLen;
                                char destination[destBufferLen];
                                if(useConvertUTF8)
                                        
convert_to_utf8(B_MS_WINDOWS_1252_CONVERSION, string.String(),
&bufferLen, destination, &destBufferLen, &state);
                                string = destination;
                                //Convert ends
                                return true;
                        }
                        string += buffer[positionInBuffer];
                        positionInBuffer++;
                }

                // Once the buffer runs out, grab some more and start again
                amt_read = file->Read(&buffer, sizeof(buffer));
                positionInBuffer = 0;
        }
        return false;
}

There are at least two problems:
The destination buffer for convert_to_utf8 might be too small, and the
source string will then be truncated.
For example an umlaut (single byte) is converted to multiple bytes in UTF-8.
To fix that, you have to place convert_to_utf8 into a loop an increase
the destination buffer as needed. This method writes the read and write bytes
into the int32 variables, so you know where to continue.

The method is not thread safe too, because it uses static variables.
You could move them into a class like this:

class LineReader {
public:
  LineReader(BFile *file, uint32 sourceEncoding);
  bool Next(BString& string);

private:
  BFile*  fFile;
  uint32  fSourceEncoding;

  char    fBuffer[4096];
  off_t   fPositionInBuffer;
  ssize_t fAmtRead;
};

Implementation of the constructor and the method are trivial ;-) and left as an exercise.

Regards,
Michael


Other related posts: