def scan(self, until=None): """ scan(until=None) Scans body for child elements from the last known child before current offset until the end of the body, or 'until.' """ offset = self.tell() childrenbefore = {(s, e) for (s, e) in self._knownChildren.items() if s <= offset} if len(childrenbefore): (s, e) = max(childrenbefore) self.seek(e) else: self.seek(0) if until is None: until = self._contentssize while offset < until: with self.lock: self.seek(offset) ebmlID = peekVint(self._file) size = peekVint(self._file, len(ebmlID)) if ebmlID != Void.ebmlID: self._knownChildren[offset] = offset + len(ebmlID) + len(size) + fromVint(size) offset += len(ebmlID) + len(size) + fromVint(size)
def decodeEBMLLacing(data): n = data[0] + 1 data = data[1:] size, data = parseVint(data) sizes = [fromVint(size)] for k in range(n - 2): size, data = parseVint(data) sizes.append(sizes[-1] + fromVint(size) - 2**(7 * len(size) - 1) + 1) return sizes, data
def parsepkt(data): """ Parse data. Returns a tuple: (trackNumber, localpts, keyframe, invisible, discardable, lacing, numberInLace, lacedData) """ trackNumber, data = parseVint(data) localpts = int.from_bytes(data[:2], "big", signed=True) flags = data[2] keyframe = bool(flags & 0b10000000) invisible = bool(flags & 0b00001000) discardable = (flags & 0b00000001) lacing = (flags & 0b00000110) >> 1 return (fromVint(trackNumber), localpts, keyframe, invisible, discardable, lacing, data[3:])
def _fromFile(cls, file, size, parent=None): self = cls.__new__(cls) self._parent = parent dataRead = 0 while dataRead < size: ebmlID = peekVint(file) childsize = peekVint(file, len(ebmlID)) childcls = self._childTypes[ebmlID] prop = self.__ebmlpropertiesbyid__[ebmlID] child = childcls.fromFile(file, parent=self) prop.__set__(self, child) dataRead += len(ebmlID) + len(childsize) + fromVint(childsize) return self
def _fromFile(cls, file, size, parent=None): self = cls([], parent=parent) dataRead = 0 while dataRead < size: ebmlID = peekVint(file) childsize = peekVint(file, len(ebmlID)) child = AttachedFile.fromFile(file, parent=self) self.attachedFiles.append(child) if not child.readonly: child.readonly = True dataRead += len(ebmlID) + len(childsize) + fromVint(childsize) return self
def readElement(self, withclass, parent=None, ignore=()): """ readElement(withclass, parent=None, ignore=()) Read element on behalf of a descendent element at the current file offset. Returns element of a class specified by 'withclass' (can be either a class, list, tuple, or dict with EBML IDs as keys). Advances read position and returns None if it detects an EBML ID specified in 'ignore'. """ if isinstance(withclass, type) and issubclass(withclass, EBMLElement): withclass = {withclass.ebmlID: withclass} elif isinstance(withclass, (list, tuple)): withclass = {cls.ebmlID: cls for cls in withclass} ignore = tuple(item.ebmlID if isinstance(item, EBMLElement) else item for item in ignore) offset = self.tell() if offset >= self._contentssize or offset < 0: return ebmlID = peekVint(self._file) size = peekVint(self._file, len(ebmlID)) if ebmlID in ignore or ebmlID == Void.ebmlID: self._file.seek(len(ebmlID) + len(size) + fromVint(size), 1) return if ebmlID not in withclass: raise ReadError(f"Unrecognized EBML ID [{formatBytes(ebmlID)}] at offet {offset} in body, (file offset {offset + self._contentsOffset}).") child = withclass[ebmlID].fromFile(self._file, parent=parent) if parent is self: child.offsetInParent = offset child.dataOffsetInParent = offset + len(ebmlID) + len(size) child.readonly = True return child
def _init_read(self): ebmlID = readVint(self._file) if self.ebmlID is not None: if self.ebmlID != ebmlID: raise ReadError(f"Incorrect EBML ID found. Expected '{formatBytes(self.ebmlID)},' got '{formatBytes(ebmlID)}' instead.") else: self.ebmlID = ebmlID self._sizeOffset = self._file.tell() size = readVint(self._file) self._sizesize = len(size) self._contentssize = fromVint(size) self._contentsOffset = self._file.tell() if self._file.writable(): self.seek(0) self.scan() self.seek(0)
def _fromBytes(cls, data, parent=None): numdata, dendata = parseVints(data) return cls(QQ( fromVint(numdata) - 2**(7 * len(numdata) - 1), fromVint(dendata)), parent=parent)
def _fromBytes(cls, data, parent=None): return cls(tuple(fromVint(b) for b in parseVints(data)), parent=parent)