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); }
/// <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)); }
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)); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
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), });
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); }
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)); }
protected internal override object DeserializeCore(ProtoReader source, ref ProtoReader.State state, int key, object value) => null;
public static DateTime ReadTimestamp(ProtoReader source) { ProtoReader.State state = default; return(ReadTimestamp(source, ref state)); }
C ISerializer <C> .Read(ref ProtoReader.State state, C value) => (C)((ISubTypeSerializer <A>) this).ReadSubType(ref state, SubTypeState <A> .Create <C>(state.Context, value));
public static TimeSpan ReadDuration(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return(ReadDuration(source, ref state)); }
public static decimal ReadDecimal(ProtoReader reader) { ProtoReader.State state = reader.DefaultState(); return(ReadDecimal(reader, ref state)); }
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()); } }
public static DateTime ReadDateTime(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return(ReadDateTime(source, ref state)); }
public static TimeSpan ReadTimeSpan(ProtoReader source) { ProtoReader.State state = default; return(ReadTimeSpan(source, ref state)); }