示例#1
0
        /// <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);
            }
        }
示例#2
0
        /// <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);
        }
示例#3
0
 public void WriteRawObject <T>(T value, ContentTypeWriter typeWriter)
 {
     throw new NotImplementedException();
 }
示例#4
0
 internal void RegisterTypeWriter(ContentTypeWriter typeWriter)
 {
     typeWriters.Add(typeWriter.TargetType, typeWriter);
 }
示例#5
0
        /// <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));
        }
示例#6
0
 public void WriteRawObject <T>(T value, ContentTypeWriter typeWriter)
 {
 }
示例#7
0
		internal void RegisterTypeWriter(ContentTypeWriter typeWriter)
		{
			typeWriters.Add(typeWriter.TargetType, typeWriter);	
		}
示例#8
0
 /// <inheritdoc/>
 internal override void OnAddedToContentWriter(ContentWriter output)
 {
     base.OnAddedToContentWriter(output);
     _underlyingType       = Enum.GetUnderlyingType(typeof(T));
     _underlyingTypeWriter = output.GetTypeWriter(_underlyingType);
 }
示例#9
0
        /// <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);
        }
示例#10
0
        /// <inheritdoc/>
        internal override void OnAddedToContentWriter(ContentWriter output)
        {
            base.OnAddedToContentWriter(output);

            _elementWriter = output.GetTypeWriter(typeof(T));
        }