Esempio n. 1
0
    def setUp(self):
        """ Set up the unit tests with a StringElement class with some
            custom data (id: 0x4F40, value: 'bork').
        """

        self.mockStream = StringIO('\x4f\x40bork\x4f\x40bork')

        mide_schema = loadSchema('mide_ide.xml')
        matroska_schema = loadSchema('matroska.xml')

        eclass1 = type('StrEl1Element', (StringElement,),
                      {'id':0x7c, 'name':'StrEl1', 'schema':mide_schema,
                       '__slots__': StringElement.__slots__})

        eclass2 = type('StrEl2Element', (StringElement,),
                      {'id':0x7c, 'name':'StrEl2', 'schema':mide_schema,
                       '__slots__': StringElement.__slots__})

        eclass3 = type('StrEl3Element', (StringElement,),
                      {'id':0x5e, 'name':'StrEl3', 'schema':matroska_schema,
                       '__slots__': StringElement.__slots__})

        self.strEl1 = eclass1(stream=self.mockStream, offset=0, size=4,
                            payloadOffset=2)

        self.strEl2 = eclass2(stream=self.mockStream, offset=0, size=4,
                                     payloadOffset=2)

        self.strEl3 = eclass3(stream=self.mockStream, offset=0, size=8,
                                     payloadOffset=2)


        self.uniEl = UnicodeElement(stream=self.mockStream, offset=0, size=4,
                                    payloadOffset=2)
Esempio n. 2
0
    def setUp(self):
        """ Set up a Schema from mide_ide.xml and create a Document from an IDE file. """

        self.schema = loadSchema('./ebmlite/schemata/mide_ide.xml')
        self.doc = self.schema.load('./tests/SSX46714-doesnot.IDE')

        self.stream = BytesIO(b'test')
Esempio n. 3
0
    def testIntEq(self):
        """ Test equality of IntegerElements. """

        # Define buffers for IntegerElements
        m1 = StringIO('\x4f\x56\x71\xea')
        m2 = StringIO('abcd')
        m3 = StringIO('\x4f\x56\x71\xea')

        # Create IntegerElements
        mide_schema = loadSchema('mide_ide.xml')
        eclass1 = type('IntEl1Element', (IntegerElement,),
                      {'id':0x7c, 'name':'IntEl1', 'schema':mide_schema,
                       '__slots__': IntegerElement.__slots__})
        eclass2 = type('IntEl2Element', (IntegerElement,),
                      {'id':0x7c, 'name':'IntEl2', 'schema':mide_schema,
                       '__slots__': IntegerElement.__slots__})
        eclass3 = type('IntEl3Element', (IntegerElement,),
                      {'id':0x7c, 'name':'IntEl3', 'schema':mide_schema,
                       '__slots__': IntegerElement.__slots__})

        intEl1 = eclass1(stream=m1, offset=0, size=4, payloadOffset=2)
        intEl2 = eclass2(stream=m2, offset=0, size=4, payloadOffset=2)
        intEl3 = eclass3(stream=m3, offset=0, size=4, payloadOffset=2)

        # Assert that the first two elements are not equal
        self.assertNotEqual(intEl1, intEl2)

        # Assert that the first and last elements are equal
        intEl1.stream.seek(0)
        intEl3.stream.seek(0)
        self.assertEqual(intEl1, intEl3)
Esempio n. 4
0
    def testCreateID(self):
        """ Test the EBML ID generation utility function. """
        schema = core.loadSchema('matroska.xml')

        ranges = dict(A=(0x81, 0xFE),
                      B=(0x407F, 0x7FFE),
                      C=(0x203FFF, 0x3FFFFE),
                      D=(0x101FFFFF, 0x1FFFFFFE))

        # Test IDs not already in schema
        for idClass in ranges.keys():
            ids = util.createID(schema, idClass, count=1000)
            self.assertTrue(all(eid not in schema for eid in ids), "createID() produced a used class %s ID"
                            % idClass)

        self.assertRaises(KeyError, util.createID, schema, 'E')

        # Test exclusion of indicated IDs
        ids = util.createID(schema, 'A', count=100)
        ids2 = util.createID(schema, 'A', count=100, exclude=ids)
        self.assertTrue(len(ids2) == 0, "createID() failed to exclude specified IDs")

        # Test count restriction.
        # Note: May need changing if the Matroska schema is modified
        self.assertTrue(4 < len(util.createID(schema, 'A', count=5)) <= 5)

        # Test ID class range restrictions
        for idClass, (minId, maxId) in ranges.items():
            m = min(util.createID(schema, idClass, minId=minId-50, count=100))
            self.assertGreaterEqual(m, minId, "createID() generated out-of-range value ID for class %s: %s"
                                    % (idClass, m))

            m = max(util.createID(schema, idClass, minId=maxId-50, count=100))
            self.assertLessEqual(m, maxId, "createID() generated out-of-range value ID for class %s: %s"
                                 % (idClass, m))
