/// <summary> /// Sets the value in this struct but doesn't set if it would conflict with any other value offsets that have been set so far in which case it returns false instead. If there was exact same type of /// value at the same offset it can be replaced with this function. /// </summary> /// <param name="offset">The offset.</param> /// <param name="value">The value.</param> /// <returns></returns> /// <exception cref="System.ArgumentOutOfRangeException"> /// offset;Offset can not be negative! /// or /// offset;Offset can not exceed the size of struct! /// or /// offset;Offset + value.Size can not exceed the size of struct! /// </exception> /// <exception cref="System.ArgumentNullException">value</exception> /// <exception cref="System.InvalidOperationException"></exception> public bool SetValueSafe(int offset, MemoryStructField value) { if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "Offset can not be negative!"); } if (offset > this.Size) { throw new ArgumentOutOfRangeException("offset", "Offset can not exceed the size of struct!"); } if (offset + value.Size > this.Size) { throw new ArgumentOutOfRangeException("offset", "Offset + value.Size can not exceed the size of struct!"); } if (value == null) { throw new ArgumentNullException("value"); } value.Offset = offset; int begin = offset; int end = offset + value.Size; ulong p2 = 0; ulong p = value.Packed; for (int i = begin; i < end; i++) { p2 = this.Fields[i]; if (p2 == 0) { continue; } // Exact same type and offset and size of value. if (p2 == p) { break; } } if (value.Data == null) { throw new InvalidOperationException(); } for (int i = begin; i < end; i++) { this.Fields[i] = p; } Memory.WriteBytes(this.Allocation.Address + offset, value.Data); return(true); }
/// <summary> /// Sets the value in this struct but replaces any old values that may have conflicted with this offset and value size. /// </summary> /// <param name="offset">The offset.</param> /// <param name="value">The value.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// offset;Offset can not be negative! /// or /// offset;Offset can not exceed the size of struct! /// or /// offset;Offset + value.Size can not exceed the size of struct! /// </exception> /// <exception cref="System.ArgumentNullException">value</exception> /// <exception cref="System.InvalidOperationException"></exception> public void SetValue(int offset, MemoryStructField value) { if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "Offset can not be negative!"); } if (offset > this.Size) { throw new ArgumentOutOfRangeException("offset", "Offset can not exceed the size of struct!"); } if (offset + value.Size > this.Size) { throw new ArgumentOutOfRangeException("offset", "Offset + value.Size can not exceed the size of struct!"); } if (value == null) { throw new ArgumentNullException("value"); } if (value.Data == null) { throw new InvalidOperationException(); } value.Offset = offset; ulong p = value.Packed; int begin = offset; int end = offset + value.Size; for (int i = begin; i < end; i++) { if (this.Fields[i] != 0) { this.ClearValue(i); } this.Fields[i] = p; } Memory.WriteBytes(this.Allocation.Address + offset, value.Data); }
/// <summary> /// Get field data from packed value. /// </summary> /// <param name="packed">The packed.</param> /// <param name="obj">The object.</param> /// <returns></returns> internal static MemoryStructField FromPacked(ulong packed, MemoryStruct obj) { if (packed == 0) { return(null); } int offset = 0; int size = 0; byte type = 0; ReadPacked(packed, ref offset, ref size, ref type); var f = new MemoryStructField(); f.Offset = offset; f.Size = size; f.Type = (FieldTypes)type; f.Data = Memory.ReadBytes(obj.Address + offset, size); return(f); }
/// <summary> /// Gets the value at offset. The offset does not have to be exact beginning offset of value as long as the value would conflict with this offset it returns the result. Check result's offset /// for actual offset of value. /// </summary> /// <param name="offset">The offset.</param> /// <returns></returns> /// <exception cref="System.ArgumentOutOfRangeException"> /// offset;Offset can not be negative! /// or /// offset;Offset can not exceed the size of struct! /// </exception> public MemoryStructField GetValue(int offset) { if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "Offset can not be negative!"); } if (offset > this.Size) { throw new ArgumentOutOfRangeException("offset", "Offset can not exceed the size of struct!"); } ulong p = 0; if (offset == this.Size || (p = this.Fields[offset]) == 0) { return(null); } return(MemoryStructField.FromPacked(p, this)); }
/// <summary> /// Clears the value at offset. This will set it back to zero and remove any traces of it. /// </summary> /// <param name="offset">The offset.</param> /// <returns></returns> /// <exception cref="System.ArgumentOutOfRangeException"> /// offset;Offset can not be negative! /// or /// offset;Offset can not exceed the size of struct! /// </exception> public bool ClearValue(int offset) { if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "Offset can not be negative!"); } if (offset > this.Size) { throw new ArgumentOutOfRangeException("offset", "Offset can not exceed the size of struct!"); } if (offset == this.Size) { return(false); } ulong p = this.Fields[offset]; if (p == 0) { return(false); } int realOffset = 0; int realSize = 0; byte realType = 0; MemoryStructField.ReadPacked(p, ref realOffset, ref realSize, ref realType); int end = realOffset + realSize; for (int i = realOffset; i < end; i++) { this.Fields[i] = 0; } Memory.WriteZero(this.Allocation.Address + realOffset, realSize); return(true); }