Opened 13 years ago

Last modified 13 years ago

#7701 closed bug

BMessage::FindString() behaves differently from BeOS's when field does not exist — at Version 3

Reported by: ttcoder Owned by: axeld
Priority: normal Milestone: R1
Component: Kits/Application Kit Version: R1/Development
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description (last modified by axeld)

m.FindString("myfield", &s) will leave 's' untouched if "myfield" is not part of 'm'. Expected behavior: in addition to returning an error code, it should also reset the string, much like m.FindInt32( "myfield", &i ) reset i to zero.

Looking at the BeBook I see it does not lean much one way or the other, so I'm tentatively categorizing this as a 'bug' only insofar as it differs from the BeOS behavior I've relied on in the past: the behavior under Haiku breaks my app (though the workaround is straight-forward). Under BeOS I could do this:

int main()
{
    BMessage m;
    m.AddString( "one", "value" );

    BString s;

    m.FindString( "one", &s );
    puts( s.String() );
    m.FindString( "two", &s );
    puts( s.String() );
}

and correctly get a blank output at the second puts() due to the absent field.

In case this sticks, here's a possible one-liner 'patch': in Message.cpp line 2635:

           const char *cstr = NULL;
	    status_t error = FindString(name, index, &cstr);
	    if (error < B_OK)
	    {
	        string->Truncate(0);  // <-- here it is, a reset that's fairly fast (Truncate() in "lazy" mode)
	        return error;
	    }
	

Change History (3)

comment:1 by anevilyak, 13 years ago

You do realize FindString returns an error code if the field couldn't be found, yes?

if (m.FindString("one", &s) == B_OK) 
  puts(s.String());

Will work fine and does not depend on side effects that aren't guaranteed or documented.

in reply to:  1 comment:2 by ttcoder, 13 years ago

Replying to anevilyak:

and does not depend on side effects that aren't guaranteed or documented.

Ok roger that, I can live with Haiku's FindString() remaining as it is. The BeOS implementation makes more sense to me (consistency of behavior between FindInt32() and FindString(), and above all, allowing client code to be more simple and elegant) but not too many devs rely on this 'feature' of BMessage like I do, I suppose.

comment:3 by axeld, 13 years ago

Description: modified (diff)

Even though the BeOS semantics of BMessage::Find*() are really braindead, it's still a compatibility issue that deserves to be fixed.

Note: See TracTickets for help on using tickets.