Esempio n. 5
0
    def setUp(self):
        """ Set up the unit tests with a DateElement class with some
            custom data (id: -, value: 0x00 00 00 41).
        """

        self.mockStream = BytesIO()
        self.mockStream.string = b'\x00\x00\x00A'

        mide_schema = loadSchema('mide_ide.xml')
        self.unkEl1 = UnknownElement(stream=self.mockStream,
                                     offset=1,
                                     size=4,
                                     payloadOffset=1,
                                     schema=mide_schema,
                                     eid=0x7c)

        self.unkEl2 = UnknownElement(stream=self.mockStream,
                                     offset=1,
                                     size=4,
                                     payloadOffset=1,
                                     schema=mide_schema,
                                     eid=0x7c)

        self.unkEl3 = UnknownElement(stream=self.mockStream,
                                     offset=1,
                                     size=4,
                                     payloadOffset=1,
                                     schema=mide_schema,
                                     eid=0x7d)
Esempio n. 6
0
    def testInfiniteElement(self):
        """ Test parsing an EBML file with an infinite-length element. """
        schemaFile = './ebmlite/schemata/matroska.xml'
        ebmlFile1 = './tests/video-2.mkv'
        ebmlFile2 = './tests/video-3.mkv'

        schema = core.loadSchema(schemaFile)

        # Convert the MKV files into human-readable xml strings
        ebmlDoc1 = schema.load(ebmlFile1, headers=True)
        ebmlRoot1 = util.toXml(ebmlDoc1)
        xmlString1 = ET.tostring(ebmlRoot1, encoding='UTF-8').replace(b'><', b'>\r\n<')

        ebmlDoc2 = schema.load(ebmlFile2, headers=True)
        ebmlRoot2 = util.toXml(ebmlDoc2)
        xmlString2 = ET.tostring(ebmlRoot2, encoding='UTF-8').replace(b'><', b'>\r\n<')

        # Convert the xml strings into lists of lines to make comparison easier,
        # dropping the second line because that will reference different source
        # file names
        xmlLines1 = xmlString1.splitlines()
        xmlLines2 = xmlString2.splitlines()

        # Compare as lists to narrow the location of any differences
        self.assertListEqual(xmlLines1[1:], xmlLines2[1:],
                             'One or more lines are different in the xml documents')
Esempio n. 7
0
    def setUp(self):
        """ Set up the unit tests with a generic Element class with some
            custom data (id: 0x4F56, value: 0x71EA).
        """

        # set element as:
        #       id:   00 1111  0101 0110
        #    value:   11 0001  1110 1010
        #   header: 0100 1111  0101 0110
        #     data: 0111 0001  1110 1010
        self.mockStream = BytesIO(b'\x4f\x56\x71\xea')

        GenericElement = type(
            'GenericElement', (Element, ), {
                'id': 0x4343,
                'name': b'Generic Element',
                'schema': loadSchema('./ebmlite/schemata/mide_ide.xml'),
                'mandatory': False,
                'multiple': False,
                'precache': False,
                'length': 4,
                'children': dict(),
                '__doc__': b'no'
            })

        self.element = GenericElement(stream=self.mockStream,
                                      offset=0,
                                      size=4,
                                      payloadOffset=2)
