public static bool EndsWithRaw(this Utf8Span str, Utf8Span value, StringComparison comparisonType = StringComparison.Ordinal)
 {
     if (str.Length() < value.Length())
     {
         return(false);
     }
     return(str.SubstringRaw(str.Length() - value.Length()).EqualsRaw(value, comparisonType));
 }
 public static Utf8Span TrimEndSimple(this Utf8Span str)
 {
     while (str.Length() != 0 && Utf8Utils.IsWhiteSpace(str.CharAt(str.Length() - 1)))
     {
         str = str.SubstringRaw(0, str.Length() - 1);
     }
     return(str);
 }
        private static int IndexOfRawCaseInsensitive(Utf8Span str, Utf8Span value)
        {
            var maxToCheck = str.Length() - value.Length();

            for (int i = 0; i <= maxToCheck; i++)
            {
                if (EqualsIgnoreCaseRaw(str.SubstringRaw(i, value.Length()), value))
                {
                    return(i);
                }
            }

            return(-1);
        }
        public static void Split(this Utf8Span this_, byte ch, StringSplitOptions options, ref Utf8SpanArray arr)
        {
            arr.data1 = this_;
            var removeEmpty = (options & StringSplitOptions.RemoveEmptyEntries) != 0;

            var index = 0;
            var pos   = 0;

            arr.count = 0;
            while (true)
            {
                var idx = this_.SubstringRaw(pos).IndexOfRaw(ch);
                if (idx == -1)
                {
                    break;
                }
                else
                {
                    idx += pos;
                }
                var length = idx != -1 ? idx - pos : this_.Length() - pos;
                if (!removeEmpty || length != 0)
                {
                    arr.Add(pos, length);
                    index++;
                }
                pos = idx + 1;
            }
            var last = this_.SubstringRaw(pos);

            if (!removeEmpty || last.Length() != 0)
            {
                arr.Add(pos, last.Length());
            }
        }
