protected override void OnSubmit(IXReadOperation reader, object obj) { if (obj != null && Identifier.CanId(obj.GetType())) { object id = Identifier.GetId(obj); if (id != null) { Submit(id, obj); } else { reader.AddTask(this, () => { object id2 = Identifier.GetId(obj); if (id2 != null) { Submit(id2, obj); return(true); } return(false); }); } } }
protected override bool OnRead <T>(IXReadOperation reader, XType <T> xType, XAttribute attribute, Func <object, bool> assign, XObjectArgs args) { Type type = typeof(T); if (Identifier.CanId(type)) { string text = attribute.Value; if (!string.IsNullOrWhiteSpace(text) && text.Length > 0) { reader.AddTask(this, () => { if (referenceObjects.TryGetValue(text, out object refObject)) { if (refObject == null || refObject.GetType() == type) { return(assign(refObject)); } else { throw new InvalidOperationException( $"Possible collision: the reference object with ID {text} was of expected type {type.Name}, " + $"but that ID resolved to an object of type {refObject.GetType().Name}."); } } return(false); }); return(true); } } return(false); }
protected override void OnBuild(XType <T[]> xType, IXReadOperation reader, XElement element, ObjectBuilder <T[]> objectBuilder) { if (!element.HasElements) { return; } IEnumerable <XElement> itemElements = ItemsAsElements ? element.Elements() : element.Elements(ItemName); T[] array = new T[itemElements.Count()]; if (array.Length > 0) { int i = 0; foreach (XElement subElement in itemElements) { int idx = i++; reader.Read <T>(subElement, x => { array[i] = x; return(true); }, ReaderHints.IgnoreElementName); } } }
protected override void OnBuild(IXReadOperation reader, XElement element, ObjectBuilder <LinkedListNode <T> > objectBuilder, XObjectArgs args) => reader.Read <T>(element, x => { objectBuilder.Object = new LinkedListNode <T>(x); return(true); }, args ?? XObjectArgs.DefaultIgnoreElementName);
protected override void OnBuild(IXReadOperation reader, XElement element, ObjectBuilder <ReadOnlyDictionary <TKey, TValue> > objectBuilder, XObjectArgs args) => reader.Read <Dictionary <TKey, TValue> >(element, x => { objectBuilder.Object = new ReadOnlyDictionary <TKey, TValue>(x); return(true); }, args ?? XObjectArgs.DefaultIgnoreElementName);
internal bool Read(IXReadOperation reader, XAttribute attribute, out T result, XObjectArgs args) { T compResult = default; if (ForEachComponent(x => x.Read(reader, attribute, out compResult, args))) { result = compResult; return(true); } result = compResult; return(false); }
protected override void OnBuild(IXReadOperation reader, XElement element, ObjectBuilder <T[, ]> objectBuilder, XObjectArgs args) { // Read as a jagged array T[][] jagged = null; reader.Read <T[][]>(element, x => { jagged = x; return(true); }); // Convert to a multidimensional array once read reader.AddTask(this, () => { if (jagged == null) { return(false); } int lb0 = jagged.GetLowerBound(0), n0 = jagged.Length; int lb1, n1; if (n0 > 0) { lb1 = jagged[0].GetLowerBound(0); n1 = jagged[0].Length; } else { lb1 = 0; n1 = 0; } objectBuilder.Object = (T[, ])Array.CreateInstance(typeof(T), new int[2] { n0, n1 }, new int[2] { lb0, lb1 }); for (int i = lb0, I = lb0 + n0; i < I; i++) { for (int j = lb1, J = lb1 + n1; j < J; j++) { objectBuilder.Object[i, j] = jagged[i][j]; } } return(true); }); }
protected override void OnBuild(XType <KeyValuePair <TKey, TValue> > xType, IXReadOperation reader, XElement element, ObjectBuilder <KeyValuePair <TKey, TValue> > objectBuilder, XObjectArgs args) { XName keyName = XComponents.Component <XAutoCollections>().KeyName, valueName = XComponents.Component <XAutoCollections>().ValueName; XElement keyElement = element.Element(keyName); if (keyElement == null) { return; } bool foundKey = false, foundValue = false; TKey key = default; TValue value = default; reader.Read <TKey>(keyElement, x => { key = x; return(foundKey = true); }, XObjectArgs.DefaultIgnoreElementName); XElement valueElement = element.Element(valueName); if (valueElement != null) { reader.Read <TValue>(valueElement, x => { value = x; return(foundValue = true); }, XObjectArgs.DefaultIgnoreElementName); } else { foundValue = true; } reader.AddTask(this, () => { if (foundKey && foundValue) { objectBuilder.Object = new KeyValuePair <TKey, TValue>(key, value); return(true); } return(false); }); }
internal bool Read <T>(IXReadOperation reader, XType <T> xType, XElement element, Func <object, bool> assign, XObjectArgs args) => OnRead(reader, xType, element, assign, args);
internal void Build(IXReadOperation reader, XElement element, ObjectBuilder <T> objectBuilder, XObjectArgs args) => ForEachComponent(x => x.Build(reader, element, objectBuilder, args));
protected override bool OnRead <T>(IXReadOperation reader, XType <T> xType, XElement element, Func <object, bool> assign, XObjectArgs args) { Type type = typeof(T); // A serialized reference has no attributes, no elements, some text, is of a type that can be ID'd, // and not of a type that has a registered XTexter string value = element.Value; if (!element.HasAttributes && !element.HasElements && !string.IsNullOrEmpty(value) && xType.Component <XTexter <T> >() == null && Identifier.CanId(type, out Type idType)) { bool idFound = false; object id = null; reader.Read(element, idType, x => { idFound = true; if (!Identifier.KeyComparer.Equals(x, ReflectionTools.GetDefaultValue(idType))) { id = x; } return(true); }, XObjectArgs.DefaultIgnoreElementName); // Schedule a task to assign the object if it shows up in the dictionary reader.AddTask(this, () => { if (!idFound) { return(false); } if (id == null) { return(true); } if (referenceObjects.TryGetValue(id, out object refObject)) { if (refObject == null || type == refObject.GetType()) { return(assign(refObject)); } else { throw new InvalidOperationException( $"Possible collision: the reference object with ID {id} was of expected type {type.Name}, " + $"but that ID resolved to an object of type {refObject.GetType().Name}."); } } return(false); }); return(true); } return(false); }
/// <summary> /// Implement this method to build (read) an object of type <typeparamref name="T"/> from the <see cref="XElement"/> /// <paramref name="element"/> where it was serialized. /// </summary> /// <param name="xType">The <see cref="XType{T}"/> instance from the current <see cref="XDomain"/>.</param> /// <param name="reader">An <see cref="IXReadOperation"/> instance for deserializing XML and scheduling tasks.</param> /// <param name="element">The <see cref="XElement"/> to be read as an instance of <typeparamref name="T"/>.</param> /// <param name="objectBuilder">An <see cref="ObjectBuilder{T}"/> to contain the constructed <typeparamref name="T"/>.</param> /// <param name="args">Optional arguments with information about XML formatting.</param> protected abstract void OnBuild(XType <T> xType, IXReadOperation reader, XElement element, ObjectBuilder <T> objectBuilder, XObjectArgs args);
internal void Build(XType <T> xType, IXReadOperation reader, XElement element, ObjectBuilder <T> objectBuilder, XObjectArgs args) => OnBuild(xType, reader, element, objectBuilder, args);
internal void Submit(IXReadOperation reader, object obj) => OnSubmit(reader, obj);
protected override void OnBuild(XType <T> xType, IXReadOperation reader, XElement element, ObjectBuilder <T> objectBuilder, XObjectArgs args) => readMethod(xType, reader, element, objectBuilder, args);
internal bool Read <T>(IXReadOperation reader, XType <T> xType, XAttribute attribute, Func <object, bool> assign, XObjectArgs args) => OnRead(reader, xType, attribute, assign, args);
protected override void OnBuild(IXReadOperation reader, XElement element, ObjectBuilder <T[]> objectBuilder, XObjectArgs args) { XCollectionArgs collectionArgs = args as XCollectionArgs ?? new XCollectionArgs(default, ItemsAsElements, ItemName);
/// <summary> /// Called whenever an object is submitted to the <see cref="XReader"/>, which occurs either because the user /// has submitted a contextual object or because a deserialized object was successfully constructed. /// </summary> /// <param name="reader">An <see cref="IXReadOperation"/> instance that exposes methods for reading XML and /// scheduling tasks using the active <see cref="XReader"/>.</param> /// <param name="obj">The object that was submitted.</param> protected virtual void OnSubmit(IXReadOperation reader, object obj) { }
/// <summary> /// Called when the <see cref="XReader"/> has arrived at an <see cref="XAttribute"/> expecting an object of type /// <typeparamref name="T"/>, but before <see cref="XTypeComponent{T}"/>s have attempted deserialization. /// </summary> /// <param name="reader">An <see cref="IXReadOperation"/> instance that exposes methods for reading XML and /// scheduling tasks using the active <see cref="XReader"/>.</param> /// <param name="xType">An <see cref="XType{T}"/> reflected from the <see cref="XDomain"/> to which this /// <see cref="XReader"/> belongs.</param> /// <param name="attribute">The <see cref="XAttribute"/> to be read.</param> /// <param name="assign">A delegate to perform on the deserialized <typeparamref name="T"/>. If it returns <c>false</c>, /// it will be added to the task queue and repeatedly attempted until it returns <c>true</c>.</param> /// <param name="args">Optional arguments to communicate to components how <paramref name="attribute"/> should be /// read.</param> /// <returns><c>True</c> if the <see cref="XReaderComponent"/> fully deserialized the object and all further /// processing of <paramref name="attribute"/> should stop.</returns> protected virtual bool OnRead <T>(IXReadOperation reader, XType <T> xType, XAttribute attribute, Func <object, bool> assign, XObjectArgs args) => false;
/// <summary> /// Called when the <see cref="XReader"/> has arrived at an <see cref="XElement"/> expecting an object of type /// <typeparamref name="T"/>, but before <see cref="XTypeComponent{T}"/>s have attempted deserialization. /// </summary> /// <param name="reader">An <see cref="IXReadOperation"/> instance that exposes methods for reading XML and /// scheduling tasks using the active <see cref="XReader"/>.</param> /// <param name="xType">An <see cref="XType{T}"/> reflected from the <see cref="XDomain"/> to which this /// <see cref="XReader"/> belongs.</param> /// <param name="element">The <see cref="XElement"/> to be read.</param> /// <param name="assign">A delegate to perform on the deserialized <typeparamref name="T"/>. If it returns <c>false</c>, /// it will be added to the task queue and repeatedly attempted until it returns <c>true</c>.</param> /// <param name="args">Optional arguments to communicate to components how <paramref name="element"/> should be /// read.</param> /// <returns><c>True</c> if the <see cref="XReaderComponent"/> fully deserialized the object and all further /// processing of <paramref name="element"/> should stop.</returns> protected virtual bool OnRead <T>(IXReadOperation reader, XType <T> xType, XElement element, Func <object, bool> assign, XObjectArgs args) => false;