Esempio n. 8
0
    def setUp(self):
        """ Set up the unit tests with an IntegerElement class with some
            custom data (id: -, value: 0xFC18).
        """

        # -1000 = -0b0000 0011  1110 1000 =>
        # 0b1111 1100  0001 1000 =>
        # 0xfc18
        self.mockStream = BytesIO(b'\xfc\x18')

        mide_schema = loadSchema('mide_ide.xml')
        eclass1 = type(
            'IntEl1Element', (IntegerElement, ), {
                'id': 0x7c,
                'name': b'IntEl1',
                'schema': mide_schema,
                '__slots__': IntegerElement.__slots__
            })

        eclass2 = type(
            'UIntEl1Element', (UIntegerElement, ), {
                'id': 0x7c,
                'name': b'UIntEl1',
                'schema': mide_schema,
                '__slots__': UIntegerElement.__slots__
            })

        self.intEl1 = eclass1(stream=self.mockStream,
                              offset=0,
                              size=4,
                              payloadOffset=2)
        self.uintEl1 = eclass2(stream=self.mockStream,
                               offset=0,
                               size=4,
                               payloadOffset=2)
Esempio n. 9
0
    def setUp(self):
        """ Set up a new Schema.  It is necessary to clear the cache to
            properly run tests.
        """

        from ebmlite import core
        core.SCHEMATA = {}
        self.schema = loadSchema('./ebmlite/schemata/mide_ide.xml')

        self.stream = BytesIO(b'test')
Esempio n. 10
0
    def testMkv(self):
        """ Test the functionality of the ebmlite library by converting a known
            good MKV file (a derivative of EBML) back and forth, then compare
            the results.
        """
        schemaFile = './ebmlite/schemata/matroska.xml'
        ebmlFile1 = './tests/video-1.mkv'
        ebmlFile2 = './tests/video-1-copy.mkv'
        xmlFile1 = './tests/video-1.xml'
        xmlFile2 = './tests/video-1-copy.xml'

        schema = core.loadSchema(schemaFile)

        # Start with toXml
        ebmlDoc1 = schema.load(ebmlFile1, headers=True)
        ebmlRoot = util.toXml(ebmlDoc1)
        xmlString1 = ET.tostring(ebmlRoot, encoding='UTF-8')

        # Save xml
        with open(xmlFile1, 'wt') as f:
            f.write(xmlString1.decode())

        # Convert xml2ebml
        with open(ebmlFile2, 'wb') as out:
            util.xml2ebml(xmlFile1, out, schema)

        # write the second xml file
        ebmlDoc2 = schema.load(ebmlFile2, headers=True)
        mkvRoot2 = util.toXml(ebmlDoc2)
        xmlString2 = ET.tostring(mkvRoot2, encoding='UTF-8')
        # self.assertEqual(xmlString1, xmlString2, "xml strings aren't matching up")
        with open(xmlFile2, 'wt') as f:
            f.write(xmlString2.decode())

        # Load back the XML files in order to compare the two
        xmlDoc1 = util.loadXml(xmlFile1, schema)
        xmlDoc2 = util.loadXml(xmlFile2, schema)

        # Compare each element from the XML
        xmlEls1 = [xmlDoc1]
        xmlEls2 = [xmlDoc2]
        while len(xmlEls1) > 0:
            self.assertEqual(xmlEls1[0], xmlEls2[0], 'Element '
                             + repr(xmlEls1[0])
                             + ' was not converted properly')
            for x in list(xmlEls1.pop(0).children.values()):
                if issubclass(x, core.Element):
                    xmlEls1.append(x)
            for x in list(xmlEls2.pop(0).children.values()):
                if issubclass(x, core.Element):
                    xmlEls2.append(x)
Esempio n. 11
0
    def testPPrint(self):
        """ Test pretty-printing EBML files. """
        schemaFile = './ebmlite/schemata/mide_ide.xml'
        schema = core.loadSchema(schemaFile)

        ebmlDoc = schema.load('./tests/SSX46714-doesnot.IDE', headers=True)

        util.pprint(ebmlDoc, out=open('./tests/IDE-Pretty.txt', 'wt'))
        xmlString = ET.tostring(util.toXml(ebmlDoc))
        prettyXmlFile = open('./tests/IDE-Pretty.xml', 'wt')
        parseString(xmlString).writexml(prettyXmlFile,
                                        addindent='\t',
                                        newl='\n',
                                        encoding='utf-8')
