private void FindLogicalBounds(bool incrementalMode) { TextStreamPosition defaultBegin = new TextStreamPosition(0, TextStreamPosition.AlignMode.BeginningOfContainingBlock, textStreamPositioningParams); TextStreamPosition defaultEnd = DetectEndPositionFromMediaSize(); TextStreamPosition newBegin = incrementalMode ? beginPosition : defaultBegin; TextStreamPosition newEnd = defaultEnd; beginPosition = defaultBegin; endPosition = defaultEnd; try { if (!incrementalMode && beginFinder != null) { newBegin = FindBound(beginFinder, VolatileStream, StreamEncoding, "beginning", textStreamPositioningParams); } if (endFinder != null) { newEnd = FindBound(endFinder, VolatileStream, StreamEncoding, "end", textStreamPositioningParams); } } finally { beginPosition = newBegin; endPosition = newEnd; } }
static bool HeuristicallyDetectWhetherMultithreadingMakesSense(CreateParserParams parserParams, TextStreamPositioningParams textStreamPositioningParams) { #if SILVERLIGHT return(false); #else if (System.Environment.ProcessorCount == 1) { return(false); } long approxBytesToRead; if (parserParams.Direction == MessagesParserDirection.Forward) { approxBytesToRead = new TextStreamPosition(parserParams.Range.Value.End, textStreamPositioningParams).StreamPositionAlignedToBlockSize - new TextStreamPosition(parserParams.StartPosition, textStreamPositioningParams).StreamPositionAlignedToBlockSize; } else { approxBytesToRead = new TextStreamPosition(parserParams.StartPosition, textStreamPositioningParams).StreamPositionAlignedToBlockSize - new TextStreamPosition(parserParams.Range.Value.Begin, textStreamPositioningParams).StreamPositionAlignedToBlockSize; } if (approxBytesToRead < MultiThreadedStrategy <int> .GetBytesToParsePerThread(textStreamPositioningParams) * 2) { return(false); } return(true); #endif }
/// <summary> /// Prepares object for sequential reading from the stream. /// The object is loaded with peice of text that contains the character pointer by <paramref name="initialPosition"/>. /// Data is loaded from the underlying stream. /// </summary> public void BeginReading(long initialPosition, TextAccessDirection direction) { if (readingStarted) { throw new InvalidOperationException("Cannot start reading session. Another reading session has already been started"); } if (initialPosition < 0) { throw new ArgumentException("Negative positions are not allowed", "initialPosition"); } readingStarted = true; this.direction = direction; this.startPosition = new TextStreamPosition(initialPosition, textStreamPositioningParams); streamPositionToReadFromNextTime = new TextStreamPosition(initialPosition, textStreamPositioningParams).StreamPositionAlignedToBlockSize; streamPositionAlignedToBufferSize = streamPositionToReadFromNextTime; decoderNeedsReloading = EncodingNeedsReloading(); textBufferLength = 0; textBufferAsString = ""; charsCutFromBeginningOfTextBuffer = 0; charsCutFromEndOfTextBuffer = 0; AdvanceBufferInternal(0); }
private static long TextStreamPositionToStreamPosition_Approx(long pos, Encoding encoding, TextStreamPositioningParams positioningParams) { TextStreamPosition txtPos = new TextStreamPosition(pos, positioningParams); int byteCount; if (encoding == Encoding.UTF8) { byteCount = txtPos.CharPositionInsideBuffer; // usually utf8 use latin chars. 1 char -> 1 byte. } else if (encoding == Encoding.Unicode || encoding == Encoding.BigEndianUnicode) { byteCount = txtPos.CharPositionInsideBuffer * 2; // usually UTF16 does not user surrogates. 1 char -> 2 bytes. } else { byteCount = encoding.GetMaxByteCount(txtPos.CharPositionInsideBuffer); // default formula } return(txtPos.StreamPositionAlignedToBlockSize + byteCount); }
/// <summary> /// Creates valid TextStreamPosition object that points to the charachter that starts at or contains /// the byte defined by <paramref name="streamPosition"/> /// </summary> /// <param name="streamPosition">Stream position. In other words 0-based byte index in stream's data.</param> /// <param name="streamEncoding">Manadatory encoding information of the stream</param> /// <param name="stream"></param> /// <returns>Valid TextStreamPosition object</returns> public static async Task <TextStreamPosition> StreamPositionToTextStreamPosition(long streamPosition, Encoding streamEncoding, Stream stream, TextStreamPositioningParams textStreamPositioningParams) { if (streamEncoding == null) { throw new ArgumentNullException("streamEncoding"); } TextStreamPosition tmp = new TextStreamPosition(streamPosition, textStreamPositioningParams); #if !SILVERLIGHT if (streamEncoding.IsSingleByte) { return(tmp); } #endif if (streamEncoding == Encoding.Unicode || streamEncoding == Encoding.BigEndianUnicode) { return(new TextStreamPosition(tmp.StreamPositionAlignedToBlockSize, tmp.CharPositionInsideBuffer / 2, textStreamPositioningParams)); } #if !SILVERLIGHT if (streamEncoding == Encoding.UTF32) { return(new TextStreamPosition(tmp.StreamPositionAlignedToBlockSize, tmp.CharPositionInsideBuffer / 4, textStreamPositioningParams)); } #endif if (stream == null) { throw new ArgumentNullException("stream object is required to determine text stream position with given encoding", "stream"); } var boundedStream = new BoundedStream(); boundedStream.SetStream(stream, false); boundedStream.SetBounds(null, streamPosition); StreamTextAccess tmpTextAccess = new StreamTextAccess(boundedStream, streamEncoding, textStreamPositioningParams); await tmpTextAccess.BeginReading(tmp.StreamPositionAlignedToBlockSize, TextAccessDirection.Forward); tmp = tmpTextAccess.CharIndexToPosition(tmpTextAccess.BufferString.Length); tmpTextAccess.EndReading(); return(tmp); }
/// <summary> /// Returns char index in BufferString string that has absolute position <paramref name="pos"/> /// </summary> public int PositionToCharIndex(TextStreamPosition pos) { int?tmp = null; if (direction == TextAccessDirection.Backward) { if (pos.StreamPositionAlignedToBlockSize == streamPositionAlignedToBufferSize) { tmp = pos.CharPositionInsideBuffer; } else if (pos.StreamPositionAlignedToBlockSize == streamPositionAlignedToBufferSize + textStreamPositioningParams.AlignmentBlockSize) { tmp = pos.CharPositionInsideBuffer + textBufferLength - charactersLeftFromPrevBlock; } } else { if (pos.StreamPositionAlignedToBlockSize == streamPositionAlignedToBufferSize) { tmp = pos.CharPositionInsideBuffer + charactersLeftFromPrevBlock; } else if (pos.StreamPositionAlignedToBlockSize == streamPositionAlignedToBufferSize - textStreamPositioningParams.AlignmentBlockSize) { tmp = pos.CharPositionInsideBuffer - totalCharactersInPrevBlock + charactersLeftFromPrevBlock; } } if (tmp != null) { int ret = tmp.Value - charsCutFromBeginningOfTextBuffer; if (ret > textBufferAsString.Length) { return(textBufferAsString.Length); } if (ret >= 0) { return(ret); } } throw new ArgumentOutOfRangeException("position maps to the character that doesn't belong to current buffer"); }