Bug in SDL_RWops?!?

Hi guys, I have “little” problem with SDL_RWops.

You see, I’m trying to load config file (which is normal text file) line by line (cause it’s the way parser is working) from SDL_RWops source. That source is created using this code, borrowed from SDL_Image:

SDL_RWops *source = SDL_RWFromFile(filename.c_str(), “r”);

Since lines can be of any sizes (could be 10, 1024 or 1, no limits), I need a way to determine where are ‘\n’ located. That way, I can dynamically mallocate enough memory and fill it with all characters up to ‘\n’ - which will be passed to parser, then we deallocate that memory, move to next line and so on.

Seeking for char inside SDL_RWops is performed by this “little” function. I know it’s far from perfect, but it should be working - however, output I get from stderr shows that it isn’t, and I suspect nasty bug in SDL_RWread() or SDL_RWtell().

//----------------------------------------------------------- CODE START

#define CFG_DEBUG(x, y) fprintf(stderr, x, y);

// returns size of line to create, counting from current read-ptr position
// xxx -char we’re looking for
int SDL_RWfind( SDL_RWops * source, char xxx, int * last_line_length)
{
const int buffer_size = 512;

// we’re reading up to buffer_size characters to this buffer
char buffer [buffer_size];

// number of bytes read during last SDL_RWread()
int read;

// number of bytes that were read up to now
int read_all = 0;
char * buffer_ptr;

do
{

// -------------------------------- start of the most important part !

// get current offset (before reading)
CFG_DEBUG("\nSDL_RWfind: Current offset before RWread: %i.\n", SDL_RWtell(source));

// according to SDL Wiki, SDL_RWread: "It returns the number of memory blocks read"
// and here blocks have size of 1 - so it should return the number of characters read
read = SDL_RWread(source, buffer, 1, buffer_size ); 

CFG_DEBUG("SDL_RWfind: Read characters: %i.\n", read);

// get current offset (after reading)
CFG_DEBUG("\nSDL_RWfind: Current offset after RWread: %i.\n", SDL_RWtell(source));

// -------------------------------- end of the most important part,  next lines of this function were added just for completness sake


if (read < 0) { CFG_DEBUG("Couldn't read even one block from stream while seeking: %c.\n", xxx); return -2; }

buffer_ptr = buffer;
read_all += read;

while ( (buffer_ptr - buffer) < read )
 { 
  if ( (*buffer_ptr) == xxx) // we've found it
   {     
    SDL_RWseek(source, -read_all, SEEK_CUR);
    return ( buffer_ptr - buffer);
   }
   
 ++buffer_ptr;
}

} while ( read == buffer_size );

*last_line_length = read_all;
SDL_RWseek(source, -read_all - 1 , SEEK_CUR);
return -1;
}

//----------------------------------------------------------- CODE END

And now, most important part of this mail:

After using that function for this file:

bad_integer = 1234
good_integer = 1234

… I get in stderr this:

  1. SDL_RWfind: Current offset before RWread: 0.
  2. SDL_RWfind: Read characters: 41.
  3. SDL_RWfind: Current offset after RWread: 45.

Do you see what’s going on? We have read 41 characters (line 2) starting from offset 0 (line 1), so we should be at position 41, right? But line 3 says that we’re at position 45!!! And as you can see, there weren’t ANY reading / writing / seeking etc. going on!

The only logic I could see after this behaviour: whole file has size of 45 bytes. But that shouldn’t change anything…

I remember some time ago there was thread about bug in SDL_RWops which will be solved in next SDL version, I googled for it but coulnd’t find… was it similiar to what I’ve encountered? Or is it my code’s failure? Or I forgot about some obvious thing here?

Anyway, if someone has working function for finding char in SDL_RWops stream or sth similiar, I would be really gratefull if he would share it with me :slight_smile:

Koshmaar

I’ve found in list archieves this mail: http://www.devolution.com/pipermail/sdl/2005-May/068922.html

Quote:

“Bugs:
-Reading from memory was not consistant with how reading from files worked.
A file of 55 bytes stored into ‘ptr’ by using 6 sets of 10 bytes would copy
55 bytes into ‘ptr’ and SDL_RWread would return 5. But the same act done on
mem RWop would result in 50 bytes copied and 5 returned.”

Is this possible that’s what is causing my problems (bug described in previous mail?). Rayan C. Gordon wrote that bugfix has been already commited to CVS.

If so, when new SDL version is going out? No, I don’t want exact date - just tell if I should wait (and I won’t wait ie. half year), or should I build my own SDL version from CVS.

Or, what’s better - if there is any hack / workaround around this bug - that would be great.

Thanks!

Koshmaar

Le Sun, 7 Aug 2005 23:40:10 +0200
"Koshmaar" a ?crit:

If so, when new SDL version is going out? No, I don’t want exact date

  • just tell if I should wait (and I won’t wait ie. half year), or
    should I build my own SDL version from CVS.

Hum, yes I agree with you. SDL-1.2.8 is from december 2004, so quite a
bit now. A new release by the end of the month should be nice. I mostly
would like a new release, because I made so many fixes to the Atari SDL
part, and would like to make them official.

There are also the small fixes I made in SDL_mixer for using rwops for
midi replay.

But all this is left to Sam, so we should wait for his advices, add any
pending patches, test them, etc…–
Patrice Mandin
WWW: http://membres.lycos.fr/pmandin/
Programmeur Linux, Atari
Sp?cialit?: D?veloppement, jeux

Patrice Mandin wrote:

Hum, yes I agree with you. SDL-1.2.8 is from december 2004, so quite a
bit now. A new release by the end of the month should be nice. I mostly
would like a new release, because I made so many fixes to the Atari SDL
part, and would like to make them official.

There are also the small fixes I made in SDL_mixer for using rwops for
midi replay.

But all this is left to Sam, so we should wait for his advices, add any
pending patches, test them, etc…

Ok, thx for the info. So, theoretically it can be released even this month… =^)~~-----------

If anyone interested, it looks that there’s workaround that bug (at least, in my case).
Parser wasn’t working properly, because I was moving backwards by value returned from SDL_RWread, which was wrong. When I changed code, so that it recorded positions before and after read, and moved backwards by one char in this loop:

int i = offset_after_read;

while ( i > offset_before_read )
{
SDL_RWseek(source, -1, SEEK_CUR);
–i;
}

suddenly it started working :slight_smile:

But it’s hack, and though generally hacks are bad, this one is even worse, since it may be exceptionally performance-expensive… so I’m waiting for new SDL version :slight_smile: Good luck with you, SDL developers!

Koshmaar