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;
}
}
}
}