public void RegisterConverter(BinaryConverter converter) { var converterType = converter.GetType(); var type = converterType.BaseType; if (type == null) { throw BinaryException.ConverterError(converterType.Name); } var genericType = type.GenericTypeArguments.Single(); _customConverters.TryAdd(genericType, converter); }
private static StandartSerializeResult InternalSerialize(object data, BinarySerializerContext context) { int realLength; byte[] serializedBody = null; StandartSerializeResult composeSerializeResult = null; var examined = 0; if (context.ReflectionData.BodyProperty != null) { var bodyValue = context.ReflectionData.BodyProperty.Get(data); if (bodyValue == null) { throw BinaryException.SerializerBodyPropertyIsNull(); } serializedBody = context.BitConverterHelper.ConvertToBytes(bodyValue, context.ReflectionData.BodyProperty.Type, context.ReflectionData.BodyProperty.Attribute.Reverse); realLength = CalculateRealLength(context.ReflectionData.LengthProperty, data, context.ReflectionData.MetaLength, serializedBody.Length); } else if (context.ReflectionData.ComposeProperty != null) { var composeValue = context.ReflectionData.ComposeProperty.Get(data); if (composeValue == null) { throw BinaryException.SerializerComposePropertyIsNull(); } if (context.ReflectionData.ComposeProperty.Type.IsPrimitive) { serializedBody = context.BitConverterHelper.ConvertToBytes(composeValue, context.ReflectionData.ComposeProperty.Type, context.ReflectionData.ComposeProperty.Attribute.Reverse); realLength = CalculateRealLength(context.ReflectionData.LengthProperty, data, context.ReflectionData.MetaLength, serializedBody.Length); } else { var composeContext = BinaryCache.GetOrAddContext(context.ReflectionData.ComposeProperty.Type, context.BitConverterHelper); composeSerializeResult = InternalSerialize(composeValue, composeContext); realLength = CalculateRealLength(context.ReflectionData.LengthProperty, data, context.ReflectionData.MetaLength, composeSerializeResult.Length); } } else { realLength = context.ReflectionData.MetaLength; } var serializeResult = new StandartSerializeResult(realLength, composeSerializeResult); var bytes = serializeResult.Bytes; foreach (var property in context.ReflectionData.Properties) { if (!property.Type.IsPrimitive && property.Attribute.BinaryDataType == BinaryDataType.Compose && composeSerializeResult != null) { Array.Copy( composeSerializeResult.Bytes, 0, bytes, property.Attribute.Index, composeSerializeResult.Length ); } else { var value = property.Attribute.BinaryDataType == BinaryDataType.Body || property.Attribute.BinaryDataType == BinaryDataType.Compose ? serializedBody ?? throw BinaryException.SerializerBodyPropertyIsNull() : context.BitConverterHelper.ConvertToBytes(property.Get(data), property.Type, property.Attribute.Reverse); var valueLength = value.Length; if (property.Attribute.BinaryDataType != BinaryDataType.Body && property.Attribute.BinaryDataType != BinaryDataType.Compose && valueLength > property.Attribute.Length) { throw BinaryException.SerializerLengthOutOfRange(property.Type.ToString(), valueLength.ToString(), property.Attribute.Length.ToString()); } value.CopyTo(bytes, property.Attribute.Index); } if (++examined == context.ReflectionData.Properties.Count) { break; } } return(serializeResult);
private static void EnsureTypeHasRequiredAttributes(Type typeData) { var members = GetMembers(typeData).ToArray(); var key = members.Where(item => GetTcpDataAttribute(item.Member).BinaryDataType == BinaryDataType.Id).ToList(); if (key.Count > 1) { throw BinaryException.AttributeDuplicate(typeData.ToString(), nameof(BinaryDataType.Id)); } if (key.Count == 1 && key.Single() is { IsProperty : true } internalMember1&& !CanReadWrite((PropertyInfo)internalMember1.Member)) { throw BinaryException.PropertyCanReadWrite(typeData.ToString(), nameof(BinaryDataType.Id)); } var body = members.Where(item => GetTcpDataAttribute(item.Member).BinaryDataType == BinaryDataType.Body).ToList(); if (body.Count > 1) { throw BinaryException.AttributeDuplicate(typeData.ToString(), nameof(BinaryDataType.Body)); } if (body.Count == 1 && body.Single() is { IsProperty : true } internalMember2&& !CanReadWrite((PropertyInfo)internalMember2.Member)) { throw BinaryException.PropertyCanReadWrite(typeData.ToString(), nameof(BinaryDataType.Body)); } var compose = members.Where(item => GetTcpDataAttribute(item.Member).BinaryDataType == BinaryDataType.Compose).ToList(); if (compose.Count > 1) { throw BinaryException.AttributeDuplicate(typeData.ToString(), nameof(BinaryDataType.Compose)); } if (body.Count == 1 && compose.Count == 1) { throw BinaryException.AttributeBodyAndComposeViolated(typeData.ToString()); } var length = members.Where(item => GetTcpDataAttribute(item.Member).BinaryDataType == BinaryDataType.Length).ToList(); if (length.Count > 1) { throw BinaryException.AttributeDuplicate(typeData.ToString(), nameof(BinaryDataType.Length)); } if (body.Count == 1) { // ReSharper disable once ConvertIfStatementToSwitchStatement if (length.Count == 0) { throw BinaryException.AttributeLengthRequired(typeData.ToString(), nameof(BinaryDataType.Body)); } if (length.Count == 1 && length.Single() is { IsProperty : true } internalMember3&& !CanReadWrite((PropertyInfo)internalMember3.Member)) { throw BinaryException.PropertyCanReadWrite(typeData.ToString(), nameof(BinaryDataType.Length)); } } else if (compose.Count == 1) { // ReSharper disable once ConvertIfStatementToSwitchStatement if (length.Count == 0) { throw BinaryException.AttributeLengthRequired(typeData.ToString(), nameof(BinaryDataType.Compose)); } if (length.Count == 1 && length.Single() is { IsProperty : true } internalMember4&& !CanReadWrite((PropertyInfo)internalMember4.Member)) { throw BinaryException.PropertyCanReadWrite(typeData.ToString(), nameof(BinaryDataType.Length)); } } else if (length.Count == 1) { throw BinaryException.AttributeRequiredWithLength(typeData.ToString()); } var metaData = members.Where(item => GetTcpDataAttribute(item.Member).BinaryDataType == BinaryDataType.MetaData).ToList(); if (key.Count == 0 && length.Count == 0 && body.Count == 0 && metaData.Count == 0) { throw BinaryException.AttributesRequired(typeData.ToString()); } foreach (var item in metaData.Where(item => item.IsProperty && !CanReadWrite((PropertyInfo)item.Member))) { throw BinaryException.PropertyCanReadWrite(typeData.ToString(), nameof(BinaryDataType.MetaData), GetTcpDataAttribute(item.Member).Index.ToString()); }