예제 #5
0
        public Utf8String Copy(Utf8Span source)
        {
            var v = Use(source.Length());

            source.Bytes.CopyTo(v);
            return(new Utf8String(v));
        }
 public static byte?TryCharAt(this Utf8Span str, int index)
 {
     if (index < 0 || index >= str.Length())
     {
         return(null);
     }
     return(str.CharAt(index));
 }
        public static Utf8Span CaptureAfter(this Utf8Span str, Utf8Span prefix, StringComparison comparisonType = StringComparison.Ordinal)
        {
            var start = str.IndexOfRaw(prefix, comparisonType);

            if (start == -1)
            {
                throw new InvalidDataException();
            }
            return(str.SubstringRaw(start + prefix.Length()));
        }
        public static Utf8Span TryCaptureAfter(this Utf8Span str, Utf8Span prefix, StringComparison comparisonType = StringComparison.Ordinal)
        {
            var start = str.IndexOfRaw(prefix, comparisonType);

            if (start == -1)
            {
                return(Utf8Span.Empty);
            }
            return(str.SubstringRaw(start + prefix.Length()));
        }
 public static int LastIndexOfRaw(this Utf8Span str, byte value)
 {
     for (int i = str.Length() - 1; i >= 0; i--)
     {
         if (str.CharAt(i) == value)
         {
             return(i);
         }
     }
     return(-1);
 }
 public static ulong ParseUInt64(Utf8Span str)
 {
     if (!Utf8Parser.TryParseUInt64(str.Bytes, out var value, out var consumed))
     {
         throw new FormatException();
     }
     if (consumed != str.Length())
     {
         throw new FormatException();
     }
     return(value);
 }
 public static int ParseInt32(Utf8Span str)
 {
     if (!Utf8Parser.TryParseInt32(str, out var value, out var consumed))
     {
         throw new FormatException();
     }
     if (consumed != str.Length())
     {
         throw new FormatException();
     }
     return(value);
 }
 public static DateTime ParseDateSeparated(Utf8Span date)
 {
     if (date.Length() != 19)
     {
         throw new FormatException();
     }
     return(new DateTime(
                ParseInt32(date.SubstringRaw(0, 4)),
                ParseInt32(date.SubstringRaw(5, 2)),
                ParseInt32(date.SubstringRaw(8, 2)),
                ParseInt32(date.SubstringRaw(11, 2)),
                ParseInt32(date.SubstringRaw(14, 2)),
                ParseInt32(date.SubstringRaw(17, 2)),
                DateTimeKind.Utc
                ));
 }
 public static DateTime ParseDateConcatenated(Utf8Span date)
 {
     if (date.Length() != 14)
     {
         throw new FormatException();
     }
     return(new DateTime(
                ParseInt32(date.SubstringRaw(0, 4)),
                ParseInt32(date.SubstringRaw(4, 2)),
                ParseInt32(date.SubstringRaw(6, 2)),
                ParseInt32(date.SubstringRaw(8, 2)),
                ParseInt32(date.SubstringRaw(10, 2)),
                ParseInt32(date.SubstringRaw(12, 2)),
                DateTimeKind.Utc
                ));
 }
        public static Utf8Span TryCaptureBetween(this Utf8Span str, Utf8Span before, Utf8Span after, StringComparison comparisonType = StringComparison.Ordinal)
        {
            var start = str.IndexOfRaw(before, comparisonType);

            if (start == -1)
            {
                return(Utf8Span.Empty);
            }
            str = str.SubstringRaw(start + before.Length());
            var end = str.IndexOfRaw(after, comparisonType);

            if (end == -1)
            {
                return(Utf8Span.Empty);
            }
            return(str.SubstringRaw(0, end));
        }
        public static Utf8Span CaptureBetween(this Utf8Span str, Utf8Span before, Utf8Span after, StringComparison comparisonType = StringComparison.Ordinal)
        {
            var start = str.IndexOfRaw(before, comparisonType);

            if (start == -1)
            {
                throw new InvalidDataException();
            }
            str = str.SubstringRaw(start + before.Length());
            var end = str.IndexOfRaw(after, comparisonType);

            if (end == -1)
            {
                throw new InvalidDataException();
            }
            return(str.SubstringRaw(0, end));
        }
        private static bool EqualsIgnoreCaseRaw(Utf8Span str, Utf8Span str2)
        {
            if (str.Length() != str2.Length())
            {
                return(false);
            }
            var a = str.Bytes;
            var b = str2.Bytes;

            for (int i = 0; i < a.Length; i++)
            {
                if (!EqualsIgnoreCaseRaw(a[i], b[i]))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #17
0
        public static string ToStringCached(this Utf8Span utf8)
        {
            if (utf8.IsEmpty)
            {
                return(string.Empty);
            }
            var utf8length = utf8.Length();
            int hash       = CalculateHash(utf8.CharAt(0), utf8.CharAt(utf8length / 2), utf8.CharAt(utf8length - 1), utf8length);

            if (cache == null)
            {
                cache = new CacheSlot[6841];
            }
            CacheSlot cacheSlot = cache[hash];
            var       list      = cacheSlot.List;

            if (list == null)
            {
                cacheSlot.List = list = new CacheEntry[6];
            }


            for (int i = 0; i < list.Length; i++)
            {
                var entry = list[i];
                if (entry.String == null)
                {
                    break;
                }
                if (entry.Span.SequenceEqual(utf8.Bytes))
                {
                    return(entry.String);
                }
            }

            lock (lockObj)
            {
                var entry = new CacheEntry();
                entry.Length = utf8length;
                entry.String = utf8.ToString();

                if (usedScratchpadBytes + utf8length <= scratchpad.Length)
                {
                    utf8.Bytes.CopyTo(scratchpad.Slice(usedScratchpadBytes));
                    entry.Bytes          = scratchpad;
                    entry.Offset         = usedScratchpadBytes;
                    usedScratchpadBytes += utf8length;
                }
                else
                {
                    scratchpad = new byte[Math.Max(scratchpad.Length, utf8length * 2)];
                    utf8.Bytes.CopyTo(scratchpad);
                    entry.Bytes         = scratchpad;
                    entry.Offset        = 0;
                    usedScratchpadBytes = utf8length;
                }

                cacheSlot.List[cacheSlot.NextItemToReplace] = entry;
                cacheSlot.NextItemToReplace = (cacheSlot.NextItemToReplace + 1) % cacheSlot.List.Length;

                cache[hash] = cacheSlot;
                return(entry.String);
            }
        }
 public static bool TryParseUInt64(Utf8Span str, out ulong val)
 {
     if (!Utf8Parser.TryParseUInt64(str, out val, out var consumed) || consumed != str.Length())
     {
         return(false);
     }
     return(true);
 }
예제 #19
0
/*
 *      internal static bool IsWhiteSpace(Utf8Span str)
 *      {
 *          str.Trim()
 *          if (str.Length == 0) return true;
 *          for (int i = 0; i < str.Length; i++)
 *          {
 *              if (Utf8Span.IsWhiteSpace(str[i])) return false;
 *          }
 *          return true;
 *      }
 */
        private unsafe int FindSeparator(Utf8Span haystack, Utf8String[] separator, out int foundSeparator)
        {
            foundSeparator = 0;
            if (separator.Length == 1)
            {
                var sep = separator[0];
                if (sep.Length() == 1)
                {
                    return(haystack.IndexOfRaw(sep.CharAt(0)));
                }
                else
                {
                    return(haystack.IndexOfRaw(sep));
                }
            }
            else
            {
                byte *charMap = stackalloc byte[32];
                InitializeProbabilisticMap(charMap, separator);


                //ref byte pCh = ref haystack.Bytes.DangerousGetPinnableReference();
                //var charthere = haystack.Bytes[0];
                //var fond = pCh;

                for (int i = 0; i < haystack.Length(); i++)
                {
                    //byte thisChar = Unsafe.Add<byte>(ref pCh, i);
                    byte thisChar = haystack.CharAt(i);

                    if (ProbablyContains(charMap, thisChar))
                    {
                        var substr = new Utf8Span(haystack.Bytes.Slice(i));
                        for (int j = 0; j < separator.Length; j++)
                        {
                            if (substr.StartsWith(separator[j]))
                            {
                                foundSeparator = j;
                                return(i);
                            }
                        }
                        //if (ArrayContains(thisChar, anyOf) >= 0)
                        //return i;
                    }
                }



                /*
                 * var maxlen = 0;
                 * for (int i = 0; i < separator.Length; i++)
                 * {
                 *  maxlen = Math.Max(maxlen, separator[i].Length);
                 * }
                 *
                 *
                 * int expected = -1;
                 * for (int i = 0; i < haystack.Length; i++)
                 * {
                 *  var substr = new Utf8Span(haystack.Bytes.Slice(i));
                 *  for (int j = 0; j < separator.Length; j++)
                 *  {
                 *      if (substr.StartsWith(separator[j]))
                 *      {
                 *          expected = i;
                 *          break;
                 *      }
                 *  }
                 *  if (expected != -1) break;
                 * }
                 *
                 *
                 * var min = int.MaxValue;
                 * var minsep = -1;
                 * const int STEP_SIZE = 100;
                 * for (int j = 0; j < haystack.Length; j += STEP_SIZE)
                 * {
                 *
                 *  var subhaystack = haystack.Substring(j, Math.Min(STEP_SIZE + maxlen, haystack.Length - j));
                 *  for (int i = 0; i < separator.Length; i++)
                 *  {
                 *      var pos = subhaystack.IndexOf(separator[i]);
                 *      if (pos != -1)
                 *      {
                 *          if (pos < min)
                 *          {
                 *              min = pos;
                 *              minsep = i;
                 *              subhaystack = subhaystack.Substring(0, Math.Min(min + maxlen, subhaystack.Length));
                 *          }
                 *      }
                 *  }
                 *
                 * //#if DEBUG
                 * //                    if (minsep != -1)
                 * //                    {
                 * //                        foundSeparator = minsep;
                 * //                        var v = j + min;
                 * //                        Debug.Assert(expected == v);
                 * //                        return v;
                 * //                    }
                 * //#endif
                 * }
                 *
                 */



                return(-1);
            }
        }
예제 #20
0
        public Utf8Span ReadTo(Utf8String[] separator, out int foundSeparator)
        {
tryagain:
            if (isCompleted)
            {
                throw new EndOfStreamException();
            }
            if (hasPendingEmptyString)
            {
                foundSeparator = -1;
                isCompleted    = true;
                return(Utf8Span.Empty);
            }
            var bufferview = new Utf8Span(buffer);

            var haystack = new Utf8Span(buffer.Slice(bufferStart, bufferDataLength - bufferStart));
            var lf       = FindSeparator(haystack, separator, out foundSeparator);

            if (lf != -1)
            {
                var u     = new Utf8Span(buffer.Slice(bufferStart, lf));
                var delta = lf + separator[foundSeparator].Length();
                position             += delta;
                bufferStart          += delta;
                hasPendingEmptyString = isEndOfStream && bufferStart == bufferDataLength;

                return(u);
            }
            else
            {
                if (isEndOfStream)
                {
                    isCompleted    = true;
                    foundSeparator = -1;
                    var delta = bufferDataLength - bufferStart;
                    position += delta;
                    return(new Utf8Span(buffer.Slice(bufferStart, delta)));
                }
                var tocopy = bufferFullSize - bufferStart;
                Array.Copy(buffer, bufferFullSize - tocopy, buffer, bufferHalfSize - tocopy, tocopy);
                FillBuffer();

                var start = bufferHalfSize - tocopy;
                haystack = new Utf8Span(buffer.Slice(start, bufferDataLength - start));
                lf       = FindSeparator(haystack, separator, out foundSeparator);

                if (lf != -1)
                {
                    var delta = lf + separator[foundSeparator].Length();
                    position   += delta;
                    bufferStart = start + delta;
                    var u = new Utf8Span(buffer.Slice(start, lf));
                    hasPendingEmptyString = isEndOfStream && bufferStart == bufferDataLength;

                    return(u);
                }
                else
                {
                    var u = new Utf8Span(buffer.Slice(start, bufferDataLength - start));
                    if (isEndOfStream)
                    {
                        isCompleted = true;
                        position   += u.Length();
                        return(u);
                    }
                    else
                    {
                        var newbuffer  = new byte[bufferFullSize * 2];
                        var datalength = bufferDataLength - bufferHalfSize + tocopy;
                        Array.Copy(buffer, start, newbuffer, bufferFullSize, datalength);
                        var newview = new Utf8Span(newbuffer);
                        bufferDataLength = bufferFullSize + datalength;
                        bufferFullSize  *= 2;
                        bufferHalfSize  *= 2;
                        this.buffer      = newbuffer;

                        FillBuffer(bufferDataLength);

                        bufferStart = bufferHalfSize;
                        goto tryagain;
                    }
                }
            }
        }