コード例 #1
0
 public static bool TryFormat(this long value, Span <byte> buffer, Format.Parsed format, FormattingData formattingData, out int bytesWritten)
 {
     return(IntegerFormatter.TryFormatInt64(value, 8, buffer, format, formattingData, out bytesWritten));
 }
コード例 #2
0
        public static bool TryFormat(this Guid value, Span<byte> buffer, Format.Parsed format, FormattingData formattingData, out int bytesWritten)
        {
            if (format.IsDefault)
            {
                format.Symbol = 'G';
            }
            Precondition.Require(format.Symbol == 'G' || format.Symbol == 'D' || format.Symbol == 'N' || format.Symbol == 'B' || format.Symbol == 'P');
            bool dash = true;
            char tail = '\0';
            bytesWritten = 0;

            switch (format.Symbol)
            {
                case 'D':
                case 'G':
                    break;

                case 'N':
                    dash = false;
                    break;

                case 'B':
                    if (!TryWriteChar('{', buffer, formattingData, ref bytesWritten)) { return false; }
                    tail = '}';
                    break;

                case 'P':
                    if (!TryWriteChar('(', buffer, formattingData, ref bytesWritten)) { return false; }
                    tail = ')';
                    break;

                default:
                    Precondition.Require(false); // how did we get here? 
                    break;
            }


            var byteFormat = new Format.Parsed('x', 2);
            unsafe
            {
                byte* bytes = (byte*)&value;

                if (!TryWriteByte(bytes[3], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[2], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[1], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[0], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }

                if (dash)
                {
                    if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; }
                }

                if (!TryWriteByte(bytes[5], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[4], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }

                if (dash)
                {
                    if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; }
                }

                if (!TryWriteByte(bytes[7], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[6], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }

                if (dash)
                {
                    if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; }
                }

                if (!TryWriteByte(bytes[8], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[9], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }

                if (dash)
                {
                    if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; }
                }

                if (!TryWriteByte(bytes[10], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[11], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[12], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[13], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[14], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[15], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; }
            }

            if (tail != '\0')
            {
                if (!TryWriteChar(tail, buffer, formattingData, ref bytesWritten)) { return false; }
            }

            return true;
        }
コード例 #3
0
        public static bool TryFormat(this string value, Span <byte> buffer, Format.Parsed format, FormattingData formattingData, out int bytesWritten)
        {
            var byteSpan = buffer.BorrowDisposableByteSpan();

            try
            {
                var avaliableBytes = byteSpan.Length;

                if (formattingData.IsUtf16)
                {
                    var neededBytes = value.Length << 1;
                    if (neededBytes > avaliableBytes)
                    {
                        bytesWritten = 0;
                        return(false);
                    }

                    unsafe
                    {
                        fixed(char *pCharacters = value)
                        {
                            byte *pBytes = (byte *)pCharacters;

                            byteSpan.Set(pBytes, neededBytes);
                        }
                    }

                    bytesWritten = neededBytes;
                    return(true);
                }

                bytesWritten = 0;
                for (int i = 0; i < value.Length; i++)
                {
                    var c = value[i];

                    var codepoint = (ushort)c;
                    if (codepoint <= 0x7f) // this if block just optimizes for ascii
                    {
                        if (bytesWritten + 1 > avaliableBytes)
                        {
                            bytesWritten = 0;
                            return(false);
                        }
                        byteSpan[bytesWritten++] = (byte)codepoint;
                    }
                    else
                    {
                        var encoded = new Utf8Helpers.FourBytes();
                        var bytes   = Utf8Helpers.CharToUtf8(c, ref encoded);

                        if (bytesWritten + bytes > avaliableBytes)
                        {
                            bytesWritten = 0;
                            return(false);
                        }

                        byteSpan[bytesWritten] = encoded.B0;
                        if (bytes > 1)
                        {
                            byteSpan[+bytesWritten + 1] = encoded.B1;

                            if (bytes > 2)
                            {
                                byteSpan[+bytesWritten + 2] = encoded.B2;

                                if (bytes > 3)
                                {
                                    byteSpan[+bytesWritten + 3] = encoded.B3;
                                }
                            }
                        }

                        bytesWritten += bytes;
                    }
                }
                return(true);
            }
            finally
            {
                byteSpan.Free();
            }
        }
コード例 #4
0
 public static bool TryFormat(this DateTime value, Span <byte> buffer, ReadOnlySpan <char> format, FormattingData formattingData, out int bytesWritten)
 {
     Format.Parsed parsedFormat = Format.Parse(format);
     return(TryFormat(value, buffer, parsedFormat, formattingData, out bytesWritten));
 }
コード例 #5
0
        private static bool TryFormatTimeSpanG(TimeSpan value, Span <byte> buffer, Format.Parsed format, FormattingData formattingData, out int bytesWritten)
        {
            bytesWritten = 0;

            if (value.Ticks < 0)
            {
                if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten))
                {
                    return(false);
                }
            }

            bool daysWritten = false;

            if (value.Days != 0 || format.Symbol == 'G')
            {
                if (!TryWriteInt32(Abs(value.Days), buffer, default(Format.Parsed), formattingData, ref bytesWritten))
                {
                    return(false);
                }
                daysWritten = true;
                if (format.Symbol == 'c')
                {
                    if (!TryWriteChar('.', buffer, formattingData, ref bytesWritten))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten))
                    {
                        return(false);
                    }
                }
            }

            var hourFormat = default(Format.Parsed);

            if ((daysWritten || format.Symbol == 'c') && format.Symbol != 'g')
            {
                hourFormat = D2;
            }
            if (!TryWriteInt32(Abs(value.Hours), buffer, hourFormat, formattingData, ref bytesWritten))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten))
            {
                return(false);
            }

            if (!TryWriteInt32(Abs(value.Minutes), buffer, D2, formattingData, ref bytesWritten))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten))
            {
                return(false);
            }

            if (!TryWriteInt32(Abs(value.Seconds), buffer, D2, formattingData, ref bytesWritten))
            {
                return(false);
            }

            long remainingTicks;

            if (value.Ticks != long.MinValue)
            {
                remainingTicks = Abs(value.Ticks) % TimeSpan.TicksPerSecond;
            }
            else
            {
                remainingTicks = long.MaxValue % TimeSpan.TicksPerSecond;
                remainingTicks = (remainingTicks + 1) % TimeSpan.TicksPerSecond;
            }

            var ticksFormat = D7;

            if (remainingTicks != 0)
            {
                if (!TryWriteChar('.', buffer, formattingData, ref bytesWritten))
                {
                    return(false);
                }
                var fraction = remainingTicks * FractionalTimeScale / TimeSpan.TicksPerSecond;
                if (!TryWriteInt64(fraction, buffer, ticksFormat, formattingData, ref bytesWritten))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #6
0
        public static bool TryFormat(this string value, Span <byte> buffer, Format.Parsed format, FormattingData formattingData, out int bytesWritten)
        {
            if (formattingData.IsUtf16)
            {
                var valueBytes = value.Length << 1;
                if (valueBytes > buffer.Length)
                {
                    bytesWritten = 0;
                    return(false);
                }

                unsafe
                {
                    fixed(char *pCharacters = value)
                    {
                        byte *pBytes = (byte *)pCharacters;

                        buffer.Set(pBytes, valueBytes);
                    }
                }

                bytesWritten = valueBytes;
                return(true);
            }


            var avaliableBytes = buffer.Length;

            bytesWritten = 0;
            for (int i = 0; i < value.Length; i++)
            {
                var c = value[i];

                var codepoint = (ushort)c;
                if (codepoint <= 0x7f) // this if block just optimizes for ascii
                {
                    if (bytesWritten + 1 > avaliableBytes)
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    buffer[bytesWritten++] = (byte)codepoint;
                }
                else
                {
                    Utf8EncodedCodePoint encoded;
                    if (!char.IsSurrogate(c))
                    {
                        encoded = new Utf8EncodedCodePoint(c);
                    }
                    else
                    {
                        if (++i >= value.Length)
                        {
                            throw new ArgumentException("Invalid surrogate pair.", nameof(value));
                        }
                        char lowSurrogate = value[i];
                        encoded = new Utf8EncodedCodePoint(c, lowSurrogate);
                    }


                    if (bytesWritten + encoded.Length > avaliableBytes)
                    {
                        bytesWritten = 0;
                        return(false);
                    }

                    buffer[bytesWritten] = encoded.Byte0;
                    if (encoded.Length > 1)
                    {
                        buffer[bytesWritten + 1] = encoded.Byte1;

                        if (encoded.Length > 2)
                        {
                            buffer[bytesWritten + 2] = encoded.Byte2;

                            if (encoded.Length > 3)
                            {
                                buffer[bytesWritten + 3] = encoded.Byte3;
                            }
                        }
                    }

                    bytesWritten += encoded.Length;
                }
            }
            return(true);
        }
コード例 #7
0
        static void AppendUntyped <TFormatter, T>(this TFormatter formatter, T value, Format.Parsed format) where TFormatter : IFormatter
        {
            #region Built in types
            var i32 = value as int?;
            if (i32 != null)
            {
                formatter.Append(i32.Value, format);
                return;
            }
            var i64 = value as long?;
            if (i64 != null)
            {
                formatter.Append(i64.Value, format);
                return;
            }
            var i16 = value as short?;
            if (i16 != null)
            {
                formatter.Append(i16.Value, format);
                return;
            }
            var b = value as byte?;
            if (b != null)
            {
                formatter.Append(b.Value, format);
                return;
            }
            var c = value as char?;
            if (c != null)
            {
                formatter.Append(c.Value, format);
                return;
            }
            var u32 = value as uint?;
            if (u32 != null)
            {
                formatter.Append(u32.Value, format);
                return;
            }
            var u64 = value as ulong?;
            if (u64 != null)
            {
                formatter.Append(u64.Value, format);
                return;
            }
            var u16 = value as ushort?;
            if (u16 != null)
            {
                formatter.Append(u16.Value, format);
                return;
            }
            var sb = value as sbyte?;
            if (sb != null)
            {
                formatter.Append(sb.Value, format);
                return;
            }
            var str = value as string;
            if (str != null)
            {
                formatter.Append(str, format);
                return;
            }
            var dt = value as DateTime?;
            if (dt != null)
            {
                formatter.Append(dt.Value, format);
                return;
            }
            var ts = value as TimeSpan?;
            if (ts != null)
            {
                formatter.Append(ts.Value, format);
                return;
            }
            #endregion

            if (value is IBufferFormattable)
            {
                formatter.Append((IBufferFormattable)value, format); // this is boxing. not sure how to avoid it.
                return;
            }

            throw new NotSupportedException("value is not formattable.");
        }