예제 #1
0
        // -------------------------------------------------------------------------------------------
        /// <summary>
        /// Returns array of string segments divided by a separator and,
        /// optionally, omitting empty segments.
        /// PENDING: Optimize with IndexOfAny for searching with the first character.
        /// </summary>
        public static string[] Segment(this string Text, string Separator, bool OmitEmptySegments = false)
        {
            if (Text.Length == 0 || Separator.Length == 0)
            {
                return(new string[0]);
            }

            int SeparatorLength      = Separator.Length;
            int InitialPosition      = 0,
                FinalPosition        = 0;
            SimpleList <string> List = new SimpleList <string>();
            string Fragment          = "";

            while ((FinalPosition = Text.IndexOf(Separator, InitialPosition)) >= 0)
            {
                Fragment = Text.Substring(InitialPosition, (FinalPosition - InitialPosition));
                if (!OmitEmptySegments || Fragment.Length > 0)
                {
                    List.Add(Fragment);
                }
                InitialPosition = FinalPosition + SeparatorLength;
            }

            Fragment = Text.Substring(InitialPosition);
            if (!OmitEmptySegments || Fragment.Length > 0)
            {
                List.Add(Fragment);
            }

            return(List.GetArray());
        }
예제 #2
0
        // -------------------------------------------------------------------------------------------
        /// <summary>
        ///  Returns an array of bytes segments divided by a separator.
        /// </summary>
        public static byte[][] Segment(this byte[] TargetBlock, byte[] Separator)
        {
            if (TargetBlock.Length == 0 || Separator.Length == 0)
            {
                return(new byte[0][]);
            }

            int SeparatorLength = Separator.Length;
            int InitialPosition = 0, FinalPosition = 0;
            SimpleList <byte[]> SegmentsList = new SimpleList <byte[]>();

            while ((FinalPosition = Search(TargetBlock, Separator, InitialPosition)) >= 0)
            {
                SegmentsList.Add(ExtractSegment(TargetBlock, InitialPosition, (FinalPosition - InitialPosition)));
                InitialPosition = FinalPosition + SeparatorLength;
            }

            SegmentsList.Add(ExtractSegment(TargetBlock, InitialPosition));

            return(SegmentsList.GetArray());
        }
예제 #3
0
        // -------------------------------------------------------------------------------------------
        /// <summary>
        /// Gives, in a target byte array, another one readed from a stream, until consume a number of bytes or before some marks conformed by more than one byte.
        /// Return the index of the found mark or -1 if the consumable bytes limit was reached.
        /// </summary>
        private static int CaptureSegmentWithComplexStreamReader(ref byte[] TargetSegment, BinaryReader TorrentReader, int BytesNumberLimit,
                                                                 int MarksMaxLength, params byte[][] LimitMarks)
        {
            int CaptureEndingCause    = -1;
            int MarksCount            = LimitMarks.GetLength(0);
            SimpleList <byte[]> Parts = new SimpleList <byte[]>();

            byte[] Part = new byte[0];
            int    ConsumedBytesCount = 0;
            int    ConsumedBytesTotal = 0;
            int    FoundedPosition    = 0;
            int    Pos = 0;

            while ((ConsumedBytesCount = (Part = TorrentReader.ReadBytes(BLOCK_SIZE_TINY)).Length) > 0)
            {
                ConsumedBytesTotal += ConsumedBytesCount;
                Pos = -1;
                foreach (byte[] Mark in LimitMarks)
                {
                    Pos++;
                    if ((FoundedPosition = Search(Part, Mark)) >= 0)
                    {
                        CaptureEndingCause = Pos;
                        TorrentReader.BaseStream.Seek((Part.Length - (FoundedPosition + Mark.Length)) * -1, SeekOrigin.Current);
                        Part = ExtractSegment(Part, 0, FoundedPosition);
                        break;
                    }
                }

                if (FoundedPosition >= 0)
                {
                    Parts.Add(Part);
                    break;
                }

                if (ConsumedBytesTotal >= BytesNumberLimit)
                {
                    throw new UsageAnomaly("Stream has been readed/consumed until reach the " + BytesNumberLimit.ToString() + " bytes limit.",
                                           new DataWagon("ConsumedBytesCount", ConsumedBytesCount));
                }

                if (ConsumedBytesCount == BLOCK_SIZE_TINY)
                {
                    Part = ExtractSegment(Part, 0, Part.Length - MarksMaxLength);
                }

                Parts.Add(Part);

                // If less than the expected bytes were read, then means the stream's end was reached.
                if (ConsumedBytesCount < BLOCK_SIZE_TINY)
                {
                    break;
                }

                TorrentReader.BaseStream.Seek(MarksMaxLength * -1, SeekOrigin.Current);
            }

            TargetSegment = new byte[((BLOCK_SIZE_TINY - MarksMaxLength) * (Parts.Count - 1)) + Part.Length];
            Pos           = 0;
            foreach (byte[] Fragment in Parts)
            {
                CopyByteArray(TargetSegment, Fragment, Pos, (byte)0, false);
                Pos += Fragment.Length;
            }

            return(CaptureEndingCause);
        }
