Files
cuetools.net/CUETools.AccurateRip/OffsetSafeCRCRecord.cs
2011-10-25 01:16:11 +00:00

148 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using CUETools.Codecs;
namespace CUETools.AccurateRip
{
[Serializable]
public class OffsetSafeCRCRecord
{
private uint[] val;
public OffsetSafeCRCRecord()
{
this.val = new uint[1];
}
public OffsetSafeCRCRecord(AccurateRipVerify ar)
: this(new uint[64 + 64])
{
int offset = 64 * 64;
for (int i = 0; i < 64; i++)
this.val[i] = ar.CTDBCRC(0, (i + 1) * 64, offset, 2 * offset);
for (int i = 0; i < 64; i++)
this.val[i + 64] = ar.CTDBCRC(0, 63 - i, offset, 2 * offset);
}
public OffsetSafeCRCRecord(uint[] val)
{
this.val = val;
}
[XmlIgnore]
public uint[] Value
{
get
{
return val;
}
}
public unsafe string Base64
{
get
{
byte[] res = new byte[val.Length * 4];
fixed (byte* pres = &res[0])
fixed (uint* psrc = &val[0])
AudioSamples.MemCpy(pres, (byte*)psrc, res.Length);
var b64 = new char[res.Length * 2 + 4];
int b64len = Convert.ToBase64CharArray(res, 0, res.Length, b64, 0);
StringBuilder sb = new StringBuilder(b64len + b64len / 4 + 1);
for (int i = 0; i < b64len; i += 64)
{
sb.Append(b64, i, Math.Min(64, b64len - i));
sb.AppendLine();
}
return sb.ToString();
}
set
{
if (value == null)
throw new ArgumentNullException();
byte[] bytes = Convert.FromBase64String(value);
if (bytes.Length % 4 != 0)
throw new InvalidDataException();
val = new uint[bytes.Length / 4];
fixed (byte* pb = &bytes[0])
fixed (uint* pv = &val[0])
AudioSamples.MemCpy((byte*)pv, pb, bytes.Length);
}
}
public override bool Equals(object obj)
{
return obj is OffsetSafeCRCRecord && this == (OffsetSafeCRCRecord)obj;
}
public override int GetHashCode()
{
return (int)val[0];
}
public static bool operator ==(OffsetSafeCRCRecord x, OffsetSafeCRCRecord y)
{
if (x as object == null || y as object == null) return x as object == null && y as object == null;
if (x.Value.Length != y.Value.Length) return false;
for (int i = 0; i < x.Value.Length; i++)
if (x.Value[i] != y.Value[i])
return false;
return true;
}
public static bool operator !=(OffsetSafeCRCRecord x, OffsetSafeCRCRecord y)
{
return !(x == y);
}
public bool DifferByOffset(OffsetSafeCRCRecord rec)
{
int offset;
return FindOffset(rec, out offset);
}
public bool FindOffset(OffsetSafeCRCRecord rec, out int offset)
{
if (this.Value.Length != 128 || rec.Value.Length != 128)
{
offset = 0;
return false;
//throw new InvalidDataException("Unsupported OffsetSafeCRCRecord");
}
for (int i = 0; i < 64; i++)
{
if (rec.Value[0] == Value[i])
{
offset = i * 64;
return true;
}
if (Value[0] == rec.Value[i])
{
offset = -i * 64;
return true;
}
for (int j = 0; j < 64; j++)
{
if (rec.Value[i] == Value[64 + j])
{
offset = i * 64 + j + 1;
return true;
}
if (Value[i] == rec.Value[64 + j])
{
offset = -i * 64 - j - 1;
return true;
}
}
}
offset = 0;
return false;
}
}
}