#region CPL License /* Nuclex Framework Copyright (C) 2002-2009 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library 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 IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion using System; using System.Collections.Generic; using Nuclex.Support.Tracking; namespace Nuclex.Audio.Metadata { /// Connection to a CDDB compatible database server public class CddbConnection : IDisposable { #region struct ServerProtocolLevel /// /// Stores the active and, if available, maximum supported protocol level /// of a CDDB server /// public struct ServerProtocolLevel { /// Initializes a new CDDB server protocol level structure /// Active server protocol level to store /// /// Maximum support server protocol level to store /// public ServerProtocolLevel( int activeProtocolLevel, int? supportedProtocolLevel ) { this.ActiveProtocolLevel = activeProtocolLevel; this.SupportedProtocolLevel = supportedProtocolLevel; } /// Protocol level currently used by the CDDB server public int ActiveProtocolLevel; /// Maximum protocol level the CDDB server supports public int? SupportedProtocolLevel; } #endregion // struct ServerProtocolLevel /// Initializes a new CDDB server connection /// Protocol by which the CDDB server can be reached /// Host name of the connected CDDB server /// Version of the CDDB software running on the server /// Whether the server has restricted us to read access internal CddbConnection( CddbProtocol protocol, string hostname, string version, bool readOnly ) { this.protocol = protocol; this.hostname = hostname; this.version = version; this.readOnly = readOnly; // This is not documented in the CDDB protocol specification, but all servers // I tested it with begin a new connection with protocol level 1. This also // is the only valid choice if the server wants to keep backward compatibility. this.activeProtocolLevel = 1; } /// Immediately releases all resources owned by the instance public void Dispose() { if(this.protocol != null) { this.protocol.Dispose(); this.protocol = null; } } /// Logs out from the server and closes the connection /// A request by which the log out process can be tracked /// /// You should call this method and wait for the request to finish before /// disposing of the connection to gracefully leave the CDDB server. /// public Request Quit() { Requests.CddbQuitRequest request = new Requests.CddbQuitRequest( this.protocol ); request.Start(); return request; } /// Lists the genre categories known to the CDDB server /// A request that will provide the genre list upon completion public Request ListCategories() { Requests.CddbCategoryListRequest request = new Requests.CddbCategoryListRequest( this.protocol ); request.Start(); return request; } /// Retrieves the protocol level currently used by the CDDB server /// /// A request that will provide the active protocol level upon completion /// public Request GetProtocolLevel() { Requests.CddbProtocolLevelRequest request = new Requests.CddbProtocolLevelRequest( this.protocol ); request.Start(); return request; } /// Changes the protocol level used by the CDDB server connection /// New protocol level to switch to /// /// A request that will indicate when the protocol level has been changed /// public Request ChangeProtocolLevel(int newLevel) { Requests.CddbProtocolLevelRequest request = new Requests.CddbProtocolLevelRequest( this.protocol, newLevel, new Requests.CddbProtocolLevelRequest.ProtocolLevelNotificationDelegate( protocolLevelChanged ) ); request.Start(); return request; } /// /// Queries the CDDB server for informations about the specified disc /// /// Total length of the CD in seconds /// /// Track offsets, in seconds, for each track of the CD /// /// A request that will provide the query results upon completion public Request Query( int discLengthSeconds, int[] trackOffsetsSeconds ) { Requests.CddbQueryRequest request = new Requests.CddbQueryRequest( this.protocol, discLengthSeconds, trackOffsetsSeconds ); request.Start(); return request; } /// Reads the CDDB entry for the specified CD /// Category in which the CD's CDDB entry is stored /// Disc id of the CD whose CDDB entry will be read /// A request that will provide the CDDB entry upon completion /// /// The CDDB specification requires you to first execute a query and only then /// use the read command to retrieve a database file. Otherwise, the data being /// returned is undefined. /// public Request Read(string category, int discId) { Requests.CddbReadRequest request = new Requests.CddbReadRequest( this.protocol, category, discId ); request.Start(); return request; } /// Hostname of the server to which the connection was made public string Hostname { get { return this.hostname; } } /// Version of the CDDB software running on the server public string Version { get { return this.version; } } /// /// Whether the client has been restricted to read access by the server /// public bool ReadOnly { get { return this.readOnly; } } /// Currently active protocol level for the connection public int ProtocolLevel { get { return this.activeProtocolLevel; } } /// Called when the active protocol level has been changed /// New protocol level the connection is using private void protocolLevelChanged(int newLevel) { bool wasUtf = (this.activeProtocolLevel >= 6); bool isUtf = (newLevel >= 6); this.activeProtocolLevel = newLevel; if(wasUtf != isUtf) { this.protocol.UseUtf8 = isUtf; } } /// Protocol used to communicate with the CDDB server private CddbProtocol protocol; /// Hostname the server reported in the greeting string private string hostname; /// Version of the CDDB software supposedly running on the server private string version; /// Whether this client is in read-only mode private bool readOnly; /// Currently active protocol level for the connection private volatile int activeProtocolLevel; } } // namespace Nuclex.Audio.Metadata