1// vi:set ft=cpp: -*- Mode: C++ -*-
2
3#pragma once
4
5#include <l4/re/cap_alloc>
6#include <l4/re/util/cap_alloc>
7#include <l4/re/namespace>
8#include <l4/re/env>
9#include <cstring>
10
11namespace L4Re { namespace Util {
12
13class Env_ns
14{
15private:
16  L4Re::Cap_alloc *_ca;
17  Env const *_env;
18
19public:
20  explicit Env_ns(Env const *env = Env::env(),
21                  L4Re::Cap_alloc *ca = L4Re::Cap_alloc::get_cap_alloc(L4Re::Util::cap_alloc))
22  : _ca(ca), _env(env) {}
23
24  L4::Cap<void>
25  query(char const *name, unsigned len, int timeout = Namespace::To_default,
26        l4_umword_t *local_id = 0, bool iterate = true) const noexcept
27  {
28    typedef Env::Cap_entry Cap_entry;
29
30    char const *n = name;
31    for (; len && *n != '/'; ++n, --len)
32      ;
33
34    Cap_entry const *e = _env->get(name, n - name);
35    if (!e)
36      return L4::Cap<void>(-L4_ENOENT);
37
38    if (len > 0 && *n == '/')
39      {
40	L4::Cap<L4Re::Namespace> ns(e->cap);
41	L4::Cap<void> cap = _ca->alloc<void>();
42
43	if (!cap.is_valid())
44	  return L4::Cap<void>(-L4_ENOMEM);
45
46	long r = ns->query(n + 1, len - 1, cap, timeout, local_id, iterate);
47	if (r >= 0)
48	  return cap;
49
50	_ca->free(cap);
51
52	return L4::Cap<void>(r);
53      }
54
55    return L4::Cap<void>(e->cap);
56  }
57
58  L4::Cap<void>
59  query(char const *name, int timeout = Namespace::To_default,
60        l4_umword_t *local_id = 0, bool iterate = true) const noexcept
61  { return query(name, __builtin_strlen(name), timeout, local_id, iterate); }
62
63  template<typename T >
64  L4::Cap<T>
65  query(char const *name, int timeout = Namespace::To_default,
66        l4_umword_t *local_id = 0, bool iterate = true) const noexcept
67  {
68    return L4::cap_cast<T>(query(name, __builtin_strlen(name),
69                                 timeout, local_id, iterate));
70  }
71};
72
73}}
74