示例#1
0
 /// <summary>
 ///   Initializes a new CDDB protocol level request for changing of
 ///   the current protocol level
 /// </summary>
 /// <param name="protocol">
 ///   Protocol used to communication with the CDDB server
 /// </param>
 /// <param name="newLevel">New protocol level that will be set</param>
 /// <param name="callback">
 ///   Callback to be invoked as soon as the new protocol level is set
 /// </param>
 public CddbProtocolLevelRequest(
   CddbProtocol protocol, int newLevel, ProtocolLevelNotificationDelegate callback
 ) {
   this.protocol = protocol;
   this.newLevel = newLevel;
   this.callback = callback;
 }
示例#2
0
    /// <summary>Queries the server for its active protocol level</summary>
    private void queryProtocolLevel() {

      // Issue the command to the CDDB server
      this.protocol.SendLine("proto", 5000);

      // Receive the reply from the server
      string statusLine = this.protocol.ReceiveLine(5000);

      // Obtain the status code returned by the server
      int statusCode = CddbProtocol.GetStatusCode(statusLine);

      // Decode the server reply
      switch(statusCode) {
        case 200: {
          this.protocolLevel = decodeDetailedProtocolLevel(statusLine);
          break;
        }
        case 201: {
          this.protocolLevel = decodeShortProtocolLevel(statusLine);
          break;
        }
        default: {
          this.exception = exceptionFromProtocolStatus(
            statusCode, statusLine.Substring((statusLine.Length >= 4) ? 4 : 3)
          );
          break;
        }
      }

    }
示例#3
0
    /// <summary>Called asynchronously to execute the request</summary>
    /// <param name="state">Not used</param>
    private void execute(object state) {
      lock(this.protocol.SyncRoot) {
        try {
          this.protocol.SendLine(
            string.Format("cddb read {0} {1:x8} ", this.category, this.discId),
            5000
          );

          // The first reply will indicate the status of the request.
          string statusLine = this.protocol.ReceiveLine(5000);
          int statusCode = CddbProtocol.GetStatusCode(statusLine);

          switch(statusCode) {
            case 210: {
              this.results = receiveDatabaseFile();
              break;
            }
            default: {
              this.exception = exceptionFromQueryStatus(
                statusCode, statusLine.Substring((statusLine.Length >= 4) ? 4 : 3)
              );
              break;
            }
          }

        }
        catch(Exception exception) {
          if(!(this.exception is AbortedException)) {
            this.exception = exception;
          }
        }
      }

      OnAsyncEnded();
    }
示例#4
0
 /// <summary>Initializes a new CDDB database read request</summary>
 /// <param name="protocol">
 ///   Protocol used to communication with the CDDB server
 /// </param>
 /// <param name="category">Category in which the CD's CDDB entry is stored</param>
 /// <param name="discId">Disc id of the CD whose CDDB entry will be read</param>
 public CddbReadRequest(
   CddbProtocol protocol, string category, int discId
 ) {
   this.protocol = protocol;
   this.category = category;
   this.discId = discId;
 }
    /// <summary>Called asynchronously to execute the request</summary>
    /// <param name="state">Not used</param>
    private void execute(object state) {
      lock(this.protocol.SyncRoot) {
        try {
          this.protocol.SendLine("quit", 5000);

          // The first reply will indicate the status of the request.
          string statusLine = this.protocol.ReceiveLine(5000);
          int statusCode = CddbProtocol.GetStatusCode(statusLine);

          switch(statusCode) {
            case 230: {
              break;
            }
            default: {
              this.exception = exceptionFromQueryStatus(
                statusCode, statusLine.Substring((statusLine.Length >= 4) ? 4 : 3)
              );
              break;
            }
          }

        }
        catch(Exception exception) {
          this.exception = exception;
        }

        // Close the connection, whether an error occured or not
        this.protocol.Dispose();
      }

      OnAsyncEnded();
    }
