Представление KUID Trainz объектом
trainz,
эксперименты,
работы,
программы,
dls,
будущее
Для грядущего проекта создан универсальный класс для работы с KUID в игре Trainz. Кому не известно, KUID это наподобие GUID. Это идентификатор дополнение в игре. Класс умеет парсить строковое значение в объект и обратно в строку. Поддерживаются обе версии (kuid и kuid2)
using System;
using System.Xml.Serialization;
using System.Text;
/// <summary>
/// <para>Универсальный класс по работе с KUID</para>
/// <para>Версия реализации - 1.0</para>
/// <para>Автор: Роман Безлепкин (Crypton)</para>
/// <para>© Crypton Technologies 2009, свободное распостранение с обязательной ссылой на источник</para>
/// </summary>
[Serializable]
public class Kuid {
/// <summary>
/// Идентификатор автора (kuid 1, 2)
/// </summary>
[XmlAttribute]
public long AuthodId = 0;
/// <summary>
/// Идентификатор содержимого (kuid 1, 2)
/// </summary>
[XmlAttribute]
public long ContentId = 0;
/// <summary>
/// <para>Идентификатор версии дополнения (kuid 2)</para>
/// <para>Согласно спецификации CCG2006, максимальное значение 127, после чего необходимо создать новый ContentId</para>
/// </summary>
[XmlAttribute]
public long VersionId = 0;
/// <summary>
/// <para>Версия формата KUID:</para>
/// <para>1.0 - формат типа <kuid:xxxx:yyyy></para>
/// <para>2.0 - формат типа <kuid2:xxxx:yyyy:vvv></para>
/// </summary>
[XmlAttribute]
public Version KuidVersion = new Version(1, 0);
/// <summary>
/// Инициализация класса
/// </summary>
public Kuid() {
}
/// <summary>
/// <para>Инициализация структуры данных с предопределенными данными</para>
/// <para>Создается KUID версии 1.0</para>
/// </summary>
/// <param name="authorid">Идентификатор автора</param>
/// <param name="contentid">Идентификатор дополнения</param>
public Kuid(long authorid, long contentid) {
this.AuthodId = authorid;
this.ContentId = contentid;
this.KuidVersion = new Version(1, 0);
}
/// <summary>
/// <para>Инициализация структуры данных с предопределенными данными</para>
/// <para>Создается KUID версии 2.0</para>
/// </summary>
/// <param name="authorid">Идентификатор автора</param>
/// <param name="contentid">Идентификатор дополнения</param>
/// <param name="versionid">Номер версии</param>
public Kuid(long authorid, long contentid, long versionid) {
this.AuthodId = authorid;
this.ContentId = contentid;
this.VersionId = versionid;
this.KuidVersion = new Version(2, 0);
}
/// <summary>
/// <para>Инициализация структуры из строки в формате <kuid...></para>
/// <para>При ошибке формата, выдаются исключения типа ArgumentException и FormatException</para>
/// </summary>
/// <param name="sKuid">KUID в формате <kuid...></param>
public Kuid(string sKuid) {
Kuid k;
parse(sKuid, out k, true);
this.AuthodId = k.AuthodId;
this.ContentId = k.ContentId;
this.KuidVersion = k.KuidVersion;
this.VersionId = k.VersionId;
}
/// <summary>
/// <para>Парсинг строкового значения kuid в объективный</para>
/// <para>Возвращается результат в параметре @out, и булевское значение от функции об успешности операции</para>
/// </summary>
/// <param name="sKuid">KUID в формате <kuid...></param>
/// <param name="out">Объективное представление об KUID где поместить выходные данные</param>
/// <returns></returns>
public bool TryParse(string sKuid, out Kuid @out) {
return parse(sKuid, out @out, false);
}
/// <summary>
/// <para>Парсинг строкового значения kuid в объективный</para>
/// <para>При ошибке выдаются исключения типа ArgumentException и FormatException</para>
/// </summary>
/// <param name="sKuid">KUID в формате <kuid...></param>
/// <returns></returns>
public Kuid Parse(string sKuid) {
Kuid k;
parse(sKuid, out k, true);
return k;
}
/// <summary>
/// Возвращает строкове представление об KUID согласно его версии
/// </summary>
/// <returns></returns>
public override string ToString() {
StringBuilder sb = new StringBuilder();
sb.Append("<");
if (this.KuidVersion.Major < 2)
sb.Append("kuid");
else
sb.Append("kuid2");
sb.Append(":");
sb.Append(this.AuthodId.ToString());
sb.Append(":");
sb.Append(this.ContentId.ToString());
if (this.KuidVersion.Major >= 2 && this.VersionId > 0) {
sb.Append(":");
sb.Append(this.VersionId.ToString());
}
sb.Append(">");
return sb.ToString();
}
/// <summary>
/// <para>Сверяет этот KUID с KUID k (проверка автора, идентификатора содержимого, и (при kuid2) версии</para>
/// <para>Возврат истины если все данные одинаковы</para>
/// </summary>
/// <param name="k">Проверка второго KUID относительно этого</param>
/// <returns></returns>
public override bool Equals(Kuid k) {
bool equal = false;
if (k.KuidVersion.Major == 1 && this.KuidVersion.Major == 1) {
equal = this.AuthodId.Equals(k.AuthodId) && this.ContentId.Equals(k.ContentId);
} else if (k.KuidVersion.Major >= 2 && this.KuidVersion.Major >= 2) {
equal = this.AuthodId.Equals(k.AuthodId) && this.ContentId.Equals(k.ContentId) && this.VersionId.Equals(k.VersionId);
} else
return false;
return equal;
}
/// <summary>
/// Возврат хэша объекта
/// </summary>
/// <returns></returns>
public override int GetHashCode() {
if (this.KuidVersion.Major < 2) {
return (int)(this.AuthodId.GetHashCode() ^ this.ContentId.GetHashCode());
} else {
return (int)(this.AuthodId.GetHashCode() ^ this.ContentId.GetHashCode() ^ this.VersionId.GetHashCode() ^ this.KuidVersion.Major.GetHashCode());
}
}
/// <summary>
/// Внутренняя реализация парсера. Возвращает булевское значение удачи парсинга (истина при удаче, ложь при неудаче)
/// </summary>
/// <param name="sKuid">куид</param>
/// <param name="out">вывод данных</param>
/// <param name="throwExceptions">истина разрешает на вывод исключений, ложь запрещает (функция возвращает false)</param>
/// <returns></returns>
bool parse(string sKuid, out Kuid @out, bool throwExceptions) {
string original = sKuid.Trim();
@out = new Kuid();
if (string.IsNullOrEmpty(sKuid.Trim())) {
if (throwExceptions) {
throw new ArgumentException("Строка sKuid пуста. Строка должна иметь формат согласно стандарту Trainz Kuid");
} else
return false;
}
sKuid = original.Replace(">", string.Empty).Replace("<", string.Empty); // удалить скобки
string[] kuidData = sKuid.Split(':'); // преобразовать куид в массив данных
if (kuidData.Length == 0 || kuidData.Length < 3) { // какие-то левые данные у нас (куид1 должен иметь 3 элемента, вот откуда тройка берется
if (throwExceptions) {
throw new FormatException("Строка sKuid имеет неверный формат. Поддерживаются форматы kuid (Trainz 2004, UTC) и kuid2 (2006 и выше). Входная строка: " + original);
} else
return false;
}
if (kuidData[0].Trim().ToLower().Equals("kuid")) {
@out.KuidVersion = new Version(1, 0);
} else if (kuidData[0].Trim().ToLower().Equals("kuid2")) {
@out.KuidVersion = new Version(2, 0);
}
if (!long.TryParse(kuidData[1].Trim(), out @out.AuthodId)) { // идентификатор автора
if (throwExceptions)
throw new FormatException("Запрещены не числовые значения в поле AUTHOR_ID, значение kuid:" + original);
else
return false;
}
if (!long.TryParse(kuidData[2].Trim(), out @out.ContentId)) { // идентификатор дополнения
if (throwExceptions)
throw new FormatException("Запрещены не числовые значения в поле CONTENT_ID, значение kuid:" + original);
else
return false;
}
@out.VersionId = 0;
if (@out.KuidVersion.Major >= 2 && kuidData.Length > 3) { // извлечь номер версии
if (!long.TryParse(kuidData[3].Trim(), out @out.VersionId)) {
if (throwExceptions)
throw new FormatException("Запрещены не числовые значения в поле VERSION_ID, значение kuid:" + original);
else
return false;
}
}
return true;
}
}
По теме: