Ejemplo n.º 1
0
    def testInfiniteElement(self):
        """ Test parsing an EBML file with an infinite-length element. """
        schemaFile = './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('><', '>\r\n<')

        ebmlDoc2 = schema.load(ebmlFile2, headers=True)
        ebmlRoot2 = util.toXml(ebmlDoc2)
        xmlString2 = ET.tostring(ebmlRoot2,
                                 encoding='UTF-8').replace('><', '>\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()
        xmlLines1 = [xmlLines1[0]] + xmlLines1[2:]
        xmlLines2 = xmlString2.splitlines()
        xmlLines2 = [xmlLines2[0]] + xmlLines2[2:]

        # Compare as lists to narrow the location of any differences
        self.assertListEqual(
            xmlLines1, xmlLines2,
            'One or more lines are different in the xml documents')
Ejemplo 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('./schemata/mide_ide.xml')
        self.doc = self.schema.load('./tests/SSX46714-doesnot.IDE')

        self.stream = StringIO('test')
Ejemplo n.º 3
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 = StringIO('\x4f\x56\x71\xea')

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

        self.element = GenericElement(stream=self.mockStream,
                                      offset=0,
                                      size=4,
                                      payloadOffset=2)
Ejemplo n.º 4
0
    def setUp(self):
        """ Set up a new Schema.  It is necessary to clear the cache to
            properly run tests.
        """

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

        self.stream = StringIO('test')
Ejemplo n.º 5
0
    def setUp(self):
        """ Set up a MasterElement with a single UIntegerElement child. """

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

        self.element = schema.elements[0x1A45DFA3](stream=self.mockStream,
                                                   offset=0,
                                                   size=4,
                                                   payloadOffset=5)
        self.element.schema = loadSchema('./schemata/mide_ide.xml')
        self.element.id = 0x1A45DFA3
Ejemplo n.º 6
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 = './schemata/matroska.xml'
        ebmlFile1 = './tests/video-1.mkv'
        ebmlFile2 = './tests/video-2.mkv'
        xmlFile1 = './tests/video-1.xml'
        xmlFile2 = './tests/video-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)

        # 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)

        # 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)
Ejemplo n.º 7
0
    def testPPrint(self):
        """ Test pretty-printing EBML files. """
        schemaFile = './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')
Ejemplo n.º 8
0
    def testParse(self):
        """ Test parsing MasterElements. """

        masterEl = MasterElement()
        masterEl.id = 0x1A45DFA3
        masterEl.size = 4
        masterEl.schema = loadSchema('./schemata/mide_ide.xml')
        self.assertEqual(masterEl, self.element)

        sEbmlVer = self.element.parse()[0]
        sEbmlVer.stream = self.mockStream
        ebmlVer = masterEl.schema.elements[0x4286](masterEl.stream, 5, 1, 8)
        ebmlVer.stream = self.mockStream
        ebmlVer._value = 16
        self.assertEqual(sEbmlVer, ebmlVer)
Ejemplo n.º 9
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, basestring):
        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
Ejemplo n.º 10
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":
Ejemplo n.º 11
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='    '))

# =======================================