/// <summary> /// Reads the current chunk and creates a runtime type for it, which is then returned. /// </summary> /// <param name="context">The context of the chunk file being read. Must not be null.</param> /// <returns>Returns null if there was no runtime type found for the current chunk.</returns> public override object Read(ChunkFileContext context) { Check.IfArgumentNull(context, nameof(context)); Check.IfArgumentNull(context.ChunkStack, nameof(context.ChunkStack)); Check.IfArgumentNull(context.ChunkStack.CurrentChunk, nameof(context.ChunkStack.CurrentChunk)); Check.IfArgumentNull(context.ChunkFile, nameof(context.ChunkFile)); Check.IfArgumentNull(context.ChunkFile.BaseStream, nameof(context.ChunkFile.BaseStream)); var reader = context.Services.GetService <FileChunkReader>(); var stream = context.ChunkFile.BaseStream; var chunk = context.ChunkStack.CurrentChunk; chunk.RuntimeInstance = reader.ReadRuntimeChunkType(stream, chunk.ChunkId); // extra check if type returned is correct for chunk. if (chunk.RuntimeInstance != null && !ChunkAttribute.GetChunkId(chunk.RuntimeInstance).MatchesWith(chunk.ChunkId.ToString())) { var msg = String.Format( CultureInfo.InvariantCulture, "The type '{0}' tagged with '{1}' was returned when '{2}' was requested.", chunk.RuntimeInstance.GetType(), ChunkAttribute.GetChunkId(chunk.RuntimeInstance), chunk.ChunkId); throw new ChunkFileException(msg); } return(chunk.RuntimeInstance); }
public ChunkFileContextBuilder AddChunk(Type chunkType) { var chunkId = ChunkAttribute.GetChunkId(chunkType); if (String.IsNullOrEmpty(chunkId)) { throw new ArgumentException($"The specified type {chunkType.Name} has no ChunkAttribute.", nameof(chunkType)); } _chunkTypes.Add(chunkType); return(this); }
public FileChunkHeader WriteNextChunk(object chunk) { Contract.Requires(chunk != null); Check.IfArgumentNull(chunk, "chunk"); // find chunk id var chunkId = ChunkAttribute.GetChunkId(chunk); if (String.IsNullOrEmpty(chunkId)) { var msg = String.Format( CultureInfo.InvariantCulture, "No Chunk Attribute was found for the specified runtime object of type '{0}'.", chunk.GetType().FullName); throw new ArgumentException(msg); } if (chunkId.HasWildcard()) { // TODO: this must be pluggable in some way // for now only digits chunkId = chunkId.Merge("0000"); } var chunkTypeId = new FourCharacterCode(chunkId); var chunkHandler = this.handlerMgr.GetChunkHandler(chunkTypeId); if (!chunkHandler.CanWrite(chunk)) { var msg = String.Format( CultureInfo.InvariantCulture, "The chunk handler '{0}' cannot write the specified runtime object.", chunkHandler.ChunkId); throw new ArgumentException(msg); } int stackPos = this.context.HeaderStack.Count; var header = this.PushNewHeader(chunkTypeId); chunkHandler.Write(this.context, chunk); // wind down the stack to the level it was before we started. while (this.context.HeaderStack.Count > stackPos) { var poppedHeader = this.PopHeader(); this.WriteChunkHeader(poppedHeader); } return(header); }
/// <summary> /// Scans the <paramref name="assembly"/> for types that have the /// <see cref="ChunkAttribute"/> applied and adds them to the factory. /// </summary> /// <param name="assembly">Must not be null.</param> /// <param name="replace">If true the Type found in the <paramref name="assembly"/> will replace /// an already registered type.</param> public void AddChunksFrom(Assembly assembly, AddMode addMode) { Check.IfArgumentNull(assembly, nameof(assembly)); var result = from type in assembly.GetTypes() where type.IsClass && type.IsChunk() select new { ChunkId = ChunkAttribute.GetChunkId(type), Type = type }; foreach (var item in result) { AddChunkType(item.ChunkId, item.Type, addMode); } }
private static string GetCollectionItemChunkId(object instance) { Type type = instance.GetType(); Type dataType = null; if (type.IsGenericType) { var genType = type.GetGenericTypeDefinition(); if (genType.FullName.StartsWith("System.Collections.Generic.", StringComparison.OrdinalIgnoreCase) && genType.FullName.EndsWith("`1", StringComparison.OrdinalIgnoreCase)) { dataType = (from typeArg in type.GetGenericArguments() select typeArg).FirstOrDefault(); } else { var msg = String.Format( CultureInfo.InvariantCulture, "The generic type '{0}' is not supported. Use IEnumerable<T> for collections.", genType.FullName); throw new NotSupportedException(msg); } } else { dataType = type; } string chunkId = null; if (dataType != null) { chunkId = ChunkAttribute.GetChunkId(dataType); } return(chunkId); }
public override void Write(ChunkFileContext context, object instance) { Check.IfArgumentNull(context, "context"); Check.IfArgumentNull(instance, "instance"); Check.IfArgumentNotOfType <RiffChunk>(instance, "instance"); var chunk = (RiffChunk)instance; if (chunk.InnerChunk == null) { throw new ArgumentException("No RIFF chunk content found.", "instance"); } // make sure the correct file type is set. chunk.FileType = new FourCharacterCode(ChunkAttribute.GetChunkId(chunk.InnerChunk)); // write out RIFF file type base.Write(context, instance); var writer = context.CompositionContainer.GetService <FileChunkWriter>(); writer.WriteRuntimeChunkType(chunk.InnerChunk); }
public bool WriteChunkObject(object value) { Contract.Requires(value != null); Check.IfArgumentNull(value, "runtimeObject"); bool isCollection = false; var type = value.GetType(); if (type.IsGenericType) { // use generic parameter as type type = (from typeArg in type.GetGenericArguments() select typeArg).FirstOrDefault(); if (type == null) { throw new ChunkFileException("Internal error. No type argument from generic type."); } isCollection = true; } var chunkId = ChunkAttribute.GetChunkId(type); foreach (var member in this.members) { if (member.ChunkMatches(chunkId) && member.CanSetValue) { member.SetValue(this.Instance, value, isCollection); return(true); } } return(false); }
private static IEnumerable <ObjectMemberData> BuildMemberList(Type type) { Contract.Requires(type != null); Check.IfArgumentNull(type, "type"); var members = (from member in type.GetMembers() where member.MemberType == MemberTypes.Property || member.MemberType == MemberTypes.Field where member.GetCustomAttributes(typeof(IgnoreAttribute), true).Length == 0 select new ObjectMemberData { FieldInfo = member as FieldInfo, PropertyInfo = member as PropertyInfo }).ToList(); foreach (var member in members) { Contract.Assume(member != null); string chunkId = null; Type dataType = null; if (member.FieldInfo != null) { dataType = member.FieldInfo.FieldType; } if (member.PropertyInfo != null) { dataType = member.PropertyInfo.PropertyType; } Contract.Assume(dataType != null); if (dataType.IsGenericType) { var genType = dataType.GetGenericTypeDefinition(); if (genType.FullName.StartsWith("System.Collections.Generic.", StringComparison.OrdinalIgnoreCase) && genType.FullName.EndsWith("`1", StringComparison.OrdinalIgnoreCase)) { member.DataType = (from typeArg in dataType.GetGenericArguments() select typeArg).FirstOrDefault(); member.IsCollection = true; } else { var msg = String.Format( CultureInfo.InvariantCulture, "The generic type '{0}' is not supported. Use IEnumerable<T> for collections.", genType.FullName); throw new NotSupportedException(msg); } } else { member.DataType = dataType; } if (member.DataType != null) { chunkId = ChunkAttribute.GetChunkId(member.DataType); } if (!String.IsNullOrEmpty(chunkId)) { member.ChunkIds = new List <string>(); member.ChunkIds.Add(chunkId); } else { var memberInfo = member.GetMemberInfo(); if (memberInfo != null) { var chunkTypes = ChunkTypeAttribute.GetChunkTypes(memberInfo); if (chunkTypes != null && chunkTypes.Length > 0) { member.ChunkIds = new List <string>(chunkTypes); } member.ChunkIdsAreChunkTypes = true; } } } return(members); }
public void AddChunkType(Type chunkType, AddMode addMode) { var chunkId = ChunkAttribute.GetChunkId(chunkType); AddChunkType(chunkId, chunkType, addMode); }