Esempio n. 12
0
    def setUp(self):
        """ Set up the unit tests with a FloatElement class with some
            custom data (id: 0x4F56, value: 0x3E AA AB).
        """

        self.mockStream = StringIO('\x4f\x56\x3e\xaa\xaa\xab')

        mide_schema = loadSchema('mide_ide.xml')
        eclass1 = type('FloatEl1Element', (FloatElement,),
                      {'id':0x7c, 'name':'FloatEl1', 'schema':mide_schema,
                       '__slots__': FloatElement.__slots__})

        self.floatEl = eclass1(stream=self.mockStream, offset=0, size=4,
                               payloadOffset=2)
    def testIde(self):
        """ Test the functionality of the ebmlite library by converting a known
            good IDE file (a derivative of EBML) back and forth, then compare
            the results.
        """
        schemaFile = './ebmlite/schemata/mide_ide.xml'
        ebmlFile1 = './tests/SSX46714-doesnot.IDE'
        ebmlFile2 = './tests/SSX46714-new.IDE'
        xmlFile1 = './tests/ssx-1.xml'
        xmlFile2 = './tests/ssx-2.xml'

        schema = core.loadSchema(schemaFile)

        # Start with toXml
        ebmlDoc1 = schema.load(ebmlFile1, headers=True)
        ebmlRoot = util.toXml(ebmlDoc1)
        xmlString1 = ET.tostring(ebmlRoot, encoding='UTF-8')

        # Save xml
        with open(xmlFile1, 'wt') as f:
            f.write(xmlString1.replace('><', '>\r\n<'))

        # Convert xml2ebml
        with open(ebmlFile2, 'wb') as out:
            util.xml2ebml(xmlFile1, out, schema)

        # write the second xml file
        ebmlDoc2 = schema.load(ebmlFile2, headers=True)
        mkvRoot2 = util.toXml(ebmlDoc2)
        xmlString2 = ET.tostring(mkvRoot2, encoding='UTF-8')
        with open(xmlFile2, 'wt') as f:
            f.write(xmlString2.replace('><', '>\r\n<'))

        # Load back the XML files in order to compare the two
        xmlDoc1 = util.loadXml(xmlFile1, schema)
        xmlDoc2 = util.loadXml(xmlFile2, schema)

        # Compare each element from the XML
        xmlEls1 = [xmlDoc1]
        xmlEls2 = [xmlDoc2]
        while len(xmlEls1) > 0:
            self.assertEqual(
                xmlEls1[0], xmlEls2[0],
                'Element ' + repr(xmlEls1[0]) + ' was not converted properly')
            for x in xmlEls1.pop(0).children.values():
                if issubclass(x, core.Element):
                    xmlEls1.append(x)
            for x in xmlEls2.pop(0).children.values():
                if issubclass(x, core.Element):
                    xmlEls2.append(x)
Esempio n. 14
0
    def setUp(self):
        """ Set up the unit tests with a DateElement class with some
            custom data (id: -, value: 0x00 00 00 41).
        """

        self.mockStream = StringIO()

        self.mockStream.string = '\x00\x00\x00A'

        mide_schema = loadSchema('mide_ide.xml')
        eclass1 = type('VoidEl1Element', (VoidElement,),
                      {'schema':mide_schema, id:0xEC,
                       '__slots__': VoidElement.__slots__})

        self.voiEl = eclass1(stream=self.mockStream, offset=1, size=4,
                             payloadOffset=1)
Esempio n. 15
0
    def setUp(self):
        """ Set up a MasterElement with a single UIntegerElement child. """

        schema = loadSchema('./ebmlite/schemata/mide_ide.xml')
        """ Master Element:   ID: 0x1A45DFA3
                            Size: 0x84
                           Value:
                UInt Element:   ID: 0x4286
                              Size: 0x81
                             value: 0x42
        """
        self.mockStream = BytesIO(b'\x1A\x45\xDF\xA3\x84\x42\x86\x81\x10')

        self.element = schema.elements[0x1A45DFA3](stream=self.mockStream,
                                                   offset=0,
                                                   size=4,
                                                   payloadOffset=5)
Esempio n. 16
0
# imports from python's built in xml library
from xml.etree import ElementTree as ET
from xml.dom.minidom import parseString

# =======================================
# converting a file from EBML to XML
# =======================================

# Files to use in this example
schemaFile = './schemata/mide_ide.xml'
ebmlFile1 = './tests/SSX46714-doesnot.IDE'
xmlFile1 = './tests/example-xml.xml'

# load the schema to use with these files.  This creates an object that is used
# to parse EBML files.
schema = core.loadSchema(schemaFile)

