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;
            }
        }
Exemple #2
0
        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");
        }