@l5i/dashjs
Version:
A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.
91 lines (90 loc) • 7 kB
JavaScript
;Object.defineProperty(exports,'__esModule',{value:true});function _interopRequireDefault(obj){return obj && obj.__esModule?obj:{'default':obj};}var _coreFactoryMaker=require('../../core/FactoryMaker');var _coreFactoryMaker2=_interopRequireDefault(_coreFactoryMaker); /**
* Creates an instance of an EBMLParser class which implements a large subset
* of the functionality required to parse Matroska EBML
*
* @param {Object} config object with data member which is the buffer to parse
*/function EBMLParser(config){config = config || {};var instance=undefined;var data=new DataView(config.data);var pos=0;function getPos(){return pos;}function setPos(value){pos = value;} /**
* Consumes an EBML tag from the data stream.
*
* @param {Object} tag to parse, A tag is an object with at least a {number} tag and
* {boolean} required flag.
* @param {boolean} test whether or not the function should throw if a required
* tag is not found
* @return {boolean} whether or not the tag was found
* @throws will throw an exception if a required tag is not found and test
* param is false or undefined, or if the stream is malformed.
* @memberof EBMLParser
*/function consumeTag(tag,test){var found=true;var bytesConsumed=0;var p1=undefined,p2=undefined;if(test === undefined){test = false;}if(tag.tag > 0xFFFFFF){if(data.getUint32(pos) !== tag.tag){found = false;}bytesConsumed = 4;}else if(tag.tag > 0xFFFF){ // 3 bytes
p1 = data.getUint16(pos);p2 = data.getUint8(pos + 2); // shift p1 over a byte and add p2
if(p1 * 256 + p2 !== tag.tag){found = false;}bytesConsumed = 3;}else if(tag.tag > 0xFF){if(data.getUint16(pos) !== tag.tag){found = false;}bytesConsumed = 2;}else {if(data.getUint8(pos) !== tag.tag){found = false;}bytesConsumed = 1;}if(!found && tag.required && !test){throw new Error('required tag not found');}if(found){pos += bytesConsumed;}return found;} /**
* Consumes an EBML tag from the data stream. If the tag is found then this
* function will also remove the size field which follows the tag from the
* data stream.
*
* @param {Object} tag to parse, A tag is an object with at least a {number} tag and
* {boolean} required flag.
* @param {boolean} test whether or not the function should throw if a required
* tag is not found
* @return {boolean} whether or not the tag was found
* @throws will throw an exception if a required tag is not found and test
* param is false or undefined, or if the stream is malformedata.
* @memberof EBMLParser
*/function consumeTagAndSize(tag,test){var found=consumeTag(tag,test);if(found){getMatroskaCodedNum();}return found;} /**
* Consumes an EBML tag from the data stream. If the tag is found then this
* function will also remove the size field which follows the tag from the
* data stream. It will use the value of the size field to parse a binary
* field, using a parser defined in the tag itself
*
* @param {Object} tag to parse, A tag is an object with at least a {number} tag,
* {boolean} required flag, and a parse function which takes a size parameter
* @return {boolean} whether or not the tag was found
* @throws will throw an exception if a required tag is not found,
* or if the stream is malformed
* @memberof EBMLParser
*/function parseTag(tag){var size=undefined;consumeTag(tag);size = getMatroskaCodedNum();return instance[tag.parse](size);} /**
* Consumes an EBML tag from the data stream. If the tag is found then this
* function will also remove the size field which follows the tag from the
* data stream. It will use the value of the size field to skip over the
* entire section of EBML encapsulated by the tag.
*
* @param {Object} tag to parse, A tag is an object with at least a {number} tag, and
* {boolean} required flag
* @param {boolean} test a flag to indicate if an exception should be thrown
* if a required tag is not found
* @return {boolean} whether or not the tag was found
* @throws will throw an exception if a required tag is not found and test is
* false or undefined or if the stream is malformed
* @memberof EBMLParser
*/function skipOverElement(tag,test){var found=consumeTag(tag,test);var headerSize=undefined;if(found){headerSize = getMatroskaCodedNum();pos += headerSize;}return found;} /**
* Returns and consumes a number encoded according to the Matroska EBML
* specification from the bitstream.
*
* @param {boolean} retainMSB whether or not to retain the Most Significant Bit (the
* first 1). this is usually true when reading Tag IDs.
* @return {number} the decoded number
* @throws will throw an exception if the bit stream is malformed or there is
* not enough data
* @memberof EBMLParser
*/function getMatroskaCodedNum(retainMSB){var bytesUsed=1;var mask=0x80;var maxBytes=8;var extraBytes=-1;var num=0;var ch=data.getUint8(pos);var i=0;for(i = 0;i < maxBytes;i += 1) {if((ch & mask) === mask){num = retainMSB === undefined?ch & ~mask:ch;extraBytes = i;break;}mask >>= 1;}for(i = 0;i < extraBytes;i += 1,bytesUsed += 1) {num = num << 8 | 0xff & data.getUint8(pos + bytesUsed);}pos += bytesUsed;return num;} /**
* Returns and consumes a float from the bitstream.
*
* @param {number} size 4 or 8 byte floats are supported
* @return {number} the decoded number
* @throws will throw an exception if the bit stream is malformed or there is
* not enough data
* @memberof EBMLParser
*/function getMatroskaFloat(size){var outFloat=undefined;switch(size){case 4:outFloat = data.getFloat32(pos);pos += 4;break;case 8:outFloat = data.getFloat64(pos);pos += 8;break;}return outFloat;} /**
* Consumes and returns an unsigned int from the bitstream.
*
* @param {number} size 1 to 8 bytes
* @return {number} the decoded number
* @throws will throw an exception if the bit stream is malformed or there is
* not enough data
* @memberof EBMLParser
*/function getMatroskaUint(size){var val=0;for(var i=0;i < size;i += 1) {val <<= 8;val |= data.getUint8(pos + i) & 0xff;}pos += size;return val;} /**
* Tests whether there is more data in the bitstream for parsing
*
* @return {boolean} whether there is more data to parse
* @memberof EBMLParser
*/function moreData(){return pos < data.byteLength;}instance = {getPos:getPos,setPos:setPos,consumeTag:consumeTag,consumeTagAndSize:consumeTagAndSize,parseTag:parseTag,skipOverElement:skipOverElement,getMatroskaCodedNum:getMatroskaCodedNum,getMatroskaFloat:getMatroskaFloat,getMatroskaUint:getMatroskaUint,moreData:moreData};return instance;}EBMLParser.__dashjs_factory_name = 'EBMLParser';exports['default'] = _coreFactoryMaker2['default'].getClassFactory(EBMLParser);module.exports = exports['default'];
//# sourceMappingURL=EBMLParser.js.map