[haiku-development] Re: Teapot diff
- From: Michael Pfeiffer <michael.w.pfeiffer@xxxxxxxxx>
- To: haiku-development@xxxxxxxxxxxxx
- Date: Thu, 25 Oct 2007 14:30:35 +0200
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
- References:
- [haiku-development] Re: Teapot diff
- From: Stephan Assmus
- [haiku-development] Re: Teapot diff
- From: Fredrik Modéen
Other related posts:
- » [haiku-development] Teapot diff
- » [haiku-development] Re: Teapot diff
- » [haiku-development] Re: Teapot diff
- » [haiku-development] Re: Teapot diff
- » [haiku-development] Re: Teapot diff
- » [haiku-development] Re: Teapot diff
- » [haiku-development] Re: Teapot diff
- » [haiku-development] Re: Teapot diff
- » [haiku-development] Re: Teapot diff
- » [haiku-development] Re: Teapot diff
file? I'm thinking of continue the playlist save/load and settingsasve/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;
}
- [haiku-development] Re: Teapot diff
- From: Stephan Assmus
- [haiku-development] Re: Teapot diff
- From: Fredrik Modéen