# Convert the EBML file to XML
ebmlDoc1 = schema.load(ebmlFile1, headers=True)  # load the file through
# the schema
ebmlRoot = toXml(ebmlDoc1)  # convert the file into
# a tree of XML elements
xmlString1 = ET.tostring(ebmlRoot, encoding='UTF-8')  # convert the xml tree
# into a string

# Save xml
with open(xmlFile1, 'wt') as f:
    # convert the xml string into a minidom object and pretty-print
    f.write(parseString(xmlString1).toprettyxml(indent='    '))

# =======================================
Esempio n. 17
0
def xml2ebml(xmlFile,
             ebmlFile,
             schema,
             sizeLength=None,
             headers=True,
             unknown=True):
    """ Convert an XML file to EBML.

        @todo: Convert XML on the fly, rather than parsing it first, allowing
            for the conversion of arbitrarily huge files.

        @param xmlFile: The XML source. Can be a filename, an open file-like
            stream, or a parsed XML document.
        @param ebmlFile: The EBML file to write. Can be a filename or an open
            file-like stream.
        @param schema: The EBML schema to use. Can be a filename or an
            instance of a `Schema`.
        @keyword sizeLength: The default length of each element's size
            descriptor. Must be large enough to store the largest 'master'
            element. If an XML element has a ``sizeLength`` attribute, it will
            override this.
        @keyword headers: If `True`, generate the standard ``EBML`` EBML
            element if the XML document does not contain one.
        @param unknown: If `True`, unknown element names will be allowed,
            provided their XML elements include an ``id`` attribute with the
            EBML ID (in hexadecimal).
        @return: the size of the ebml file in bytes.
        @raise NameError: raises if an xml element is not present in the schema.
    """
    if isinstance(ebmlFile, str):
        ebmlFile = open(ebmlFile, 'wb')
        openedEbml = True
    else:
        openedEbml = False

    if not isinstance(schema, core.Schema):
        schema = core.loadSchema(schema)

    if isinstance(xmlFile, ET.Element):
        # Already a parsed XML element
        xmlRoot = xmlFile
    elif isinstance(xmlFile, ET.ElementTree):
        # Already a parsed XML document
        xmlRoot = xmlFile.getroot()
    else:
        xmlDoc = ET.parse(xmlFile)
        xmlRoot = xmlDoc.getroot()

    if xmlRoot.tag not in schema and xmlRoot.tag != schema.document.__name__:
        raise NameError("XML element %s not an element or document in "
                        "schema %s (wrong schema)" %
                        (xmlRoot.tag, schema.name))

    headers = headers and 'EBML' in schema
    if headers and 'EBML' not in (el.tag for el in xmlRoot):
        pos = ebmlFile.tell()
        cls = schema.document
        ebmlFile.write(cls.encodePayload(cls._createHeaders()))
        numBytes = ebmlFile.tell() - pos
    else:
        numBytes = 0

    if xmlRoot.tag == schema.document.__name__:
        for el in xmlRoot:
            numBytes += xmlElement2ebml(el,
                                        ebmlFile,
                                        schema,
                                        sizeLength,
                                        unknown=unknown)
    else:
        numBytes += xmlElement2ebml(xmlRoot,
                                    ebmlFile,
                                    schema,
                                    sizeLength,
                                    unknown=unknown)

    if openedEbml:
        ebmlFile.close()

    return numBytes
Esempio n. 18
0
                           '--clobber',
                           action="store_true",
                           help="Clobber (overwrite) existing files.")
    argparser.add_argument('-p',
                           '--pretty',
                           action="store_true",
                           help="Generate 'pretty' XML with ebml2xml.")

    args = argparser.parse_args()

    if not os.path.exists(args.input):
        sys.stderr.write("Input file does not exist: %s\n" % args.input)
        exit(1)

    try:
        schema = core.loadSchema(args.schema)
    except IOError as err:
        errPrint("Error loading schema: %s\n" % err)

    if args.output:
        output = os.path.realpath(os.path.expanduser(args.output))
        if os.path.exists(output) and not args.clobber:
            errPrint("Output file exists: %s" % args.output)
        out = open(output, 'wb')
    else:
        out = sys.stdout

    if args.mode == "xml2ebml":
        xml2ebml(args.input, out,
                 schema)  # , sizeLength=4, headers=True, unknown=True)
    elif args.mode == "ebml2xml":