I'm completely stuck with this for about 2 days now and it seems I simply can't get my head around the problem I'm facing.
Currently, I'm writing an SDP parsing library that should also be usable for creating correct SDP
messages according to it's specification (https://www.rfc-editor.org/rfc/rfc4566). But the specification is sometimes very open or unclear, so I try to implement a necessary amount of flexibility while still being as close to the RFC as possible.
Example Problem
A SDP message can contain media information ("m
" field) where as this information has the following pattern:
m=<media> <port> <proto> <fmt> ...
And example message could look like this:
m=video 49170/2 RTP/AVP 31
Take a look at the proto flag, which stands for Media Transport Protocol. According to the specification, this field can have the following values:
- RTP/AVP
- RTP/SAVP
- UDP
This is a list of values, so it's obviously appropriate to take an enumeration.
public enum MediaTransportProtocolType {
RTP/AVP
RTP/SAVP
UDP
}
Ooops! But this doesn't work because of the "/" char. So, how am I able to use this for parsing? I extended the Enumeration
fields with the DescriptionAttribute
public enum MediaTransportProtocolType {
[Description("RTP/AVP")
RTP_AVP
[Description("RTP/SAVP")
RTP_SAVP
[Description("UDP")
UDP
}
Now I can simply look up the appropriate media transport protocol type by it's description. But now, the RFC specification goes on:
This memo registers three values [...] If other RTP profiles are
defined in the future [...]
So it's possible that a future network device can send me an media transport protocol that I'm not aware of. The whole enumeration thing doesn't work here anymore as System.Enum
is not extendable due to various reason.
Solution
On my way looking for a solution I met the Type Safe Enumeration Pattern (AKA StringEnum
) as described in here: how can i use switch statement on type-safe enum pattern. This answer even describes a solution to make them switchable, even if it's an ugly solution IMHO.
But again, this does only work for a defined range. I extended the Type Safe Enumeration
class with a dictionary to store instances that I can look up while parsing, but also add new ones if I don't now them.
But what about all the other fields? And what about casting?
This answer here describes an approach with a base class and casting through explicit operators: Casting string to type-safe-enum using user-defined conversion
I tried it out, but it's not working the way I'd like it to be. (Invalid casting exceptions, dirty two casts pattern, not extendable).
How does one parse SDP information correctly and easily while still providing a library that allows to create a correct SDP?