mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-02 08:42:52 +00:00
os: generalize Session_label, Session_policy
The utilities in os/session_policy.h used to be tailored for the matching of session arguments against a server-side policy configuration. However, the policy-matching part is useful in other situations, too. This patch removes the tight coupling with the session-argument parsing (via Arg_string) and the hard-wired use of 'Genode::config()'. To make the utilities more versatile, the 'Session_label' has become a 'Genode::String' (at the time when we originally introduced the 'Session_label', there was no 'Genode::String'). The parsing of the session arguments happens in the constructor of this special 'String'. The constructor of 'Session_policy' now takes a 'Genode::String' as argument. So it can be used with the 'Session_label' but also with other 'String' types. Furthermore, the implicit use of 'Genode::config()' can be overridden by explicitly specifying the config node as an argument.
This commit is contained in:
parent
1f941d1c87
commit
dce6e14e3e
@ -18,38 +18,33 @@
|
|||||||
#include <os/config.h>
|
#include <os/config.h>
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
|
|
||||||
class Session_label;
|
struct Session_label;
|
||||||
class Session_policy;
|
class Session_policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Genode::Session_label
|
struct Genode::Session_label : String<128>
|
||||||
{
|
{
|
||||||
public:
|
Session_label() { }
|
||||||
|
|
||||||
enum { MAX_LEN = 128 };
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param args session arguments as null-terminated string
|
||||||
|
*
|
||||||
|
* The constructor extracts the label from the supplied session-argument
|
||||||
|
* string.
|
||||||
|
*/
|
||||||
|
explicit Session_label(char const *args)
|
||||||
|
{
|
||||||
|
typedef String<128> String;
|
||||||
|
|
||||||
private:
|
char buf[String::capacity()];
|
||||||
|
Arg_string::find_arg(args, "label").string(buf, sizeof(buf),
|
||||||
char _buf[MAX_LEN];
|
"<undefined>");
|
||||||
|
*static_cast<String *>(this) = String(buf);
|
||||||
public:
|
}
|
||||||
|
|
||||||
Session_label() { _buf[0] = 0; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* \param args session arguments as null-terminated string
|
|
||||||
*/
|
|
||||||
explicit Session_label(char const *args)
|
|
||||||
{
|
|
||||||
Arg_string::find_arg(args, "label").string(_buf, sizeof(_buf),
|
|
||||||
"<undefined>");
|
|
||||||
}
|
|
||||||
|
|
||||||
char const *string() const { return _buf; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -71,41 +66,43 @@ class Genode::Session_policy : public Xml_node
|
|||||||
* Returns true if the start of the label matches the specified
|
* Returns true if the start of the label matches the specified
|
||||||
* match string
|
* match string
|
||||||
*/
|
*/
|
||||||
static bool _label_matches(Session_label const &label, char const *match) {
|
static bool _label_matches(char const *label, char const *match) {
|
||||||
return strcmp(label.string(), match, strlen(match)) == 0; }
|
return strcmp(label, match, strlen(match)) == 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query session policy from session label
|
* Query session policy from session label
|
||||||
*/
|
*/
|
||||||
static Xml_node _query_policy(Session_label const &label)
|
static Xml_node _query_policy(char const *label, Xml_node config)
|
||||||
{
|
{
|
||||||
/* find index of policy node that matches best */
|
/*
|
||||||
int best_match = -1;
|
* Find policy node that matches best
|
||||||
try {
|
*/
|
||||||
unsigned label_len = 0;
|
Xml_node best_match("<none/>");
|
||||||
Xml_node policy = config()->xml_node().sub_node();
|
|
||||||
|
|
||||||
for (int i = 0;; i++, policy = policy.next()) {
|
unsigned label_len = 0;
|
||||||
|
|
||||||
if (!policy.has_type("policy"))
|
/*
|
||||||
continue;
|
* Functor to be applied to each policy node
|
||||||
|
*/
|
||||||
|
auto lambda = [&] (Xml_node policy) {
|
||||||
|
|
||||||
/* label attribute from policy node */
|
/* label attribute from policy node */
|
||||||
char policy_label[Session_label::MAX_LEN];
|
char policy_label[Session_label::capacity()];
|
||||||
policy.attribute("label").value(policy_label,
|
policy.attribute("label").value(policy_label,
|
||||||
sizeof(policy_label));
|
sizeof(policy_label));
|
||||||
|
|
||||||
if (!_label_matches(label, policy_label)
|
if (!_label_matches(label, policy_label)
|
||||||
|| strlen(policy_label) < label_len)
|
|| strlen(policy_label) < label_len)
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
label_len = strlen(policy_label);
|
label_len = strlen(policy_label);
|
||||||
best_match = i;
|
best_match = policy;
|
||||||
}
|
};
|
||||||
} catch (...) { }
|
|
||||||
|
|
||||||
if (best_match != -1)
|
config.for_each_sub_node("policy", lambda);
|
||||||
return config()->xml_node().sub_node(best_match);
|
|
||||||
|
if (!best_match.has_type("none"))
|
||||||
|
return best_match;
|
||||||
|
|
||||||
throw No_policy_defined();
|
throw No_policy_defined();
|
||||||
}
|
}
|
||||||
@ -115,23 +112,28 @@ class Genode::Session_policy : public Xml_node
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* \param args session arguments
|
* \param label label used as the selector of a policy
|
||||||
|
* \param config XML node that contains the policies as sub nodes,
|
||||||
|
* using the component's top-level config node by
|
||||||
|
* default
|
||||||
*
|
*
|
||||||
* \throw No_policy_defined if the server configuration has no
|
* \throw No_policy_defined the server configuration has no
|
||||||
* policy defined for the session
|
* policy defined for the specified label
|
||||||
* request
|
|
||||||
*
|
*
|
||||||
* On construction, the 'Session_policy' looks up the 'policy' XML
|
* On construction, the 'Session_policy' looks up the 'policy' XML node
|
||||||
* node that matches the label provided as argument. The
|
* that matches the label provided as argument. The server-side
|
||||||
* server-side policies are defined in one or more policy subnodes
|
* policies are defined in one or more policy subnodes of the server's
|
||||||
* of the server's 'config' node. Each policy node has a label
|
* 'config' node. Each policy node has a label attribute. If the policy
|
||||||
* attribute. If the policy label matches the first part of the
|
* label matches the first part of the label as delivered as session
|
||||||
* label delivered as session argument, the policy matches. If
|
* argument, the policy matches. If multiple policies match, the one
|
||||||
* multiple policies match, the one with the largest label is
|
* with the longest label is selected.
|
||||||
* selected.
|
|
||||||
*/
|
*/
|
||||||
explicit Session_policy(Session_label const &label)
|
template <size_t N>
|
||||||
: Xml_node(_query_policy(label)) { }
|
explicit Session_policy(String<N> const &label,
|
||||||
|
Xml_node config = Genode::config()->xml_node())
|
||||||
|
:
|
||||||
|
Xml_node(_query_policy(label.string(), config))
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__OS__SESSION_POLICY_H_ */
|
#endif /* _INCLUDE__OS__SESSION_POLICY_H_ */
|
||||||
|
@ -69,7 +69,7 @@ class Session : public Session_list::Element
|
|||||||
* Append label separator to match selectors with a trailing
|
* Append label separator to match selectors with a trailing
|
||||||
* separator.
|
* separator.
|
||||||
*/
|
*/
|
||||||
char label[Genode::Session_label::MAX_LEN + 4];
|
char label[Genode::Session_label::capacity() + 4];
|
||||||
Genode::snprintf(label, sizeof(label), "%s ->", _label.string());
|
Genode::snprintf(label, sizeof(label), "%s ->", _label.string());
|
||||||
return Genode::strcmp(label, selector,
|
return Genode::strcmp(label, selector,
|
||||||
Genode::strlen(selector)) == 0;
|
Genode::strlen(selector)) == 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user