예제 #4
0
        // -------------------------------------------------------------------------------------------
        /// <summary>
        /// Gives, in a target byte array, another one readed from a stream, until consume a number of bytes or before some marks conformed by only one byte.
        /// Return the index of the found mark or -1 if the consumable bytes limit was reached.
        /// </summary>
        private static int CaptureSegmentWithSimpleStreamReader(ref byte[] TargetSegment, BinaryReader TorrentReader, int BytesNumberLimit,
                                                                params byte[][] LimitMarks)
        {
            int  CaptureEndingCause = -1;
            int  MarksCount         = LimitMarks.GetLength(0);
            int  Ind = 0;
            int  Pos = 0;
            int  ConsumedBytesCount = 0;
            bool FoundedMark        = false;
            byte Atom = 0;
            SimpleList <byte[]> Parts = new SimpleList <byte[]>();

            byte[] Part           = new byte[0];
            int    PartBytesCount = 0;

            Parts.Add(Part);

            try
            {
                while (ConsumedBytesCount < BytesNumberLimit)
                {
                    Atom = TorrentReader.ReadByte();
                    ConsumedBytesCount++;
                    FoundedMark = false;

                    for (Ind = 0; Ind < MarksCount; Ind++)
                    {
                        if (Atom == LimitMarks[Ind][0])
                        {
                            FoundedMark        = true;
                            CaptureEndingCause = Ind;
                            break;
                        }
                    }

                    if (FoundedMark)
                    {
                        break;
                    }

                    if (PartBytesCount == BLOCK_SIZE_TINY)
                    {
                        Part           = new byte[BLOCK_SIZE_TINY];
                        PartBytesCount = 0;
                        Parts.Add(Part);
                    }

                    Part[PartBytesCount] = Atom;
                    PartBytesCount++;
                }

                throw new UsageAnomaly("Stream has been readed/consumed until reach the " + BytesNumberLimit.ToString() + " bytes limit.",
                                       new DataWagon("ConsumedBytesCount", ConsumedBytesCount));
            }
#pragma warning disable 168
            catch (EndOfStreamException Anomaly)
            {   // The possible end of the stream is expected.
            };
#pragma warning restore 168

            TargetSegment = new byte[(BLOCK_SIZE_TINY * (Parts.Count - 1)) + PartBytesCount];
            Ind           = 0;
            Pos           = 0;
            foreach (byte[] Fragment in Parts)
            {
                Ind++;
                CopyByteArray(TargetSegment, (Ind < Parts.Count ? Fragment : BytesHandling.ExtractSegment(Fragment, 0, PartBytesCount)), Pos, (byte)0, false);
                Pos += BLOCK_SIZE_TINY;
            }

            return(CaptureEndingCause);
        }