Esempio n. 1
0
 public static string Get_Location(DataConsumer <char> Stream)
 {
     return(Stream.AsMemory().Slice((int)Stream.LongPosition, 32).ToString());
 }
Esempio n. 2
0
        public static byte[] Percent_Decode(ReadOnlyMemory <byte> input)
        {/* Docs: https://url.spec.whatwg.org/#percent-decode */
            DataConsumer <byte> Stream = new DataConsumer <byte>(input, byte.MinValue);
            /* Create a list of memory chunks that make up the final string */
            ulong newLength  = 0;
            ulong?chunkStart = null;
            ulong chunkCount = 0;
            var   chunks     = new LinkedList <Tuple <ReadOnlyMemory <byte>, byte?> >();

            while (!Stream.atEnd)
            {
                EFilterResult filterResult = EFilterResult.FILTER_ACCEPT;
                byte?         bytePoint    = null;

                if (Stream.Next == CHAR_PERCENT && Is_Ascii_Hex_Digit((char)Stream.NextNext) && Is_Ascii_Hex_Digit((char)Stream.NextNextNext))
                {
                    filterResult = EFilterResult.FILTER_SKIP;
                    uint low  = (uint)Ascii_Hex_To_Value((char)Stream.NextNext);
                    uint high = (uint)Ascii_Hex_To_Value((char)Stream.NextNextNext);
                    bytePoint = (byte)(low | (high >> 4));
                    Stream.Consume(2);
                    break;
                }

                /* When filter result:
                 * ACCEPT: Char should be included in chunk
                 * SKIP: Char should not be included in chunk, if at chunk-start shift chunk-start past char, otherwise end chunk
                 * REJECT: Char should not be included in chunk, current chunk ends
                 */
                bool end_chunk = false;
                switch (filterResult)
                {
                case EFilterResult.FILTER_ACCEPT:    // Char should be included in the chunk
                {
                    if (!chunkStart.HasValue)
                    {
                        chunkStart = Stream.LongPosition;                              /* Start new chunk (if one isnt started yet) */
                    }
                }
                break;

                case EFilterResult.FILTER_REJECT:    // Char should not be included in chunk, current chunk ends
                {
                    end_chunk = true;
                }
                break;

                case EFilterResult.FILTER_SKIP:    // Char should not be included in chunk, if at chunk-start shift chunk-start past char, otherwise end chunk
                {
                    if (!chunkStart.HasValue)
                    {
                        chunkStart = Stream.LongPosition + 1;        /* At chunk-start */
                    }
                    else
                    {
                        end_chunk = true;
                    }
                }
                break;
                }

                if (end_chunk || Stream.Remaining <= 1)
                {
                    if (!chunkStart.HasValue)
                    {
                        chunkStart = Stream.LongPosition;
                    }

                    /* Push new chunk to our list */
                    var chunkSize = Stream.LongPosition - chunkStart.Value;
                    var Mem       = Stream.AsMemory().Slice((int)chunkStart.Value, (int)chunkSize);
                    var chunk     = new Tuple <ReadOnlyMemory <byte>, byte?>(Mem, bytePoint);
                    chunks.AddLast(chunk);

                    chunkCount++;
                    chunkStart = null;
                    newLength += chunkSize;
                    /* If we actually decoded a byte then account for it in the newLength */
                    if (filterResult != EFilterResult.FILTER_ACCEPT)
                    {
                        newLength++;
                    }
                }

                Stream.Consume();
            }

            /* Compile the string */
            var           dataPtr = new byte[newLength];
            Memory <byte> data    = new Memory <byte>(dataPtr);

            ulong index = 0;

            foreach (var tpl in chunks)
            {
                var chunk = tpl.Item1;
                /* Copy chunk data */
                chunk.CopyTo(data.Slice((int)index));
                index += (ulong)chunk.Length;

                if (tpl.Item2.HasValue)
                {
                    data.Span[(int)index] = tpl.Item2.Value;
                    index++;
                }
            }

            return(dataPtr);
        }