/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Xml; using System.Diagnostics; using ModernKeePassLib.Utility; namespace ModernKeePassLib { // [ImmutableObject(true)] /// /// Represents an UUID of a password entry or group. Once created, PwUuid /// objects aren't modifyable anymore (immutable). /// public sealed class PwUuid { /// /// Standard size in bytes of a UUID. /// public const uint UuidSize = 16; /// /// Zero UUID (all bytes are zero). /// public static readonly PwUuid Zero = new PwUuid(); private byte[] m_pbUuid = new byte[UuidSize]; /// /// Get the 16 UUID bytes. /// public byte[] UuidBytes { get { return m_pbUuid; } } /// /// Construct a new UUID object. Its value is initialized to zero. /// private PwUuid() { SetZero(); } /// /// Construct a new UUID object. /// /// If this parameter is true, a new /// UUID is generated. If it is false, the UUID is initialized /// to zero. public PwUuid(bool bCreateNew) { if(bCreateNew) CreateNew(); else SetZero(); } /// /// Construct a new UUID object. /// /// Initial value of the PwUuid object. public PwUuid(byte[] uuidBytes) { SetValue(uuidBytes); } /// /// Create a new, random UUID. /// /// Returns true if a random UUID has been generated, /// otherwise it returns false. private void CreateNew() { while(true) { m_pbUuid = Guid.NewGuid().ToByteArray(); if((m_pbUuid == null) || (m_pbUuid.Length != UuidSize)) throw new InvalidOperationException(); // Zero is a reserved value -- do not generate Zero if(this.EqualsValue(PwUuid.Zero) == false) break; } } /// /// Compare this UUID with another. /// /// Second UUID object. /// Returns true if both PwUuid object contain the same /// value, otherwise false is returned. public bool EqualsValue(PwUuid uuid) { Debug.Assert(uuid != null); if(uuid == null) throw new ArgumentNullException("uuid"); for(int i = 0; i < UuidSize; ++i) { if(m_pbUuid[i] != uuid.m_pbUuid[i]) return false; } return true; } /// /// Convert the UUID to its string representation. /// /// String containing the UUID value. public string ToHexString() { return MemUtil.ByteArrayToHexString(m_pbUuid); } /// /// Set the UUID value. The input parameter will not be modified. /// /// UUID bytes. The byte array must contain /// exactly UUIDSize bytes, otherwise the function will fail. private void SetValue(byte[] uuidBytes) { Debug.Assert((uuidBytes != null) && (uuidBytes.Length == UuidSize)); if(uuidBytes == null) throw new ArgumentNullException("uuidBytes"); if(uuidBytes.Length != UuidSize) throw new ArgumentException(); Array.Copy(uuidBytes, m_pbUuid, (int)UuidSize); } /// /// Set the UUID value to zero. /// private void SetZero() { Array.Clear(m_pbUuid, 0, (int)UuidSize); } } public sealed class PwUuidComparable : IComparable { private byte[] m_pbUuid = new byte[PwUuid.UuidSize]; public PwUuidComparable(PwUuid pwUuid) { if(pwUuid == null) throw new ArgumentNullException("pwUuid"); Array.Copy(pwUuid.UuidBytes, m_pbUuid, (int)PwUuid.UuidSize); } public int CompareTo(PwUuidComparable other) { if(other == null) throw new ArgumentNullException("other"); for(int i = 0; i < (int)PwUuid.UuidSize; ++i) { if(m_pbUuid[i] < other.m_pbUuid[i]) return -1; if(m_pbUuid[i] > other.m_pbUuid[i]) return 1; } return 0; } } }