Представление 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 - формат типа &lt;kuid:xxxx:yyyy&gt;</para>
    /// <para>2.0 - формат типа &lt;kuid2:xxxx:yyyy:vvv&gt;</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>Инициализация структуры из строки в формате &lt;kuid...&gt;</para>
    /// <para>При ошибке формата, выдаются исключения типа ArgumentException и FormatException</para>
    /// </summary>
    /// <param name="sKuid">KUID в формате &lt;kuid...&gt;</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 в формате &lt;kuid...&gt;</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 в формате &lt;kuid...&gt;</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;
    }
}

По теме: