DriverSettingsMessageAdapter: added "wildcard" support.

* You can now add arbitrarily named fields to the message as well,
  without having them all specified in the template.
* Also added a missing converter method that is called when there
  are no values to add, and implemented all methods in the base
  class, so that you only have to implement the methods you actually
  need.
This commit is contained in:
Axel Dörfler
2015-07-22 20:42:22 +02:00
parent e51a20af4f
commit c4b6278c02
4 changed files with 170 additions and 17 deletions
@@ -22,10 +22,15 @@ public:
virtual status_t ConvertFromDriverSettings( virtual status_t ConvertFromDriverSettings(
const driver_parameter& parameter, const driver_parameter& parameter,
const char* name, int32 index, uint32 type, const char* name, int32 index, uint32 type,
BMessage& target) = 0; BMessage& target);
virtual status_t ConvertEmptyFromDriverSettings(
const driver_parameter& parameter,
const char* name, uint32 type,
BMessage& target);
virtual status_t ConvertToDriverSettings(const BMessage& source, virtual status_t ConvertToDriverSettings(const BMessage& source,
const char* name, int32 index, const char* name, int32 index,
uint32 type, BString& value) = 0; uint32 type, BString& value);
}; };
@@ -28,6 +28,32 @@ DriverSettingsConverter::~DriverSettingsConverter()
} }
status_t
DriverSettingsConverter::ConvertFromDriverSettings(
const driver_parameter& parameter, const char* name, int32 index,
uint32 type, BMessage& target)
{
return B_NOT_SUPPORTED;
}
status_t
DriverSettingsConverter::ConvertEmptyFromDriverSettings(
const driver_parameter& parameter, const char* name, uint32 type,
BMessage& target)
{
return B_NOT_SUPPORTED;
}
status_t
DriverSettingsConverter::ConvertToDriverSettings(const BMessage& source,
const char* name, int32 index, uint32 type, BString& value)
{
return B_NOT_SUPPORTED;
}
// #pragma mark - // #pragma mark -
@@ -133,14 +159,19 @@ const settings_template*
DriverSettingsMessageAdapter::_FindSettingsTemplate( DriverSettingsMessageAdapter::_FindSettingsTemplate(
const settings_template* settingsTemplate, const char* name) const settings_template* settingsTemplate, const char* name)
{ {
while (settingsTemplate->name != NULL) { const settings_template* wildcardTemplate = NULL;
if (!strcmp(name, settingsTemplate->name))
while (settingsTemplate->type != 0) {
if (settingsTemplate->name != NULL
&& !strcmp(name, settingsTemplate->name))
return settingsTemplate; return settingsTemplate;
if (settingsTemplate->name == NULL)
wildcardTemplate = settingsTemplate;
settingsTemplate++; settingsTemplate++;
} }
return NULL; return wildcardTemplate;
} }
@@ -152,7 +183,7 @@ DriverSettingsMessageAdapter::_FindParentValueTemplate(
if (settingsTemplate == NULL) if (settingsTemplate == NULL)
return NULL; return NULL;
while (settingsTemplate->name != NULL) { while (settingsTemplate->type != 0) {
if (settingsTemplate->parent_value) if (settingsTemplate->parent_value)
return settingsTemplate; return settingsTemplate;
@@ -167,12 +198,15 @@ status_t
DriverSettingsMessageAdapter::_AddParameter(const driver_parameter& parameter, DriverSettingsMessageAdapter::_AddParameter(const driver_parameter& parameter,
const settings_template& settingsTemplate, BMessage& message) const settings_template& settingsTemplate, BMessage& message)
{ {
const char* name = settingsTemplate.name;
if (name == NULL)
name = parameter.name;
for (int32 i = 0; i < parameter.value_count; i++) { for (int32 i = 0; i < parameter.value_count; i++) {
if (settingsTemplate.converter != NULL) { if (settingsTemplate.converter != NULL) {
status_t status status_t status
= settingsTemplate.converter->ConvertFromDriverSettings( = settingsTemplate.converter->ConvertFromDriverSettings(
parameter, settingsTemplate.name, i, settingsTemplate.type, parameter, name, i, settingsTemplate.type, message);
message);
if (status == B_OK) if (status == B_OK)
continue; continue;
if (status != B_NOT_SUPPORTED) if (status != B_NOT_SUPPORTED)
@@ -183,12 +217,10 @@ DriverSettingsMessageAdapter::_AddParameter(const driver_parameter& parameter,
switch (settingsTemplate.type) { switch (settingsTemplate.type) {
case B_STRING_TYPE: case B_STRING_TYPE:
status = message.AddString(settingsTemplate.name, status = message.AddString(name, parameter.values[i]);
parameter.values[i]);
break; break;
case B_INT32_TYPE: case B_INT32_TYPE:
status = message.AddInt32(settingsTemplate.name, status = message.AddInt32(name, atoi(parameter.values[i]));
atoi(parameter.values[i]));
break; break;
case B_BOOL_TYPE: case B_BOOL_TYPE:
{ {
@@ -197,7 +229,7 @@ DriverSettingsMessageAdapter::_AddParameter(const driver_parameter& parameter,
|| !strcasecmp(parameter.values[i], "yes") || !strcasecmp(parameter.values[i], "yes")
|| !strcasecmp(parameter.values[i], "enabled") || !strcasecmp(parameter.values[i], "enabled")
|| !strcasecmp(parameter.values[i], "1"); || !strcasecmp(parameter.values[i], "1");
status = message.AddBool(settingsTemplate.name, value); status = message.AddBool(name, value);
break; break;
} }
case B_MESSAGE_TYPE: case B_MESSAGE_TYPE:
@@ -210,9 +242,18 @@ DriverSettingsMessageAdapter::_AddParameter(const driver_parameter& parameter,
if (status != B_OK) if (status != B_OK)
return status; return status;
} }
if (settingsTemplate.type == B_BOOL_TYPE && parameter.value_count == 0) {
// Empty boolean parameters are always true if (parameter.value_count == 0) {
return message.AddBool(settingsTemplate.name, true); if (settingsTemplate.converter != NULL) {
status_t status
= settingsTemplate.converter->ConvertEmptyFromDriverSettings(
parameter, name, settingsTemplate.type, message);
if (status == B_NOT_SUPPORTED)
return B_OK;
} else if (settingsTemplate.type == B_BOOL_TYPE) {
// Empty boolean parameters are always true
return message.AddBool(name, true);
}
} }
return B_OK; return B_OK;
@@ -234,7 +234,7 @@ DriverSettingsMessageAdapterTest::TestParent()
void void
DriverSettingsMessageAdapterTest::TestConverter() DriverSettingsMessageAdapterTest::TestConverter()
{ {
class InterfaceAddressFamilyConverter : public DriverSettingsConverter { class HexConverter : public DriverSettingsConverter {
public: public:
status_t ConvertFromDriverSettings(const driver_parameter& parameter, status_t ConvertFromDriverSettings(const driver_parameter& parameter,
const char* name, int32 index, uint32 type, BMessage& target) const char* name, int32 index, uint32 type, BMessage& target)
@@ -274,6 +274,109 @@ DriverSettingsMessageAdapterTest::TestConverter()
} }
void
DriverSettingsMessageAdapterTest::TestWildcard()
{
const settings_template kTemplateA[] = {
{B_STRING_TYPE, NULL, NULL},
{B_INT32_TYPE, "test", NULL},
{}
};
Settings settingsA("this is\n"
"just a\n"
"test 42 43");
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, settingsA.ToMessage(kTemplateA, message));
CPPUNIT_ASSERT_EQUAL(42, message.GetInt32("test", 0, 0));
CPPUNIT_ASSERT_EQUAL(43, message.GetInt32("test", 1, 0));
CPPUNIT_ASSERT_EQUAL(3, message.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT_EQUAL(BString("is"),
BString(message.GetString("this", "-")));
CPPUNIT_ASSERT_EQUAL(BString("a"),
BString(message.GetString("just", "-")));
const settings_template kSubTemplateB[] = {
{B_STRING_TYPE, NULL, NULL, true},
{}
};
const settings_template kTemplateB[] = {
{B_MESSAGE_TYPE, "it", kSubTemplateB},
{}
};
Settings settingsB("it just works\n");
CPPUNIT_ASSERT_EQUAL(B_OK, settingsB.ToMessage(kTemplateB, message));
CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
BMessage subMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("it", &subMessage));
CPPUNIT_ASSERT_EQUAL(BString("just"),
BString(subMessage.GetString("it", 0, "-")));
CPPUNIT_ASSERT_EQUAL(BString("works"),
BString(subMessage.GetString("it", 1, "-")));
CPPUNIT_ASSERT_EQUAL(1, subMessage.CountNames(B_ANY_TYPE));
Settings settingsC("it {\n"
"\tstill works\n"
"}\n");
CPPUNIT_ASSERT_EQUAL(B_OK, settingsC.ToMessage(kTemplateB, message));
CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("it", &subMessage));
CPPUNIT_ASSERT_EQUAL(BString("works"),
BString(subMessage.GetString("still", "-")));
CPPUNIT_ASSERT_EQUAL(1, subMessage.CountNames(B_ANY_TYPE));
class WildcardConverter : public DriverSettingsConverter {
public:
status_t ConvertFromDriverSettings(const driver_parameter& parameter,
const char* name, int32 index, uint32 type, BMessage& target)
{
BMessage message;
message.AddString("args", parameter.values[index]);
return target.AddMessage(parameter.name, &message);
}
status_t ConvertEmptyFromDriverSettings(
const driver_parameter& parameter, const char* name, uint32 type,
BMessage& target)
{
if (parameter.parameter_count != 0)
return B_OK;
BMessage message;
return target.AddMessage(name, &message);
}
} converter;
const settings_template kSubTemplateC[] = {
{B_STRING_TYPE, NULL, NULL, true, &converter},
{}
};
const settings_template kTemplateC[] = {
{B_MESSAGE_TYPE, "if", kSubTemplateC},
{}
};
Settings settingsD("if {\n"
"\tsafemode\n"
"\tfile_exists one\n"
"}\n");
CPPUNIT_ASSERT_EQUAL(B_OK, settingsD.ToMessage(kTemplateC, message));
CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("if", &subMessage));
CPPUNIT_ASSERT_EQUAL(2, subMessage.CountNames(B_ANY_TYPE));
BMessage subSubMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("safemode",
&subSubMessage));
CPPUNIT_ASSERT(subSubMessage.IsEmpty());
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("file_exists",
&subSubMessage));
CPPUNIT_ASSERT_EQUAL(BString("one"),
BString(subSubMessage.GetString("args", 0, "-")));
CPPUNIT_ASSERT_EQUAL(1, subSubMessage.CountNames(B_ANY_TYPE));
}
/*static*/ void /*static*/ void
DriverSettingsMessageAdapterTest::AddTests(BTestSuite& parent) DriverSettingsMessageAdapterTest::AddTests(BTestSuite& parent)
{ {
@@ -292,6 +395,9 @@ DriverSettingsMessageAdapterTest::AddTests(BTestSuite& parent)
suite.addTest(new CppUnit::TestCaller<DriverSettingsMessageAdapterTest>( suite.addTest(new CppUnit::TestCaller<DriverSettingsMessageAdapterTest>(
"DriverSettingsMessageAdapterTest::TestConverter", "DriverSettingsMessageAdapterTest::TestConverter",
&DriverSettingsMessageAdapterTest::TestConverter)); &DriverSettingsMessageAdapterTest::TestConverter));
suite.addTest(new CppUnit::TestCaller<DriverSettingsMessageAdapterTest>(
"DriverSettingsMessageAdapterTest::TestWildcard",
&DriverSettingsMessageAdapterTest::TestWildcard));
parent.addTest("DriverSettingsMessageAdapterTest", &suite); parent.addTest("DriverSettingsMessageAdapterTest", &suite);
} }
@@ -19,6 +19,7 @@ public:
void TestMessage(); void TestMessage();
void TestParent(); void TestParent();
void TestConverter(); void TestConverter();
void TestWildcard();
static void AddTests(BTestSuite& suite); static void AddTests(BTestSuite& suite);
}; };