public static ReadOnlySpan <char> Unescape(ReadOnlySpan <char> input, bool removeQuotes, char quoteChar) { var length = input.Length; int start = 0; int count = 0; var output = StringBuilderThreadStatic.Allocate(); for (; count < length;) { var c = input[count]; if (removeQuotes) { if (c == quoteChar) { if (start != count) { output.Append(input.Slice(start, count - start)); } count++; start = count; continue; } } if (c == JsonUtils.EscapeChar) { if (start != count) { output.Append(input.Slice(start, count - start)); } start = count; count++; if (count >= length) { continue; } //we will always be parsing an escaped char here c = input[count]; switch (c) { case 'a': output.Append('\a'); count++; break; case 'b': output.Append('\b'); count++; break; case 'f': output.Append('\f'); count++; break; case 'n': output.Append('\n'); count++; break; case 'r': output.Append('\r'); count++; break; case 'v': output.Append('\v'); count++; break; case 't': output.Append('\t'); count++; break; case 'u': if (count + 4 < length) { var unicodeString = input.Slice(count + 1, 4); var unicodeIntVal = MemoryProvider.Instance.ParseUInt32(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 5; } else { output.Append(c); } break; case 'x': if (count + 4 < length) { var unicodeString = input.Slice(count + 1, 4); var unicodeIntVal = MemoryProvider.Instance.ParseUInt32(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 5; } else if (count + 2 < length) { var unicodeString = input.Slice(count + 1, 2); var unicodeIntVal = MemoryProvider.Instance.ParseUInt32(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 3; } else { output.Append(input.Slice(start, count - start)); } break; default: output.Append(c); count++; break; } start = count; } else { count++; } } output.Append(input.Slice(start, length - start)); return(StringBuilderThreadStatic.ReturnAndFree(output).AsSpan()); }
public static StringSegment Unescape(StringSegment input, bool removeQuotes) { var length = input.Length; int start = 0; int count = 0; var output = StringBuilderThreadStatic.Allocate(); for (; count < length;) { if (removeQuotes) { if (input.GetChar(count) == JsonUtils.QuoteChar) { if (start != count) { output.Append(input.Buffer, input.Offset + start, count - start); } count++; start = count; continue; } } if (input.GetChar(count) == JsonUtils.EscapeChar) { if (start != count) { output.Append(input.Buffer, input.Offset + start, count - start); } start = count; count++; if (count >= length) { continue; } //we will always be parsing an escaped char here var c = input.GetChar(count); switch (c) { case 'a': output.Append('\a'); count++; break; case 'b': output.Append('\b'); count++; break; case 'f': output.Append('\f'); count++; break; case 'n': output.Append('\n'); count++; break; case 'r': output.Append('\r'); count++; break; case 'v': output.Append('\v'); count++; break; case 't': output.Append('\t'); count++; break; case 'u': if (count + 4 < length) { var unicodeString = input.Substring(count + 1, 4); var unicodeIntVal = UInt32.Parse(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 5; } else { output.Append(c); } break; case 'x': if (count + 4 < length) { var unicodeString = input.Substring(count + 1, 4); var unicodeIntVal = uint.Parse(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 5; } else if (count + 2 < length) { var unicodeString = input.Substring(count + 1, 2); var unicodeIntVal = uint.Parse(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 3; } else { output.Append(input.Buffer, input.Offset + start, count - start); } break; default: output.Append(c); count++; break; } start = count; } else { count++; } } output.Append(input.Buffer, input.Offset + start, length - start); return(new StringSegment(StringBuilderThreadStatic.ReturnAndFree(output))); }
/// <summary> /// Converts to xsdduration. /// </summary> /// <param name="timeSpan">The time span.</param> /// <returns>System.String.</returns> public static string ToXsdDuration(TimeSpan timeSpan) { if (timeSpan == TimeSpan.MinValue) { return(MinSerializedValue); } if (timeSpan == TimeSpan.MaxValue) { return(MaxSerializedValue); } var sb = StringBuilderThreadStatic.Allocate(); sb.Append(timeSpan.Ticks < 0 ? "-P" : "P"); double ticks = timeSpan.Ticks; if (ticks < 0) { ticks = -ticks; } double totalSeconds = ticks / TimeSpan.TicksPerSecond; long wholeSeconds = (long)totalSeconds; long seconds = wholeSeconds; long sec = seconds >= 60 ? seconds % 60 : seconds; long min = (seconds = seconds / 60) >= 60 ? seconds % 60 : seconds; long hours = (seconds = seconds / 60) >= 24 ? seconds % 24 : seconds; long days = seconds / 24; double remainingSecs = sec + (totalSeconds - wholeSeconds); if (days > 0) { sb.Append(days + "D"); } if (days == 0 || hours + min + sec + remainingSecs > 0) { sb.Append("T"); if (hours > 0) { sb.Append(hours + "H"); } if (min > 0) { sb.Append(min + "M"); } if (remainingSecs > 0) { var secFmt = string.Format(CultureInfo.InvariantCulture, "{0:0.0000000}", remainingSecs); secFmt = secFmt.TrimEnd('0').TrimEnd('.'); sb.Append(secFmt + "S"); } else if (sb.Length == 2) //PT { sb.Append("0S"); } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }