void SerializePrimitive(BitStreamWriter writer, object value, PrimitiveContract contract, DsdlType derivedDsdlType, bool tailArrayOptimization) { if (contract.TypeCode == PrimitiveTypeCode.String && derivedDsdlType is ArrayDsdlType adt && adt.IsStringLike) { byte[] stringBytes; if (value == null) { stringBytes = _emptyByteArray; } else { if (!(value is string stringValue)) { throw new ArgumentException("Cannot cast value to string.", nameof(value)); } stringBytes = _encoding.GetBytes(stringValue); } SerializeList(writer, stringBytes, contract, null, adt, tailArrayOptimization); return; } if (!(derivedDsdlType is PrimitiveDsdlType t)) { throw new InvalidOperationException($"Primitive DSDL type expected for type '{contract.UnderlyingType.FullName}'."); } switch (t) { case BooleanDsdlType _: var boolValue = (bool)ConvertUtils.ConvertOrCast(value, CultureInfo.CurrentCulture, typeof(bool)); BitSerializer.Write(writer, boolValue, t.MaxBitlen); break; case IntDsdlType idt: var longValue = (long)ConvertUtils.ConvertOrCast(value, CultureInfo.CurrentCulture, typeof(long)); longValue = ApplyIntegerCastMode(longValue, idt); BitSerializer.Write(writer, longValue, t.MaxBitlen); break; case UIntDsdlType uidt: var ulongValue = (ulong)ConvertUtils.ConvertOrCast(value, CultureInfo.CurrentCulture, typeof(ulong)); ulongValue = ApplyIntegerCastMode(ulongValue, uidt); BitSerializer.Write(writer, ulongValue, t.MaxBitlen); break; case FloatDsdlType fdt: var doubleValue = (double)ConvertUtils.ConvertOrCast(value, CultureInfo.CurrentCulture, typeof(double)); WriteFloatPrimitive(writer, doubleValue, fdt); break; default: throw new ArgumentOutOfRangeException(nameof(t)); } }
static void WriteFloatPrimitive(BitStreamWriter writer, double value, FloatDsdlType type) { var range = TypeLimits.GetFloatRange(type.MaxBitlen); switch (type.CastMode) { case CastMode.Saturated: if (value > range.Maximum) { value = range.Maximum; } if (value < range.Minimum) { value = range.Minimum; } break; case CastMode.Truncated: if (!double.IsNaN(value) && value > range.Maximum) { value = double.PositiveInfinity; } if (!double.IsNaN(value) && value < range.Maximum) { value = double.NegativeInfinity; } break; default: throw new ArgumentOutOfRangeException(); } switch (type.MaxBitlen) { case 16: var val = BitSerializer.Float32ToUInt16((float)value); BitSerializer.Write(writer, val, 16); break; case 32: BitSerializer.Write(writer, (float)value, 32); break; case 64: BitSerializer.Write(writer, value, 64); break; default: throw new InvalidOperationException($"Unexpected float bit lenght: {type.MaxBitlen}."); } }
static object ReadFloatPrimitiveType(BitStreamReader reader, FloatDsdlType t) { switch (t.MaxBitlen) { case 16: var value = (ushort)BitSerializer.ReadUInt(reader, 16); return(BitSerializer.UInt16ToFloat32(value)); case 32: return(BitSerializer.ReadSingle(reader, 32)); case 64: return(BitSerializer.ReadDouble(reader, 64)); default: throw new InvalidOperationException($"Unexpected float bit lenght: {t.MaxBitlen}."); } }
object ReadPrimitiveType(BitStreamReader reader, PrimitiveDsdlType t) { switch (t) { case BooleanDsdlType _: return(BitSerializer.ReadBoolean(reader, t.MaxBitlen)); case IntDsdlType _: return(BitSerializer.ReadIntTyped(reader, t.MaxBitlen)); case UIntDsdlType _: return(BitSerializer.ReadUIntTyped(reader, t.MaxBitlen)); case FloatDsdlType fdt: return(ReadFloatPrimitiveType(reader, fdt)); default: throw new ArgumentOutOfRangeException(nameof(t)); } }
int ReadDynamicArraySize(BitStreamReader reader, ArrayDsdlType t) { var bitLen = BitSerializer.IntBitLength(t.MaxSize + 1); return((int)BitSerializer.ReadUInt(reader, bitLen)); }
int ReadUnionFieldIndex(BitStreamReader reader, CompositeDsdlTypeBase t) { var bitLen = BitSerializer.IntBitLength(t.Fields.Count); return((int)BitSerializer.ReadUInt(reader, bitLen)); }
void WriteUnionFieldIndex(BitStreamWriter writer, int index, CompositeDsdlTypeBase t) { var bitLen = BitSerializer.IntBitLength(t.Fields.Count); BitSerializer.Write(writer, index, bitLen); }
void WriteDynamicArraySize(BitStreamWriter writer, int count, ArrayDsdlType arrayDsdlType) { var bitLen = BitSerializer.IntBitLength(arrayDsdlType.MaxSize + 1); BitSerializer.Write(writer, count, bitLen); }