예제 #1
0
        A ISubTypeSerializer <A> .ReadSubType(ref ProtoReader.State state, SubTypeState <A> value)
        {
            int field;

            value.OnBeforeDeserialize((obj, ctx) => obj.OnBeforeDeserialize());
            while ((field = state.ReadFieldHeader()) != 0)
            {
                switch (field)
                {
                case 1:
                    value.Value.AVal = state.ReadInt32();
                    break;

                case 4:
                    value.ReadSubType <B>(ref state, this);
                    break;

                default:
                    state.SkipField();
                    break;
                }
            }
            value.Value.OnAfterDeserialize();
            return(value.Value);
        }
예제 #2
0
        /// <summary>
        /// Parses a decimal from a protobuf stream
        /// </summary>
        public static decimal ReadDecimal(ProtoReader reader, ref ProtoReader.State state)
        {
            ulong low       = 0;
            uint  high      = 0;
            uint  signScale = 0;

            int          fieldNumber;
            SubItemToken token = ProtoReader.StartSubItem(reader, ref state);

            while ((fieldNumber = reader.ReadFieldHeader(ref state)) > 0)
            {
                switch (fieldNumber)
                {
                case FieldDecimalLow: low = reader.ReadUInt64(ref state); break;

                case FieldDecimalHigh: high = reader.ReadUInt32(ref state); break;

                case FieldDecimalSignScale: signScale = reader.ReadUInt32(ref state); break;

                default: reader.SkipField(ref state); break;
                }
            }
            ProtoReader.EndSubItem(token, reader, ref state);

            int lo     = (int)(low & 0xFFFFFFFFL),
                mid    = (int)((low >> 32) & 0xFFFFFFFFL),
                hi     = (int)high;
            bool isNeg = (signScale & 0x0001) == 0x0001;
            byte scale = (byte)((signScale & 0x01FE) >> 1);

            return(new decimal(lo, mid, hi, isNeg, scale));
        }
예제 #3
0
        private static TimeSpan ReadDurationFallback(ProtoReader source, ref ProtoReader.State state)
        {
            long         seconds = 0;
            int          nanos   = 0;
            SubItemToken token   = ProtoReader.StartSubItem(source, ref state);
            int          fieldNumber;

            while ((fieldNumber = source.ReadFieldHeader(ref state)) > 0)
            {
                switch (fieldNumber)
                {
                case 1:
                    seconds = source.ReadInt64(ref state);
                    break;

                case 2:
                    nanos = source.ReadInt32(ref state);
                    break;

                default:
                    source.SkipField(ref state);
                    break;
                }
            }
            ProtoReader.EndSubItem(token, source, ref state);
            return(FromDurationSeconds(seconds, nanos));
        }
예제 #4
0
 /// <summary>
 /// Parses a DateTime from a protobuf stream using the standardized format, google.protobuf.Timestamp
 /// </summary>
 public static DateTime ReadTimestamp(ProtoReader source, ref ProtoReader.State state)
 {
     // note: DateTime is only defined for just over 0000 to just below 10000;
     // TimeSpan has a range of +/- 10,675,199 days === 29k years;
     // so we can just use epoch time delta
     return(TimestampEpoch + ReadDuration(source, ref state));
 }
예제 #5
0
 /// <summary>
 /// Parses a TimeSpan from a protobuf stream using the standardized format, google.protobuf.Duration
 /// </summary>
 public static TimeSpan ReadDuration(ProtoReader source, ref ProtoReader.State state)
 {
     if (source.WireType == WireType.String && state.RemainingInCurrent >= 20)
     {
         var ts = TryReadDurationFast(source, ref state);
         if (ts.HasValue)
         {
             return(ts.GetValueOrDefault());
         }
     }
     return(ReadDurationFallback(source, ref state));
 }
예제 #6
0
        /// <summary>
        /// Parses a DateTime from a protobuf stream
        /// </summary>
        public static DateTime ReadDateTime(ProtoReader source, ref ProtoReader.State state)
        {
            long ticks = ReadTimeSpanTicks(source, ref state, out DateTimeKind kind);

            if (ticks == long.MinValue)
            {
                return(DateTime.MinValue);
            }
            if (ticks == long.MaxValue)
            {
                return(DateTime.MaxValue);
            }
            return(EpochOrigin[(int)kind].AddTicks(ticks));
        }
예제 #7
0
        /// <summary>
        /// Parses a TimeSpan from a protobuf stream using protobuf-net's own representation, bcl.TimeSpan
        /// </summary>
        public static TimeSpan ReadTimeSpan(ProtoReader source, ref ProtoReader.State state)
        {
            long ticks = ReadTimeSpanTicks(source, ref state, out DateTimeKind kind);

            if (ticks == long.MinValue)
            {
                return(TimeSpan.MinValue);
            }
            if (ticks == long.MaxValue)
            {
                return(TimeSpan.MaxValue);
            }
            return(TimeSpan.FromTicks(ticks));
        }
