[haiku-development] Re: Problem with BMessage and SettingsMessage

  • From: Niels Sascha Reedijk <niels.reedijk@xxxxxxxxx>
  • To: Haiku Development <haiku-development@xxxxxxxxxxxxx>
  • Date: Fri, 16 Apr 2021 10:39:55 +0100

Hi,

On Fri, Apr 16, 2021 at 10:10 AM <fredrik@xxxxxxxxx> wrote:


HI
I have a problem (making new methods to SettingsMessage). I was thinking of 
change how Bluetooth pref store it's settings, but in small steps.
First step are to convert the stored settingsfile to BMessage.
struct {
    bdaddr_t PickedDevice;
    DeviceClass LocalDeviceClass;
    int32 Policy;
   int32 InquiryTime;
} Data;

int are not hard. when It comes to DeviceClass I was considering to store the 
3 ints that it contains of and just make a DeviceClass when I read the 
settings from file.

My biggest problem are how to store this bdaddr_t. Here I was consider 
FindData/AddData, If that the case, then I need to extend SettingsMessage 
with GetValue/SetValue for Data and there are my problem. Or should BMessage 
should be extended to hadle a bdaddr_t?

I see that bdaddr_t is defined as:
typedef struct {
    uint8 b[6];
} __attribute__((packed)) bdaddr_t;

In this case I would do it as follows. I would define a unique type
code for the bdaddr_t type, like:
const type_code kBluetoothDeviceAddress = 'BDAd';

You then use BMessage::AddData()/FindData()/ReplaceData() to add the
data, with this exact type. By definition, the bdaddr_t type is going
to be of a fixed size, and the size will always be 6 bytes.

This are what I came up with.. it's now how it should be. I don't even know 
how this would be in C# (if it is/was possible). And that are what I use 
ewery day..

status_t
SettingsMessage::SetValue(const char* name, type_code type, const void* data,
ssize_t numBytes)

Could work.

const void*
SettingsMessage::GetValue(const char* name, type_code type, ssize_t numBytes, 
const void& defaultValue)

This will not work, because what address are you going to return in
case of success? The idea of BMessage::FindData() is that you write
the outcome to a void* buffer, not create a new buffer.

Arguably you could add a method with the following prototype:
status_t
SettingsMessage::GetValue(const char* name, type_code type, void
*buffer, ssize_t numBytes)

The instruction to the user would then be that the input buffer should
contain a valid default value. This one will not be overwritten if
there is no value in the settings file/memory.

Below I have changed the lines that I think would/should change:

This are how it suppose to be used.
void
BluetoothSettings::LoadSettings(Data& settings) const
{
// This are how the default was set before.
// Data.PickedDevice = bdaddrUtils::NullAddress();
// Data.LocalDeviceClass = DeviceClass();
// Data.Policy = 0;
// Data.InquiryTime = 15;

//Last parameter are the default value.
   settings.PickedDevice = fSettingsMessage.GetValue(kPickedDevice,  
B_ANY_TYPE, bdaddrUtils::NullAddress());
 settings.PickedDevice = fSettingsMessage.GetValue(kPickedDevice,
kBluetoothDeviceAddress, &Data.PickedDevice, sizeof(bdaddr_t));
   settings.Policy = fSettingsMessage.GetValue(kPolicy, 0);
   settings.InquiryTime = fSettingsMessage.GetValue(kInquiryTime, 15);
}

void
BluetoothSettings::SaveSettings(const Data& settings)
{
   fSettingsMessage.SetValue("bdaddr", B_ANY_TYPE, settings.bdaddr, 
sizeof(bdaddr_t));
fSettingsMessage.SetValue("bdaddr", kBluetoothDeviceAddress,
&settings.bdaddr, sizeof(bdaddr_t));
   fSettingsMessage.SetValue(kPolicy, settings.Policy);
   fSettingsMessage.SetValue(kInquiryTime, settings.InquiryTime);

   fSettingsMessage.Save();
}

Having said that, I find it difficult to understand what the value of
the GetValue() overloaded methods is, when there are BMessage::Get*()
methods that are also available.

Regards,

N>

Other related posts: