[vlc-devel] [Patches] Dash: mostly cosmetics

Tobias Güntner fatbull at web.de
Wed Dec 7 17:20:23 CET 2011


Am 07.12.2011 13:30, schrieb Hugo Beauzée-Luyssen:
> On Wed, Dec 7, 2011 at 12:39 PM, Tobias Güntner<fatbull at web.de>  wrote:
>> Am 06.12.2011 13:43, schrieb Hugo Beauzée-Luyssen:
>>
>>> Most of the error handling could be done once and for all after the
>>> parsing occurred.
>>
>>
>> Hmmm.
>>
>> Is the parsing really done if supposedly simple getters can still fail
>> because of errors in an input file? Aren't Attribute- and
>> ElementNotPresentException actually (tree) parsing errors? Why do most
>> getters return strings, although their names suggest otherwise? Why do
>> getters returning numbers have to call atoi first, i.e. parse their own
>> value? Shouldn't BasicCMParser take care of all these issues *before*
>> creating MPD objects?
>>
>
> I was thinking about some missing elements. Some attributes are
> mandatory and should indeed be parsed in the ctor, so the getter
> doesn't have to run atoi.
> Some getters return strings but shouldn't. Some patches I sent fix the
> problem for a few of them, some other need to be fixed.
> And indeed, the parser should run some input sanity check before
> trying to use the elements themselves.

That's not what I meant. Let me try again.

I suggest parsing that stuff in a real parser, not in constructors. And 
by "parsing" I mean the transformation of an XML DOM tree into actual 
MPD objects; not the transformation of a text blob into an XML DOM tree.

Parsing is more or less "on demand" right now, i.e., whenever a getter 
is called, it looks in a map whether an attribute was present in the 
input file and parses it, or throws an exception if there was a problem. 
This means every user of the MPD classes has to deal with parsing 
errors. Wouldn't it be a lot easier to handle this in one place?

* Let's remove all parsing logic from MPD classes, specifically the 
SomethingNotPresentExceptions and the attribute maps. Instead, create 
setters for individual attributes or have the constructors initialize 
them. Either way, attribute values are always valid and have the correct 
type. Only (trivial) getters and setters and perhaps a few special 
purpose methods remain. No exceptions are thrown.

* Have BasicCMParser read and parse all attributes. If attributes are 
missing, the parser can throw an AttributeNotPresentException. If some 
attributes are optional, the parser can instead set a reasonable default 
value or the class can set it in its ctor.

* Descend recursively to parse all XML nodes. If all child nodes and 
attributes could be parsed and are valid, create the appropriate MPD 
object and return it. If some elements are mandatory or may not be 
empty, this is the place to handle that, e.g., by throwing an 
ElementNotPresentException.

Pseudo code:

class BasicCMParser {
	string attribute(Node* parent, string name) {
		return attribute value or throw AttributeNotPresentException;
	}
	string attribute(Node* parent, string name, string default) {
		return attribute value or return default;
	}
	int intAttribute(Node* parent, string name, int default, int min, int 
max) {
		return attribute value or return default or throw 
InvalidAttributeValueException;
	}
	// ditto for other attribute types (int, date, enum, etc.)

	MPD* parseMPD(Node* root) {
		// parse attributes
		minBufferTime = intAttribute(root, "minBufferTime", 0, 0, MAX_TIME);
		// parse child elements
		vector<Period> periods;
		for(...) periods.add(parsePeriod(child));
		// input is valid, create the object
		return new MPD(...);
	}
	Period* parsePeriod(Node* node) {
		...
		parseGroup(...);
		...
	}
	...
	Representation* parseRepresentation(Node* node, SegmentInfoDefault* 
default) {
		...
		if(segment info is present)
			parseSegmentInfo(...);
		else
			use SegmentInfoDefault;
		...
	}
}

When the parser returns, users (like BasicCMManager) can call getters 
without having to worry about missing attributes. Also, callers don't 
have to worry about optional elements, either. For example, a 
Representation object can always store a SegmentInfo if the parser 
ensures that it is properly filled (i.e. from a SegmentInfo or 
SegmentInfoDefault element (or whatever the standard says; I'm not that 
familiar with it)).

Regards,
Tobias

PS:
The call to strstr in DOMParser::isDash looks suspicious. stream_Peek 
doesn't return a NUL terminated string, does it?




More information about the vlc-devel mailing list