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()); } }
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); }
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); }
/* * 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); } }
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; } } } }