/// <summary> /// Writes a single object to the output binary, using the specified type hint and writer worker. /// </summary> /// <typeparam name="T">The type of value.</typeparam> /// <param name="value">The value to write.</param> /// <param name="typeWriter">The content type writer.</param> /// <remarks>The type hint should be retrieved from the Initialize method of the ContentTypeWriter /// that is calling WriteObject, by calling GetTypeWriter and passing it the type of the field used /// to hold the value being serialized. /// </remarks> public void WriteObject <T>(T value, ContentTypeWriter typeWriter) { if (typeWriter == null) { throw new ArgumentNullException("typeWriter"); } if (value == null) { // Zero means a null object Write7BitEncodedInt(0); } else { Type objectType = typeof(T); if (!objectType.IsValueType) { var index = typeWriterMap[typeWriter.GetType()]; // Because zero means null object, we add one to the index before writing it to the file Write7BitEncodedInt(index + 1); } typeWriter.Write(this, value); } }
/// <summary> /// Retrieves the worker writer for the specified type. /// </summary> /// <param name="type">The type.</param> /// <returns>The worker writer.</returns> /// <remarks>This should be called from the ContentTypeWriter.Initialize method.</remarks> public ContentTypeWriter GetTypeWriter(Type type) { ContentTypeWriter result = null; var contentTypeWriterType = typeof(ContentTypeWriter <>).MakeGenericType(type); Type typeWriterType; if (type == typeof(Array)) { result = new ArrayWriter <Array>(); } else if (typeWriterMap.TryGetValue(contentTypeWriterType, out typeWriterType)) { result = (ContentTypeWriter)Activator.CreateInstance(typeWriterType); } else if (type.IsArray) { var writerType = type.GetArrayRank() == 1 ? typeof(ArrayWriter <>) : typeof(MultiArrayWriter <>); result = (ContentTypeWriter)Activator.CreateInstance(writerType.MakeGenericType(type.GetElementType())); typeWriterMap.Add(contentTypeWriterType, result.GetType()); } else if (type.IsEnum) { result = (ContentTypeWriter)Activator.CreateInstance(typeof(EnumWriter <>).MakeGenericType(type)); typeWriterMap.Add(contentTypeWriterType, result.GetType()); } else if (type.IsGenericType) { var inputTypeDef = type.GetGenericTypeDefinition(); Type chosen = null; foreach (var kvp in typeWriterMap) { var args = kvp.Key.GetGenericArguments(); if (args.Length == 0) { continue; } if (!kvp.Value.IsGenericTypeDefinition) { continue; } if (!args[0].IsGenericType) { continue; } // Compare generic type definition var keyTypeDef = args[0].GetGenericTypeDefinition(); if (inputTypeDef == keyTypeDef) { chosen = kvp.Value; break; } } try { if (chosen == null) { result = (ContentTypeWriter)Activator.CreateInstance(typeof(ReflectiveWriter <>).MakeGenericType(type)); } else { var concreteType = type.GetGenericArguments(); result = (ContentTypeWriter)Activator.CreateInstance(chosen.MakeGenericType(concreteType)); } // save it for next time. typeWriterMap.Add(contentTypeWriterType, result.GetType()); } catch (Exception) { throw new InvalidContentException(String.Format("Could not find ContentTypeWriter for type '{0}'", type.Name)); } } else { result = (ContentTypeWriter)Activator.CreateInstance(typeof(ReflectiveWriter <>).MakeGenericType(type)); typeWriterMap.Add(contentTypeWriterType, result.GetType()); } var initMethod = result.GetType().GetMethod("Initialize", BindingFlags.NonPublic | BindingFlags.Instance); initMethod.Invoke(result, new object[] { this }); return(result); }
public void WriteRawObject <T>(T value, ContentTypeWriter typeWriter) { throw new NotImplementedException(); }
internal void RegisterTypeWriter(ContentTypeWriter typeWriter) { typeWriters.Add(typeWriter.TargetType, typeWriter); }
/// <summary> /// Initialize the writer. /// </summary> /// <param name="compiler">Compiler instance calling this writer.</param> protected override void Initialize(ContentCompiler compiler) { base.Initialize(compiler); elementWriter = compiler.GetTypeWriter(typeof(T)); }
public void WriteRawObject <T>(T value, ContentTypeWriter typeWriter) { }
internal void RegisterTypeWriter(ContentTypeWriter typeWriter) { typeWriters.Add(typeWriter.TargetType, typeWriter); }
/// <inheritdoc/> internal override void OnAddedToContentWriter(ContentWriter output) { base.OnAddedToContentWriter(output); _underlyingType = Enum.GetUnderlyingType(typeof(T)); _underlyingTypeWriter = output.GetTypeWriter(_underlyingType); }
/// <summary> /// Retrieves the worker writer for the specified type. /// </summary> /// <param name="type">The type.</param> /// <returns>The worker writer.</returns> /// <remarks>This should be called from the ContentTypeWriter.Initialize method.</remarks> public ContentTypeWriter GetTypeWriter(Type type) { ContentTypeWriter result = null; var contentTypeWriterType = typeof(ContentTypeWriter <>).MakeGenericType(type); Type typeWriterType; if (typeWriterMap.TryGetValue(contentTypeWriterType, out typeWriterType)) { result = (ContentTypeWriter)Activator.CreateInstance(typeWriterType); } else if (type.IsArray) { if (type.GetArrayRank() != 1) { throw new NotSupportedException("We don't support multidimensional arrays!"); } result = (ContentTypeWriter)Activator.CreateInstance(typeof(ArrayWriter <>).MakeGenericType(type.GetElementType())); typeWriterMap.Add(contentTypeWriterType, result.GetType()); } else { var inputTypeDef = type.GetGenericTypeDefinition(); Type chosen = null; foreach (var kvp in typeWriterMap) { var args = kvp.Key.GetGenericArguments(); if (args.Length == 0) { continue; } if (!args[0].IsGenericType) { continue; } // Compare generic type definition var keyTypeDef = args[0].GetGenericTypeDefinition(); if (inputTypeDef.Equals(keyTypeDef)) { chosen = kvp.Value; break; } } try { var concreteType = type.GetGenericArguments(); result = (ContentTypeWriter)Activator.CreateInstance(chosen.MakeGenericType(concreteType)); // save it for next time. typeWriterMap.Add(contentTypeWriterType, result.GetType()); } catch (Exception) { throw new InvalidContentException(String.Format("Could not find ContentTypeWriter for type '{0}'", type.Name)); } } if (result != null) { MethodInfo dynMethod = result.GetType().GetMethod("Initialize", BindingFlags.NonPublic | BindingFlags.Instance); dynMethod.Invoke(result, new object[] { this }); } return(result); }
/// <inheritdoc/> internal override void OnAddedToContentWriter(ContentWriter output) { base.OnAddedToContentWriter(output); _elementWriter = output.GetTypeWriter(typeof(T)); }