Real Time Open Sound Control librtosc
typed-message.h
1 #ifndef RTOSC_TYPED_MESSAGE_H
2 #define RTOSC_TYPED_MESSAGE_H
3 #include <rtosc/typestring.hh>
4 #include <rtosc/rtosc.h>
5 #include <type_traits>
6 #include <stdexcept>
7 
8 namespace rtosc
9 {
10 struct match_exact{};
11 struct match_partial{};
12 
13 template<class... Types> class rtMsg;
14 
15 // empty tuple
16 template<> class rtMsg<>
17 {
18  public:
19  rtMsg(const char *arg = NULL, const char *spec=NULL, bool _=false)
20  :msg(arg)
21  {
22  if(arg && spec && !rtosc_match_path(spec, arg, NULL))
23  msg = NULL;
24  (void)_;
25  }
26 
27  operator bool(void){return this->msg;}
28 
29  const char *msg;
30 };
31 
32 template<class T>
34 {
35  static std::true_type size;
36 };
37 
38 template<char ... C>
39 struct advance_size<irqus::typestring<C...>>
40 {
41  static std::false_type size;
42 };
43 
44 template<class T>
45 bool valid_char(char) { return false;}
46 
47 template<>
48 bool valid_char<const char*>(char c) { return c=='s' || c=='S'; };
49 
50 template<>
51 bool valid_char<int32_t>(char c) { return c=='i'; };
52 
53 template<>
54 bool valid_char<float>(char c) { return c=='f'; };
55 
56 template<int i>
57 bool validate(const char *arg)
58 {
59  return rtosc_narguments(arg) == i;
60 }
61 
62 template<class T>
63 bool match_path(std::false_type, const char *arg)
64 {
65  return rtosc_match_path(T::data(), arg, NULL);
66 }
67 
68 template<class T>
69 bool match_path(std::true_type, const char *)
70 {
71  return true;
72 }
73 
74 template<int i, class This, class... Rest>
75 bool validate(const char *arg)
76 {
77  auto size = advance_size<This>::size;
78  if(size && !valid_char<This>(rtosc_type(arg,i)))
79  return false;
80  else if(!size && !match_path<This>(size, arg))
81  return false;
82  else
83  return validate<i+advance_size<This>::size,Rest...>(arg);
84 }
85 
86 //Tuple Like Template Class Definition
87 template<class This, class... Rest>
88 class rtMsg<This, Rest...>:public rtMsg<Rest...>
89 {
90  public:
91  typedef This This_;
92  typedef rtMsg<Rest...> T;
93  rtMsg(const char *arg = NULL, const char *spec=NULL)
94  :T(arg, spec, false)
95  {
96  if(this->msg && !validate<0,This,Rest...>(this->msg))
97  this->msg = NULL;
98  }
99 
100  rtMsg(const char *arg, const char *spec, bool)
101  :T(arg, spec, false)
102  {}
103 
104 };
105 
106 
107 // tuple_element
108 template<size_t Index, class Tuple> struct osc_element;
109 
110 // select first element
111 template<class This, class... Rest>
112 struct osc_element<0, rtMsg<This, Rest...>>
113 {
114  typedef This type;
115 };
116 
117 // recursive tuple_element definition
118 template <size_t Index, class This, class... Rest>
119 struct osc_element<Index, rtMsg<This, Rest...>>
120 : public osc_element<Index - 1, rtMsg<Rest...>>
121 {
122 };
123 
124 template<class T>
125 T rt_get_impl(const char *msg, size_t i);
126 
127 template<>
128 const char *rt_get_impl(const char *msg, size_t i)
129 {
130  return rtosc_argument(msg,i).s;
131 }
132 
133 template<>
134 int32_t rt_get_impl(const char *msg, size_t i)
135 {
136  return rtosc_argument(msg,i).i;
137 }
138 
139 // get reference to _Index element of tuple
140 template<size_t Index, class... Types> inline
141  typename osc_element<Index, rtMsg<Types...>>::type
142 get(rtMsg<Types...>& Tuple)
143 {
144  if(!Tuple.msg)
145  throw std::invalid_argument("Message Does Not Match Spec");
146  typedef typename std::remove_reference<typename osc_element<Index, rtMsg<Types...>>::type>::type T;
147  return rt_get_impl<T>(Tuple.msg, Index);
148 }
149 
150 template<class... Types> inline
151  typename osc_element<0, rtMsg<Types...>>::type
152 first(rtMsg<Types...>&Tuple)
153 {
154  return get<0>(Tuple);
155 }
156 
157 template<class... Types> inline
158  typename osc_element<1, rtMsg<Types...>>::type
159 second(rtMsg<Types...>&Tuple)
160 {
161  return get<1>(Tuple);
162 }
163 
164 };
165 #endif
const char * rtosc_match_path(const char *pattern, const char *msg, const char **path_end)
Attempt to match a rtosc style path while ignoring arguments.
Definition: typed-message.h:13
Definition: typed-message.h:10
char rtosc_type(const char *msg, unsigned i)
Functions handling messages and arguments.
unsigned rtosc_narguments(const char *msg)
Returns the number of arguments found in a given message.
rtosc_arg_t rtosc_argument(const char *msg, unsigned i)
Blob data may be safely written to.
Definition: typed-message.h:11
Definition: typed-message.h:33
Definition: typed-message.h:108