/// <summary> /// Gets a collection with the primitive elements from the data. /// </summary> /// <param name="data"> Data of the collection. </param> /// <param name="collectionType"> Type of the collection. </param> /// <param name="elementType"> Type of the element. </param> /// <param name="count"> Count of the elements. </param> /// <returns> The collection. </returns> protected virtual IEnumerable GetPrimitiveCollection(byte[] data, Type collectionType, Type elementType, int count) { IEnumerable enumerable = this.CreateCollection(collectionType, elementType, count); Func <string, object> reader = GetValueReader(elementType); if (reader != null) { IEnumerable <string> lines = StringUtils.SplitLines(data.GetString()); Array array = enumerable as Array; if (array != null) { int index = -1; foreach (string line in lines) { if (++index == count) { break; } array.SetValue(reader(line), index); } return(enumerable); } IList list = enumerable as IList; if (list != null) { int index = 0; foreach (string line in lines) { if (index++ == count) { break; } list.Add(reader(line)); } return(enumerable); } using (CollectionWriter writer = new CollectionWriter(this, enumerable)) { int index = 0; foreach (string line in lines) { if (index++ == count) { break; } writer.Add(reader(line)); } return(enumerable); } } return(enumerable); }
/// <summary> /// Tries read the entries of the data by the path and creates a new collection. /// </summary> /// <param name="path"> The path. </param> /// <param name="type"> The type. </param> /// <param name="typeInterfaces"> Interfaces of the type. </param> /// <param name="className"> Name of the class. </param> /// <param name="values"> Values of the class. </param> /// <param name="storer"> The storer. </param> /// <param name="entries"> List of the entries of the storer. </param> /// <param name="references"> Dictionary that contains references to the objects. </param> /// <returns> Collection if collection has been created successfully, otherwise null. </returns> private object TryReadCollection(string path, Type type, Type[] typeInterfaces, string className, IDictionary <string, string> values, IReadOnlyDataStorer storer, LinkedList <IDataStorerEntry> entries, Dictionary <string, object> references) { // Tries get types of the collection and elements of the collection Type[] targetTypes = GetCollectionTypesCA(type, typeInterfaces, className); if (targetTypes == null) { // Target types are null -> collection isn't supported -> returns null return(null); } // Reads the information about of the collection Type collectionType = targetTypes[0]; Type elementType = targetTypes[1]; int count = Convert.ToInt32(values[CountString]); if (count != 0) { bool isPrimitive = values[PrimitiveString] == TrueString; if (!isPrimitive) { // Elements of the array/collection aren't primitive - reads the elements from different files IEnumerable enumerable = this.CreateCollection(collectionType, elementType, count); references.Add(path, enumerable); Array array = enumerable as Array; if (array != null) { // Reads the array for (int i = 0; i < count; i++) { array.SetValue(this.Read( elementType, StringUtils.Combine(path, i.ToString(), DirectorySeparatorString), storer, entries, references), i ); } return(enumerable); } else { // Reads the collection IList list = enumerable as IList; if (list != null) { // Collection implements IList interface - the interface should be used for the fast writing the elements of the collection for (int i = 0; i < count; i++) { list.Add(this.Read( elementType, StringUtils.Combine(path, i.ToString(), DirectorySeparatorString), storer, entries, references) ); } return(enumerable); } else { // Collection not implements IList interface - the collection writer should be used for the writing the elements of the collection using (CollectionWriter writer = new CollectionWriter(this, enumerable)) { for (int i = 0; i < count; i++) { writer.Add(this.Read( elementType, StringUtils.Combine(path, i.ToString(), DirectorySeparatorString), storer, entries, references) ); } } return(enumerable); } } } else { // Elements of the array/collection are primitive - reads the elements from single file byte[] data = ReadAndRemoveEntry(path, CollectionFileName, storer, entries); IEnumerable enumerable = this.GetPrimitiveCollection(data, collectionType, elementType, count); references.Add(path, enumerable); return(enumerable); } } else { // Collection is empty -> returns empty collection IEnumerable enumerable = this.CreateCollection(collectionType, elementType, 0); references.Add(path, enumerable); return(enumerable); } }