示例#6
0
 /// <summary>Initializes a new CDDB disc query request</summary>
 /// <param name="protocol">
 ///   Protocol used to communication with the CDDB server
 /// </param>
 /// <param name="discLengthSeconds">
 ///   Total length of the CD (from the beginning of the first track to the end of the
 ///   last track) in seconds
 /// </param>
 /// <param name="trackOffsetsSeconds">
 ///   Offsets of the individual tracks on the CD in seconds
 /// </param>
 public CddbQueryRequest(
   CddbProtocol protocol, int discLengthSeconds, int[] trackOffsetsSeconds
 ) {
   this.protocol = protocol;
   this.discLengthSeconds = discLengthSeconds;
   this.trackOffsetsSeconds = trackOffsetsSeconds;
 }
    /// <summary>Aborts the running process. Can be called from any thread.</summary>
    /// <remarks>
    ///   The receiver should honor the abort request and stop whatever it is
    ///   doing as soon as possible. The method does not impose any requirement
    ///   on the timeliness of the reaction of the running process, but implementers
    ///   are advised to not ignore the abort request and urged to try and design
    ///   their code in such a way that it can be stopped in a reasonable time
    ///   (eg. within 1 second of the abort request).
    /// </remarks>
    public void AsyncAbort() {
      if(this.protocol != null) {
        CddbProtocol theProtocol = this.protocol;
        this.protocol = null;

        theProtocol.Dispose();
      }
    }
示例#8
0
    /// <summary>Receives the repy to the 'hello' and validates it</summary>
    private void receiveHelloReply() {
      string replyLine = this.protocol.ReceiveLine(5000);

      int statusCode = CddbProtocol.GetStatusCode(replyLine);
      this.exception = exceptionFromHelloResponseStatus(
        statusCode, replyLine.Substring((replyLine.Length >= 4) ? 4 : 3)
      );
    }
示例#9
0
    /// <summary>Aborts the running process. Can be called from any thread.</summary>
    /// <remarks>
    ///   The receiver should honor the abort request and stop whatever it is
    ///   doing as soon as possible. The method does not impose any requirement
    ///   on the timeliness of the reaction of the running process, but implementers
    ///   are advised to not ignore the abort request and urged to try and design
    ///   their code in such a way that it can be stopped in a reasonable time
    ///   (eg. within 1 second of the abort request).
    /// </remarks>
    public void AsyncAbort() {
      if(this.protocol != null) {
        CddbProtocol theProtocol = this.protocol;
        this.protocol = null;

        this.exception = new AbortedException("Aborted on user request");

        theProtocol.Dispose();
      }
    }
示例#10
0
    /// <summary>
    ///   Performs the client/server handshake upon connecting to a CDDB server
    /// </summary>
    /// <param name="status">Not used</param>
    private void performClientServerHandshake(object status) {
      try {
        this.protocol = new CddbProtocol(this.socket);

        // Receive the server greeting string. This is sent by the CDDB server to
        // any client as soon as it connects and contains the server status and
        // software running on the server
        string greetingLine = this.protocol.ReceiveLine(5000);

        OnProgressAchieved(0.6f);

        // Obtain the status code returned from the server and convert it to
        // an exception if it indicates an error
        int greetingStatusCode = CddbProtocol.GetStatusCode(greetingLine);
        this.exception = exceptionFromGreetingStatus(
          greetingStatusCode, greetingLine.Substring((greetingLine.Length >= 4) ? 4 : 3)
        );

        // If no error has occured, decode the server greeting string
        if(this.exception == null) {
          ServerGreeting greeting = decodeServerGreeting(greetingLine);

          // The server greeting was decoded successfully, now let's identify ourselves
          // to the CDDB server
          sendHello();

          OnProgressAchieved(0.8f);

          // Receive the reply to our 'hello' from the server
          receiveHelloReply();

          // If everything went fine the CDDB connection is ready to enter normal service
          if(this.exception == null) {
            this.connection = new CddbConnection(
              protocol,
              greeting.Hostname,
              greeting.Version,
              (greetingStatusCode == 201) // Read only connection?
            );
          }
        }
      }
      catch(ObjectDisposedException exception) {
        if(!(this.exception is AbortedException)) {
          this.exception = exception;
        }
      }
      catch(Exception exception) {
        this.exception = exception;
      }

      OnAsyncEnded();
    }
