/// <inheritdoc /> public bool RegisterType(ContextTypeFlags contextFlags, IContextKey key, Type type, ITypeSerializerStrategy strategy) { if (type == null) { throw new ArgumentNullException(nameof(type), $"Provided argument {nameof(type)} is null."); } if (strategy == null) { throw new ArgumentNullException(nameof(strategy), $"Provided argument {nameof(strategy)} is null."); } if (key == null) { throw new ArgumentNullException(nameof(key), $"Provided argument {nameof(key)} is null."); } //Check if contextflags are none. We can skip everything and delegate to contextless if (contextFlags == ContextTypeFlags.None) { return(RegisterType(type, strategy)); } //Register a new contextless serializer strategyLookupTable.Add(new ContextualSerializerLookupKey(contextFlags, key, type), strategy); return(true); }
public ContextualSerializerLookupKey(ContextTypeFlags flags, [NotNull] IContextKey contextSpecificKey, [NotNull] Type type) { if (contextSpecificKey == null) { throw new ArgumentNullException(nameof(contextSpecificKey), $"Provided argument {nameof(contextSpecificKey)} is null."); } if (type == null) { throw new ArgumentNullException(nameof(type), $"Provided argument {type} is null."); } ContextType = type; ContextFlags = flags; ContextSpecificKey = contextSpecificKey; CachedToString = $"{this.ContextFlags.ToString()}-{this.ContextSpecificKey?.GetType()?.Name}-{this.ContextSpecificKey.Key}-{ContextType?.FullName}"; CachedHashCode = CachedToString.GetHashCode(); }
private ContextualSerializerLookupKey GetKeyFromStorage(ContextTypeFlags flags, Type t) { lock (syncObj) { if (CachedKeyStore.ContainsKey(t)) { if (CachedKeyStore[t].ContainsKey(flags)) { return(CachedKeyStore[t][flags]); } else { return(CachedKeyStore[t][flags] = new ContextualSerializerLookupKey(flags, NoContextKey.Value, t)); } } else { CachedKeyStore.Add(t, new Dictionary <ContextTypeFlags, ContextualSerializerLookupKey>()); return(GetKeyFromStorage(flags, t)); } } }
/// <inheritdoc /> public ContextualSerializerLookupKey Create([NotNull] ISerializableTypeContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } //We must inspect the metadata to build the key if (!context.HasContextualMemberMetadata()) { GetKeyFromStorage(ContextTypeFlags.None, context.TargetType); } //Build the relevant flags ContextTypeFlags flags = ContextTypeFlags.None; if (context.HasMemberAttribute <ReadToEndAttribute>()) { flags |= ContextTypeFlags.ReadToEnd; } if (context.HasMemberAttribute <ReverseDataAttribute>()) { flags |= ContextTypeFlags.Reverse; } if (context.HasMemberAttribute <EnumStringAttribute>()) { flags |= ContextTypeFlags.EnumString; } //Check for no terminate too if (context.HasMemberAttribute <DontTerminateAttribute>()) { flags |= ContextTypeFlags.DontTerminate; } if (context.HasMemberAttribute <CompressAttribute>()) { flags |= ContextTypeFlags.Compressed; } //Encoding requires multiple flags to be set. //We can't rely on the context key since it may be used for size if (context.HasMemberAttribute <EncodingAttribute>()) { flags |= ContextTypeFlags.Encoding; EncodingAttribute attri = context.GetMemberAttribute <EncodingAttribute>(); switch (attri.DesiredEncodingType) { case EncodingType.ASCII: flags |= ContextTypeFlags.ASCII; break; case EncodingType.UTF16: flags |= ContextTypeFlags.UTF16; break; case EncodingType.UTF32: flags |= ContextTypeFlags.UTF32; break; case EncodingType.UTF8: flags |= ContextTypeFlags.UTF8; break; } } if (context.HasMemberAttribute <SendSizeAttribute>()) { return(new ContextualSerializerLookupKey(flags | ContextTypeFlags.SendSize, new SendSizeContextKey(context.GetMemberAttribute <SendSizeAttribute>().TypeOfSize, context.GetMemberAttribute <SendSizeAttribute>().AddedSize), context.TargetType)); } if (context.HasMemberAttribute <KnownSizeAttribute>()) { return(new ContextualSerializerLookupKey(flags | ContextTypeFlags.FixedSize, new SizeContextKey(context.GetMemberAttribute <KnownSizeAttribute>().KnownSize), context.TargetType)); } //If we're here then we have flags that weren't mutually exclusive return(GetKeyFromStorage(flags, context.TargetType)); }
public static bool HasSerializerFor([NotNull] this IContextualSerializerProvider provider, ContextTypeFlags contextFlags, [NotNull] IContextKey key, [NotNull] Type type) { if (provider == null) { throw new ArgumentNullException(nameof(provider), $"Cannot call extension method on null {nameof(IContextualSerializerProvider)}"); } if (key == null) { throw new ArgumentNullException(nameof(key)); } if (type == null) { throw new ArgumentNullException(nameof(type)); } if (!Enum.IsDefined(typeof(ContextTypeFlags), contextFlags)) { throw new ArgumentOutOfRangeException(nameof(contextFlags), "Value should be defined in the ContextTypeFlags enum."); } /*if (!Enum.IsDefined(typeof(ContextTypeFlags), contextFlags)) * throw new InvalidEnumArgumentException(nameof(contextFlags), (int) contextFlags, typeof(ContextTypeFlags));*/ return(provider.HasSerializerFor(new ContextualSerializerLookupKey(contextFlags, key, type))); }