public void LoadSnapshot(ModuleDataSnapshot snapshot) { if (snapshot.SegmentCount != fieldsByFieldContainer.Count) { throw new ArgumentException($"Expected {fieldsByFieldContainer.Count} data segments; snapshot contains {snapshot.SegmentCount}"); } // Validate we have all the segments before we start mutating the fields. foreach (var container in fieldsByFieldContainer.Keys) { if (!snapshot.TryGetSegment(container.Address, out var segment)) { throw new ArgumentException($"Data does not contain segment for address {container.Address}"); } } foreach (var(fieldContainer, fieldList) in fieldsByFieldContainer) { var segment = snapshot[fieldContainer.Address]; originalSegmentsByFieldContainer[fieldContainer] = segment.Clone(); foreach (DataFieldBase field in fieldList) { field.Load(segment); } } }
public ModuleDataSnapshot CreateSnapshot() { var snapshot = new ModuleDataSnapshot(); foreach (var(fieldContainer, fieldList) in fieldsByFieldContainer) { snapshot.Add(CreateDataSegment(fieldContainer, fieldList)); } return(snapshot); }
/// <summary> /// Creates a new snapshot with all the segments in this one, but relocated /// such that the data is <paramref name="from"/> is moved to <paramref name="to"/> /// (and all other data is offset by the same amount). /// </summary> internal ModuleDataSnapshot Relocated(ModuleAddress from, ModuleAddress to) { var offset = to.LogicalValue - from.LogicalValue; var snapshot = new ModuleDataSnapshot(); foreach (var segment in Segments) { snapshot.Add(segment.WithAddress(segment.Address.PlusLogicalOffset(offset))); } return(snapshot); }
/// <summary> /// Loads data from a snapshot which could contain just part of the data contained /// in this object. This is internal as it's inherently somewhat dangerous - it should only be called /// for well-defined snapshots, e.g. "a whole kit". /// </summary> internal void LoadPartialSnapshot(ModuleDataSnapshot snapshot) { // TODO: This is more awkward than it should be, because we keep a map based on field containers rather than // addresses. We could change the map... then we might not need the FieldContainer.AddressComparer, either. foreach (var(container, fieldList) in fieldsByFieldContainer) { if (snapshot.TryGetSegment(container.Address, out var segment)) { foreach (DataFieldBase field in fieldList) { field.Load(segment); } } } }
internal ModuleDataSnapshot CreatePartialSnapshot(TreeNode root) { if (root.Container.Schema != Schema) { throw new ArgumentException("Invalid root for snapshot: incorrect schema"); } var fieldContainers = root.DescendantFieldContainers().ToList(); var snapshot = new ModuleDataSnapshot(); foreach (var fc in fieldContainers) { snapshot.Add(CreateDataSegment(fc, fieldsByFieldContainer[fc])); } return(snapshot); }
public void LoadSnapshot(ModuleDataSnapshot snapshot, ILogger logger) { if (snapshot.SegmentCount != fieldsByFieldContainer.Count) { throw new ArgumentException($"Expected {fieldsByFieldContainer.Count} data segments; snapshot contains {snapshot.SegmentCount}"); } // Validate we have all the segments before we start mutating the fields. foreach (var container in fieldsByFieldContainer.Keys) { if (!snapshot.TryGetSegment(container.Address, out var segment)) { throw new ArgumentException($"Data does not contain segment for address {container.Address}"); } } LoadPartialSnapshot(snapshot, logger); }
internal ModuleDataSnapshot CreatePartialSnapshot(TreeNode root) { if (root.Container.Schema != Schema) { throw new ArgumentException("Invalid root for snapshot: incorrect schema"); } if (!(root.Container is ContainerBase containerBase)) { throw new ArgumentException("Invalid root for snapshot: unknown container type"); } var fieldContainers = containerBase.DescendantsAndSelf().OfType <FieldContainer>().ToList(); var snapshot = new ModuleDataSnapshot(); foreach (var fc in fieldContainers) { snapshot.Add(CreateDataSegment(fc, fieldsByFieldContainer[fc])); } return(snapshot); }
/// <summary> /// Loads data from a snapshot which could contain just part of the data contained /// in this object. This is internal as it's inherently somewhat dangerous - it should only be called /// for well-defined snapshots, e.g. "a whole kit". /// </summary> internal void LoadPartialSnapshot(ModuleDataSnapshot snapshot, ILogger logger) { // TODO: This is more awkward than it should be, because we keep a map based on field containers rather than // addresses. We could change the map... then we might not need the FieldContainer.AddressComparer, either. foreach (var(container, fieldList) in fieldsByFieldContainer) { if (snapshot.TryGetSegment(container.Address, out var segment)) { originalSegmentsByFieldContainer[container] = segment.Clone(); foreach (DataFieldBase field in fieldList) { var errors = field.Load(segment); foreach (var error in errors) { // Just treat data validation errors as warnings; they're not *program* errors. logger.LogWarning(error.ToString()); } } } } }