using System; using System.Text; using GeViSetEditor.Core.Models; namespace GeViSetEditor.Core.Parsers { /// /// Modifies configuration in-place to preserve binary structure /// Safer approach for edit operations /// public class InPlaceConfigModifier { /// /// Modify a node's value in the original data array /// Only works for fixed-size types (boolean, integer) /// public bool ModifyNode(byte[] data, ConfigNode node, object newValue) { if (node == null || data == null) return false; switch (node.NodeType) { case "boolean": return ModifyBoolean(data, node, newValue); case "integer": return ModifyInteger(data, node, newValue); case "string": // Strings are variable length - can only modify if same length return ModifyString(data, node, newValue); default: return false; } } private bool ModifyBoolean(byte[] data, ConfigNode node, object newValue) { try { // Boolean structure: 01 // Value is at StartOffset + 1 int valueOffset = node.StartOffset + 1; if (valueOffset >= data.Length) return false; bool boolValue = Convert.ToBoolean(newValue); data[valueOffset] = boolValue ? (byte)1 : (byte)0; // Update node value node.Value = boolValue; return true; } catch { return false; } } private bool ModifyInteger(byte[] data, ConfigNode node, object newValue) { try { // Integer structure: 04 // Value is at StartOffset + 1 int valueOffset = node.StartOffset + 1; if (valueOffset + 4 > data.Length) return false; int intValue = Convert.ToInt32(newValue); byte[] bytes = BitConverter.GetBytes(intValue); Array.Copy(bytes, 0, data, valueOffset, 4); // Update node value node.Value = intValue; return true; } catch { return false; } } private bool ModifyString(byte[] data, ConfigNode node, object newValue) { try { // String structure: 07 // Original length at StartOffset + 1 int lengthOffset = node.StartOffset + 1; if (lengthOffset >= data.Length) return false; byte originalLength = data[lengthOffset]; string newString = newValue?.ToString() ?? ""; byte[] newBytes = Encoding.UTF8.GetBytes(newString); // Can only modify if new string has same length if (newBytes.Length != originalLength) { Console.WriteLine($" ⚠ Cannot modify string: length mismatch (original={originalLength}, new={newBytes.Length})"); return false; } // Copy new string data int dataOffset = lengthOffset + 1; Array.Copy(newBytes, 0, data, dataOffset, newBytes.Length); // Update node value node.Value = newString; return true; } catch { return false; } } /// /// Check if a node can be modified in-place /// public bool CanModify(ConfigNode node, object newValue) { if (node == null) return false; switch (node.NodeType) { case "boolean": case "integer": return true; case "string": // String can only be modified if same length string currentStr = node.Value?.ToString() ?? ""; string newStr = newValue?.ToString() ?? ""; return Encoding.UTF8.GetByteCount(currentStr) == Encoding.UTF8.GetByteCount(newStr); default: return false; } } } }