예제 #8
0
        public static TimeSpan ReadTimeSpan(ref ProtoReader.State state)
        {
            switch (state.WireType)
            {
            case WireType.String:
            case WireType.StartGroup:
                var scaled = state.ReadMessage <ScaledTicks>(default, default, serializer: SerializerCache <PrimaryTypeProvider> .InstanceField);
                return(scaled.ToTimeSpan());

            case WireType.Fixed64:
                long ticks = state.ReadInt64();
                return(ticks switch
                {
                    long.MinValue => TimeSpan.MinValue,
                    long.MaxValue => TimeSpan.MaxValue,
                    _ => TimeSpan.FromTicks(ticks),
                });
예제 #9
0
        C ISubTypeSerializer <C> .ReadSubType(ref ProtoReader.State state, SubTypeState <C> value)
        {
            int field;

            while ((field = state.ReadFieldHeader()) != 0)
            {
                switch (field)
                {
                case 3:
                    value.Value.CVal = state.ReadInt32();
                    break;

                default:
                    state.SkipField();
                    break;
                }
            }
            return(value.Value);
        }
예제 #10
0
        private static TimeSpan?TryReadDurationFast(ProtoReader source, ref ProtoReader.State state)
        {
            int offset       = state.OffsetInCurrent;
            var span         = state.Span;
            int prefixLength = ProtoReader.State.ParseVarintUInt32(span, offset, out var len);

            offset += prefixLength;
            if (len == 0)
            {
                return(TimeSpan.Zero);
            }

            if ((prefixLength + len) > state.RemainingInCurrent)
            {
                return(null);                                                 // don't have entire submessage
            }
            if (span[offset] != (1 << 3))
            {
                return(null);                          // expected field 1
            }
            var   msgOffset = 1 + ProtoReader.State.TryParseUInt64Varint(span, 1 + offset, out var seconds);
            ulong nanos     = 0;

            if (msgOffset < len)
            {
                if (span[msgOffset++ + offset] != (2 << 3))
                {
                    return(null);                                        // expected field 2
                }
                msgOffset += ProtoReader.State.TryParseUInt64Varint(span, msgOffset + offset, out nanos);
            }
            if (msgOffset != len)
            {
                return(null);                  // expected no more fields
            }
            state.Skip(prefixLength + (int)len);
            source.Advance(prefixLength + len);
            return(FromDurationSeconds((long)seconds, (int)(long)nanos));
        }
예제 #11
0
 protected internal override object DeserializeCore(ProtoReader source, ref ProtoReader.State state, int key, object value) => null;
예제 #12
0
 public static DateTime ReadTimestamp(ProtoReader source)
 {
     ProtoReader.State state = default;
     return(ReadTimestamp(source, ref state));
 }
예제 #13
0
 C ISerializer <C> .Read(ref ProtoReader.State state, C value)
 => (C)((ISubTypeSerializer <A>) this).ReadSubType(ref state, SubTypeState <A> .Create <C>(state.Context, value));
예제 #14
0
 public static TimeSpan ReadDuration(ProtoReader source)
 {
     ProtoReader.State state = source.DefaultState();
     return(ReadDuration(source, ref state));
 }
예제 #15
0
 public static decimal ReadDecimal(ProtoReader reader)
 {
     ProtoReader.State state = reader.DefaultState();
     return(ReadDecimal(reader, ref state));
 }
예제 #16
0
        private static long ReadTimeSpanTicks(ProtoReader source, ref ProtoReader.State state, out DateTimeKind kind)
        {
            kind = DateTimeKind.Unspecified;
            switch (source.WireType)
            {
            case WireType.String:
            case WireType.StartGroup:
                SubItemToken  token = ProtoReader.StartSubItem(source, ref state);
                int           fieldNumber;
                TimeSpanScale scale = TimeSpanScale.Days;
                long          value = 0;
                while ((fieldNumber = source.ReadFieldHeader(ref state)) > 0)
                {
                    switch (fieldNumber)
                    {
                    case FieldTimeSpanScale:
                        scale = (TimeSpanScale)source.ReadInt32(ref state);
                        break;

                    case FieldTimeSpanValue:
                        source.Assert(ref state, WireType.SignedVariant);
                        value = source.ReadInt64(ref state);
                        break;

                    case FieldTimeSpanKind:
                        kind = (DateTimeKind)source.ReadInt32(ref state);
                        switch (kind)
                        {
                        case DateTimeKind.Unspecified:
                        case DateTimeKind.Utc:
                        case DateTimeKind.Local:
                            break;             // fine

                        default:
                            throw new ProtoException("Invalid date/time kind: " + kind.ToString());
                        }
                        break;

                    default:
                        source.SkipField(ref state);
                        break;
                    }
                }
                ProtoReader.EndSubItem(token, source, ref state);
                switch (scale)
                {
                case TimeSpanScale.Days:
                    return(value * TimeSpan.TicksPerDay);

                case TimeSpanScale.Hours:
                    return(value * TimeSpan.TicksPerHour);

                case TimeSpanScale.Minutes:
                    return(value * TimeSpan.TicksPerMinute);

                case TimeSpanScale.Seconds:
                    return(value * TimeSpan.TicksPerSecond);

                case TimeSpanScale.Milliseconds:
                    return(value * TimeSpan.TicksPerMillisecond);

                case TimeSpanScale.Ticks:
                    return(value);

                case TimeSpanScale.MinMax:
                    switch (value)
                    {
                    case 1: return(long.MaxValue);

                    case -1: return(long.MinValue);

                    default: throw new ProtoException("Unknown min/max value: " + value.ToString());
                    }

                default:
                    throw new ProtoException("Unknown timescale: " + scale.ToString());
                }

            case WireType.Fixed64:
                return(source.ReadInt64(ref state));

            default:
                throw new ProtoException("Unexpected wire-type: " + source.WireType.ToString());
            }
        }
예제 #17
0
 public static DateTime ReadDateTime(ProtoReader source)
 {
     ProtoReader.State state = source.DefaultState();
     return(ReadDateTime(source, ref state));
 }
예제 #18
0
 public static TimeSpan ReadTimeSpan(ProtoReader source)
 {
     ProtoReader.State state = default;
     return(ReadTimeSpan(source, ref state));
 }