NBTExplorer/SubstrateCS/Source/Core/NibbleArray.cs

255 lines
6 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
namespace Substrate.Core
{
public class NibbleArray : IDataArray, ICopyable<NibbleArray>
{
private readonly byte[] _data = null;
public NibbleArray (int length)
{
_data = new byte[(int)Math.Ceiling(length / 2.0)];
}
public NibbleArray (byte[] data)
{
_data = data;
}
public int this[int index]
{
get
{
int subs = index >> 1;
if ((index & 1) == 0)
{
return (byte)(_data[subs] & 0x0F);
}
else
{
return (byte)((_data[subs] >> 4) & 0x0F);
}
}
set
{
int subs = index >> 1;
if ((index & 1) == 0)
{
_data[subs] = (byte)((_data[subs] & 0xF0) | (value & 0x0F));
}
else
{
_data[subs] = (byte)((_data[subs] & 0x0F) | ((value & 0x0F) << 4));
}
}
}
public int Length
{
get { return _data.Length << 1; }
}
public int DataWidth
{
get { return 4; }
}
protected byte[] Data
{
get { return _data; }
}
public void Clear ()
{
for (int i = 0; i < _data.Length; i++)
{
_data[i] = 0;
}
}
#region ICopyable<NibbleArray> Members
public virtual NibbleArray Copy ()
{
byte[] data = new byte[_data.Length];
_data.CopyTo(data, 0);
return new NibbleArray(data);
}
#endregion
}
public sealed class XZYNibbleArray : NibbleArray, IDataArray3
{
private readonly int _xdim;
private readonly int _ydim;
private readonly int _zdim;
public XZYNibbleArray (int xdim, int ydim, int zdim)
: base(xdim * ydim * zdim)
{
_xdim = xdim;
_ydim = ydim;
_zdim = zdim;
}
public XZYNibbleArray (int xdim, int ydim, int zdim, byte[] data)
: base(data)
{
_xdim = xdim;
_ydim = ydim;
_zdim = zdim;
if (xdim * ydim * zdim != data.Length * 2)
{
throw new ArgumentException("Product of dimensions must equal half length of raw data");
}
}
public int this[int x, int y, int z]
{
get
{
int index = _ydim * (x * _zdim + z) + y;
return this[index];
}
set
{
int index = _ydim * (x * _zdim + z) + y;
this[index] = value;
}
}
public int XDim
{
get { return _xdim; }
}
public int YDim
{
get { return _ydim; }
}
public int ZDim
{
get { return _zdim; }
}
public int GetIndex (int x, int y, int z)
{
return _ydim * (x * _zdim + z) + y;
}
public void GetMultiIndex (int index, out int x, out int y, out int z)
{
int yzdim = _ydim * _zdim;
x = index / yzdim;
int zy = index - (x * yzdim);
z = zy / _ydim;
y = zy - (z * _ydim);
}
#region ICopyable<NibbleArray> Members
public override NibbleArray Copy ()
{
byte[] data = new byte[Data.Length];
Data.CopyTo(data, 0);
return new XZYNibbleArray(_xdim, _ydim, _zdim, data);
}
#endregion
}
public sealed class YZXNibbleArray : NibbleArray, IDataArray3
{
private readonly int _xdim;
private readonly int _ydim;
private readonly int _zdim;
public YZXNibbleArray (int xdim, int ydim, int zdim)
: base(xdim * ydim * zdim)
{
_xdim = xdim;
_ydim = ydim;
_zdim = zdim;
}
public YZXNibbleArray (int xdim, int ydim, int zdim, byte[] data)
: base(data)
{
_xdim = xdim;
_ydim = ydim;
_zdim = zdim;
if (xdim * ydim * zdim != data.Length * 2) {
throw new ArgumentException("Product of dimensions must equal half length of raw data");
}
}
public int this[int x, int y, int z]
{
get
{
int index = _xdim * (y * _zdim + z) + x;
return this[index];
}
set
{
int index = _xdim * (y * _zdim + z) + x;
this[index] = value;
}
}
public int XDim
{
get { return _xdim; }
}
public int YDim
{
get { return _ydim; }
}
public int ZDim
{
get { return _zdim; }
}
public int GetIndex (int x, int y, int z)
{
return _xdim * (y * _zdim + z) + x;
}
public void GetMultiIndex (int index, out int x, out int y, out int z)
{
int xzdim = _xdim * _zdim;
y = index / xzdim;
int zx = index - (y * xzdim);
z = zx / _xdim;
x = zx - (z * _xdim);
}
#region ICopyable<NibbleArray> Members
public override NibbleArray Copy ()
{
byte[] data = new byte[Data.Length];
Data.CopyTo(data, 0);
return new YZXNibbleArray(_xdim, _ydim, _zdim, data);
}
#endregion
}
}