示例#11
0
    /// <summary>Called asynchronously to execute the request</summary>
    /// <param name="state">Not used</param>
    private void execute(object state) {
      lock(this.protocol.SyncRoot) {
        try {
          sendQuery();

          // The first reply will indicate the status of the request.
          string statusLine = this.protocol.ReceiveLine(5000);
          int statusCode = CddbProtocol.GetStatusCode(statusLine);

          switch(statusCode) {
            case 200: { // Exact match found
              this.results = new Cddb.Disc[1] {
                decodeDiscFromStatusLine(statusLine)
              };
              break;
            }
            case 202: { // No matches found
              this.results = new Cddb.Disc[0];
              break;
            }
            case 211: { // Inexact matches found
              this.results = receiveDiscs();
              break;
            }
            default: {
              this.exception = exceptionFromQueryStatus(
                statusCode, statusLine.Substring((statusLine.Length >= 4) ? 4 : 3)
              );
              break;
            }
          }

        }
        catch(Exception exception) {
          if(!(this.exception is AbortedException)) {
            this.exception = exception;
          }
        }
      }

      OnAsyncEnded();
    }
示例#12
0
    /// <summary>Changes the CDDB server's active protocol level</summary>
    private void changeProtocolLevel() {

      // Issue the command to the CDDB server
      this.protocol.SendLine(string.Format("proto {0}", this.newLevel.Value), 5000);

      // Receive the reply from the server
      string statusLine = this.protocol.ReceiveLine(5000);

      // Obtain the status code returned by the server
      int statusCode = CddbProtocol.GetStatusCode(statusLine);

      // Decode the server reply
      switch(statusCode) {
        case 200: {
          this.protocolLevel = decodeDetailedProtocolLevel(statusLine);
          break;
        }
        case 201: {
          this.protocolLevel = decodeShortProtocolLevel(statusLine);
          break;
        }
        default: {
          this.exception = exceptionFromProtocolStatus(
            statusCode, statusLine.Substring((statusLine.Length >= 4) ? 4 : 3)
          );
          return;
        }
      }

      // Because we're pedantic, we'll check whether the server actually reported
      // the new protocol level we requested back to us.
      if(this.newLevel.Value != this.protocolLevel.ActiveProtocolLevel) {
        this.exception = new BadResponseException(
          "Server sent a positive response but didn't change the protocol level"
        );
      } else { // Everything went well
        this.callback(this.newLevel.Value);
      }

    }
    /// <summary>Called asynchronously to execute the request</summary>
    /// <param name="state">Not used</param>
    private void execute(object state) {
      lock(this.protocol.SyncRoot) {
        try {
          // Issue the command to the CDDB server
          this.protocol.SendLine("cddb lscat", 5000);

          // The first reply will indicate the status of the request.
          string statusLine = this.protocol.ReceiveLine(5000);
          int statusCode = CddbProtocol.GetStatusCode(statusLine);

          // Process the response according to its status code
          switch(statusCode) {

            // Request was accepted and genre list follows
            case 210: {
              this.categories = receiveCategoryList();
              break;
            }

            // No success code, find out what exactly went wrong
            default: {
              this.exception = exceptionFromGenreListStatus(
                statusCode, statusLine.Substring((statusLine.Length >= 4) ? 4 : 3)
              );
              break;
            }

          }
        }
        catch(Exception exception) {
          this.exception = exception;
        }
      }

      OnAsyncEnded();
    }
示例#14
0
 /// <summary>
 ///   Initializes a new CDDB protocol level request for retrieval of
 ///   the current protocol level
 /// </summary>
 /// <param name="protocol">
 ///   Protocol used to communication with the CDDB server
 /// </param>
 public CddbProtocolLevelRequest(
   CddbProtocol protocol
 ) {
   this.protocol = protocol;
 }
 /// <summary>Initializes a new CDDB quit request</summary>
 /// <param name="protocol">
 ///   Protocol used to communication with the CDDB server
 /// </param>
 public CddbQuitRequest(CddbProtocol protocol) {
   this.protocol = protocol;
 }
 /// <summary>Initializes a new CDDB category list request</summary>
 /// <param name="protocol">
 ///   Protocol used to communication with the CDDB server
 /// </param>
 public CddbCategoryListRequest(CddbProtocol protocol) {
   this.protocol = protocol;
 }
示例#17
0
 /// <summary>Initializes a new CDDB quit request</summary>
 /// <param name="protocol">
 ///   Protocol used to communication with the CDDB server
 /// </param>
 public CddbQuitRequest(CddbProtocol protocol) {
   this.protocol = protocol;
 }