Пример #1
0
		public ElementInfo Next() {
			if((lastElementPos != ~VIntConsts.UNKNOWN_LENGTH && nextElementPos >= lastElementPos) || nextElementPos == ~VIntConsts.UNKNOWN_LENGTH || dataSrc.EOF) return null;
			if(dataSrc.Position != nextElementPos) dataSrc.Position = nextElementPos;

			ElementInfo elemInfo;
			var docElementId = dataSrc.ReadIdentifier();
			var vintPos = dataSrc.Position;
			var dataLength = dataSrc.ReadVInt();
			var dataPos = dataSrc.Position;

			var isDocElementInvalid = docElementId < 0 && (~docElementId & VIntConsts.ERROR) != 0;
			var isDataLengthInvalid = dataLength < 0 && (~dataLength & VIntConsts.ERROR) != 0;
			var isOutOfBounds = lastElementPos != ~VIntConsts.UNKNOWN_LENGTH && dataPos + dataLength > lastElementPos;
			if(isDocElementInvalid || isDataLengthInvalid || isOutOfBounds) {
				elemInfo = new ElementInfo(EBMLDocElement.Unknown, nextElementPos, vintPos, dataPos, 0);

				dataSrc.SyncTo(bytePatterns, lastElementPos);
				nextElementPos = dataSrc.Position;

				return elemInfo;
			}

			var docElem = docType.RetrieveDocElement(docElementId);
			elemInfo = new ElementInfo(docElem, nextElementPos, vintPos, dataPos, dataLength < 0 ? default(Int64?) : dataLength);

			nextElementPos = dataLength < 0 ? ~VIntConsts.UNKNOWN_LENGTH : dataPos + dataLength;

			//Trace.WriteLine(elemInfo.ToDetailedString());
			return elemInfo;
		}
Пример #2
0
		public Object RetrieveValue(ElementInfo elem) {
			if(elem == null) throw new ArgumentNullException("elem");
			if(!elem.DataLength.HasValue) throw new InvalidOperationException("Cannot retrieve value: Length unknown");

			if(elem.DataLength.Value == 0) return new byte[0];

			if(dataSrc.Position != elem.DataPos) throw new InvalidOperationException("Cannot retrieve value: Current position doesn't match element data position");

			Int64 offset;
			var valueData = dataSrc.GetData(elem.DataLength.Value, out offset);

			return docType.RetrieveValue(elem.DocElement, valueData, offset, elem.DataLength.Value);
		}
Пример #3
0
        public ElementInfo WriteElement(EBMLDocElement elem, Stream data)
        {
            Int64 idPos = dataSrc.Position;
            dataSrc.WriteIdentifier(elem.Id);

            Int64 vIntPos = dataSrc.Position;
            dataSrc.WriteFakeVInt(8);
            Int64 dataPos = dataSrc.Position;
            dataSrc.Write(data);

            var elemInfo = new ElementInfo(elem, idPos, vIntPos, dataPos, null);

            UpdateElementLength(elemInfo);

            return elemInfo;
        }
Пример #4
0
        private void UpdateElementLength(ElementInfo elemInfo)
        {
            var currentPos = dataSrc.Position;

            var dataLength = currentPos - elemInfo.DataPos;
            elemInfo.DataLength = dataLength;

            dataSrc.Position = elemInfo.VIntPos;
            dataSrc.WriteVInt(dataLength, 8);

            dataSrc.Position = currentPos;
        }
Пример #5
0
		public IDisposable EnterElement(ElementInfo elemInfo) {
			var disposable = new PreviousState {
				NextElementPos = nextElementPos,
				LastElementPos = lastElementPos
			};

			disposable.Disposed += (s, e) => {
				var d = (PreviousState)s;
				if(nextElementPos < d.LastElementPos) nextElementPos = d.NextElementPos;
				lastElementPos = d.LastElementPos;
			};

			nextElementPos = elemInfo.DataPos;
			lastElementPos = elemInfo.DataLength.HasValue ? elemInfo.DataPos + elemInfo.DataLength.Value : ~VIntConsts.UNKNOWN_LENGTH;

			return disposable;
		}