public virtual void SetOutput(IValueItem item) { if (!AllowMultipleInputs) { foreach (var input in Inputs) Repository.Remove(input); } if (!AllowMultipleOutputs) { foreach (var output in Outputs) Repository.Remove(output); } var cd = new ConnectionData(); cd.InputIdentifier = item.Identifier; cd.OutputIdentifier = Identifier; Repository.Add(cd); }
internal static IValueItem ReadTypeMetaInfo(IStreamReader reader, uint typeId, ISerializeContext ctx) { byte metaTypeVersion = reader.ReadUInt8(); string assemblyName; string typeFullName; Type type; if (metaTypeVersion == SingleTypeDescr) { assemblyName = reader.ReadString(); typeFullName = reader.ReadString(); if (!TypeService.TryGetTypeByName(typeFullName, out type, ctx.Serializer.CustomLookupAssemblies)) { if (ctx.Serializer.AutoCreateMissingTypes) { return(AutoCreateMissingDeserializeType(typeId, assemblyName, typeFullName, reader, ctx)); } else { throw new TypeAccessException($"Type {typeFullName} not found!"); } } IValueItem resultItem = ctx.GetByType(type); if (resultItem is ITypeStructure) { ITypeStructure result = (ITypeStructure)resultItem; short itemCount = reader.ReadInt16(); if (result.TypeId == typeId) { // internal type is equal remote type for (int i = 0; i < itemCount; i++) { SkipPropertyMetaInfo(reader); } return(result); } else { // differences between local type and remote type // read actual structure and try map to old/new structure ComplexStructure tolerantLayoutStructure = ComplexStructure.CreateTolerantLayoutStructure(type, ctx); for (int i = 0; i < itemCount; i++) { ItemType itemType = (ItemType)reader.ReadInt16(); // ItemType Enum uint propertyTypeId = reader.ReadUInt32(); // TypeId (Type Hash) string propertyName = reader.ReadString(); // Property Name bool isNullable = reader.ReadBool(); // Nullable Flag IValueItem nameMatchingItem = result.Items.Where(item => item.Name == propertyName).FirstOrDefault(); if (nameMatchingItem != null) { bool typeMatch = itemType == nameMatchingItem.Type; bool typeIdMatch = propertyTypeId == nameMatchingItem.TypeId; bool nullableMatch = isNullable == nameMatchingItem.IsNullable; bool fromNotNullable = !isNullable && nameMatchingItem.IsNullable; if (typeMatch && typeIdMatch && nullableMatch) { // Property has exactly the same attributes > no conversion required tolerantLayoutStructure.AddTolerantLayoutProperty(ctx, propertyName); } else if (typeMatch && typeIdMatch && !nullableMatch && fromNotNullable) { // Property changed only from not nullable to nullable tolerantLayoutStructure.AddTolerantLayoutConverterProperty(nameMatchingItem, ctx, propertyName, itemType, propertyTypeId, isNullable, v => v); } else if (!typeMatch && !typeIdMatch && (nullableMatch || fromNotNullable)) { // Only property type changed // Check if type can be converted without loosing data Func <object, object> converter = null; if (itemType == ItemType.Int32 && nameMatchingItem.Type == ItemType.Int64) { // Read incoming Int32 and convert to local Int64 property converter = v => (long)(int)v; } else if (itemType == ItemType.Int16 && nameMatchingItem.Type == ItemType.Int32) { // Read incoming Int16 and convert to local Int32 property converter = v => (int)(short)v; } else if (itemType == ItemType.Byte && nameMatchingItem.Type == ItemType.Int16) { // Read incoming Byte and convert to local Int16 property converter = v => (short)(byte)v; } else if (itemType == ItemType.Double && nameMatchingItem.Type == ItemType.Decimal) { // Read incoming Double and convert to local Decimal property converter = v => (decimal)(double)v; } else if (itemType == ItemType.Char && nameMatchingItem.Type == ItemType.String) { // Read incoming Char and convert to local String property converter = v => new string(new char[] { (char)v }); } if (converter != null) { tolerantLayoutStructure.AddTolerantLayoutConverterProperty(nameMatchingItem, ctx, propertyName, itemType, propertyTypeId, isNullable, converter); } } } else { // no name matching property found (removed, renamed or old local version) > create dummy item tolerantLayoutStructure.AddTolerantLayoutDummyProperty(ctx, propertyName, itemType, propertyTypeId, isNullable); } } tolerantLayoutStructure.FinalizeTolerantLayoutStructure(); if (typeId == tolerantLayoutStructure.TypeId) { // Tolerant mapping was successful // Register only type ID in global cache BinarySerializer.RegisterTolerantTypeMapping(tolerantLayoutStructure); return(tolerantLayoutStructure); } else { // Can't map old/new structure to incoming type meta data throw new FormatException($"The incoming binary format does not match the loaded type {type.FullName}! An tolerant mapping was not possible. Please update the remote or local interface assemblies. Expected Type Id: {result.TypeId}; Received Type Id: {typeId}"); } } } else if (resultItem is ITypePrefix) { // Only type prefix - e.g. enum ITypePrefix result = (ITypePrefix)resultItem; short itemCount = reader.ReadInt16(); if (result.TypeId == typeId) { // internal type is equal remote type for (int i = 0; i < itemCount; i++) { SkipPropertyMetaInfo(reader); } return(result); } else { throw new FormatException($"The incoming binary format does not match the loaded type {type.FullName}! An tolerant mapping was not possible. Please update the remote or local interface assemblies. Expected Type Id: {result.TypeId}; Received Type Id: {typeId}"); } } else { return(resultItem); } } else if (metaTypeVersion == CollectionTypeDescr) { assemblyName = reader.ReadString(); typeFullName = reader.ReadString(); //todo: load assembly if required if (TypeService.TryGetTypeByName(typeFullName, out type)) { CollectionItems result = (CollectionItems)ctx.GetByType(type); if (result.TypeId == typeId) { return(result); } else { // differences between local type and remote type //todo: implement throw new NotImplementedException($"Support for different binary layout is not implemented yet! Local Type ID: {result.TypeId}; Remote Type ID: {typeId}"); } } else { throw new TypeAccessException($"Type {typeFullName} not found!"); } } else { throw new NotSupportedException($"Type meta information version {metaTypeVersion} not supported!"); } }
/// <summary> /// Initializes a new instance of the <see cref="TolerantConvertItem" /> class. /// </summary> /// <param name="sourceTypeItem">The source type item.</param> /// <param name="targetTypeItem">The target type item.</param> /// <param name="converter">The converter.</param> public TolerantConvertItem(IValueItem sourceTypeItem, IValueItem targetTypeItem, Func <object, object> converter) { this.sourceTypeItem = sourceTypeItem; this.targetTypeItem = targetTypeItem; this.converter = converter; }
internal bool TryGetDifferentTargetType(Type objectType, out IValueItem targetItem) { return(differentTargetTypes.TryGetValue(objectType, out targetItem)); }
public void WriteValue(IStreamWriter writer, ISerializeContext context, object value) { // Complex structure // TypeID UInt32 // ContentType Byte context.Key = this.Name; if (isObject) { // property or collection does not specify a target type // determine object type if (value != null) { Type valType = value.GetType(); IValueItem item; var differentTargetStructure = context.DetermineSpecialInterfaceType(value.GetType(), type); if (differentTargetStructure != null) { item = differentTargetStructure; } else { item = context.GetByType(valType); } if (!item.IsTypePrefixExpected) { // Write type id for value types as well (unknown structure) writer.WriteUInt32(item.TypeId); writer.WriteUInt8(ValueItem.SingleValueIdent); } item.WriteValue(writer, context, value); } else { // write complex object type id for null value writer.WriteInt32((int)ItemType.ComplexObject); writer.WriteUInt8(ValueItem.NullValueIdent); } } else if (value == null) { // Write null writer.WriteUInt32(this.TypeId); writer.WriteUInt8(ValueItem.NullValueIdent); } else { IValueItem differentTargetStructure = null; if (CheckDifferentType) { differentTargetStructure = context.DetermineSpecialInterfaceType(value.GetType(), type); } if (differentTargetStructure != null) { // Special target interface type serialization differentTargetStructure.WriteValue(writer, context, value); } else { // Just write type properties writer.WriteUInt32(this.TypeId); if (context.IsWriteTypeMetaInfoRequired(this.TypeId)) { // serialize type meta info at the first time TypeMetaStructure.WriteTypeMetaInfo(writer, this); } writer.WriteUInt8(ValueItem.SingleObjectIdent); object oldParentObj = context.ParentObject; context.ParentObject = value; for (int itemIndex = 0; itemIndex < items.Count; itemIndex++) { var item = items[itemIndex]; var valueItem = item.GetItemValue(value); item.WriteValue(writer, context, valueItem); } context.ParentObject = oldParentObj; } } }
//protected override Boolean ImplAddSequenceItem ( SequenceType sequence, Object item ) //{ // if ( !(item is SequenceItemType) ) return false; // SequenceItemType kvp = (SequenceItemType) item; // try { sequence.Add ( kvp.Key, kvp.Value ); } // catch { return false; } // return true; //} // End of ImplAddSequenceItem (...) protected override Boolean ImplDeserializeItem( out Object retVal, Object item, IHierarchicalMetadataSerializationContext context) { retVal = null; IValueItem curCtxtLvlVi = null; KeyValuePair <SequenceKeyType, SequenceValueType> kvp; IValueUnit kvpVu; IValueUnit kvpCtxtLvl = null; SequenceKeyType kvpKey = default(SequenceKeyType); SequenceValueType kvpValue = default(SequenceValueType); IValueItem valueItem = null; if (context == null) { return(false); } if ((kvpVu = item as IValueUnit) == null) { return(false); } if (kvpVu.Count != 2) { return(false); } if ((kvpCtxtLvl = context.Hierarchy.Peek() as IValueUnit) == null) { return(false); } // Deserialize the Key if ((valueItem = kvpVu [nameof(kvp.Key)]) == null) { return(false); } if ((curCtxtLvlVi = kvpCtxtLvl [nameof(kvp.Key)]) == null) { context.Hierarchy.Push(null); } else { context.Hierarchy.Push(curCtxtLvlVi.Value as IValueUnit); } try { if (!base.ImplDeserializeItem(out Object key, valueItem.Value, context)) { return(false); } kvpKey = (SequenceKeyType)key; } finally { context.Hierarchy.Pop(); } // Deserialize the Value if ((valueItem = kvpVu [nameof(kvp.Value)]) == null) { return(false); } if ((curCtxtLvlVi = kvpCtxtLvl [nameof(kvp.Value)]) == null) { context.Hierarchy.Push(null); } else { context.Hierarchy.Push(curCtxtLvlVi.Value as IValueUnit); } try { if (!base.ImplDeserializeItem(out Object value, valueItem.Value, context)) { return(false); } kvpValue = (SequenceValueType)value; } finally { context.Hierarchy.Pop(); } kvp = new KeyValuePair <SequenceKeyType, SequenceValueType> (kvpKey, kvpValue); retVal = kvp; return(true); } // End of ImplDeserializeItem (...)
/// <summary> /// Initializes a new instance of the <see cref="CollectionItems"/> class. /// </summary> /// <param name="type">The type.</param> public CollectionItems(Type type, string name, Func <object, object> getter, Action <object, object> setter, ITypeResolver typeResolver) { this.type = type; if (name != null) { this.Name = name; } else { this.Name = type.FullName; } this.isArray = type.IsArray; this.setter = setter; this.getter = getter; this.typeId = CalculateTypeId(); if (isArray) { itemType = type.GetElementType(); isByteArray = itemType.Equals(typeof(byte)); } else { // type is a collection // check if collection is generic IEnumerable<T> if (type.IsGenericType) { Type genericCollectionInterface = type.GetInterface("IEnumerable`1"); Type[] genericTypes = type.GetGenericArguments(); if (genericTypes.Length == 1) { Type listType = typeof(List <>); targetCollectionType = listType.MakeGenericType(genericTypes); itemType = genericTypes[0]; } else if (genericTypes.Length == 0 && genericCollectionInterface != null) { genericTypes = genericCollectionInterface.GetGenericArguments(); Type listType = typeof(List <>); targetCollectionType = listType.MakeGenericType(genericTypes); itemType = genericTypes[0]; } else { throw new NotImplementedException("More than one generic arguments is not supported yet!"); } } else { var defaultConstructor = type.GetConstructor(System.Type.EmptyTypes); if (defaultConstructor != null) { targetCollectionType = type; } else { // untyped collection targetCollectionType = typeof(ArrayList); } itemType = typeof(object); } implementsIList = targetCollectionType.GetInterface("IList") != null; if (!implementsIList) { specialCollAddMethod = targetCollectionType.GetMethod("Add"); } } itemStructure = typeResolver.GetByType(itemType); }