Logo Search packages:      
Sourcecode: libmpdclient version File versions  Download package

mpd_malloc struct mpd_pair* mpd_recv_pair ( struct mpd_connection connection  )  [read]

Reads the next mpd_pair from the server. Returns NULL if there are no more pairs.

The caller must dispose the pair with either mpd_return_pair() or mpd_enqueue_pair().

Definition at line 40 of file recv.c.

References mpd_connection::async, mpd_connection::command_list_remaining, mpd_connection::discrete_finished, mpd_connection::error, MPD_ERROR_MALFORMED, MPD_ERROR_STATE, mpd_recv_pair(), mpd_pair::name, mpd_connection::pair, mpd_connection::pair_state, mpd_connection::parser, mpd_connection::receiving, mpd_connection::sending_command_list, and mpd_pair::value.

Referenced by mpd_recv_directory(), mpd_recv_entity(), mpd_recv_idle(), mpd_recv_output(), mpd_recv_pair(), mpd_recv_pair_named(), mpd_recv_playlist(), mpd_recv_song(), mpd_recv_stats(), mpd_recv_status(), mpd_response_finish(), and mpd_response_next().

{
      struct mpd_pair *pair;
      char *line;
      enum mpd_parser_result result;
      const char *msg;

      assert(connection != NULL);

      if (mpd_error_is_defined(&connection->error))
            return NULL;

      /* check if the caller has returned the previous pair */
      assert(connection->pair_state != PAIR_STATE_FLOATING);

      if (connection->pair_state == PAIR_STATE_NULL) {
            /* return the enqueued NULL pair */
            connection->pair_state = PAIR_STATE_NONE;
            return NULL;
      }

      if (connection->pair_state == PAIR_STATE_QUEUED) {
            /* dequeue the pair from mpd_enqueue_pair() */
            pair = &connection->pair;
            connection->pair_state = PAIR_STATE_FLOATING;
            return pair;
      }

      assert(connection->pair_state == PAIR_STATE_NONE);

      if (!connection->receiving ||
          (connection->sending_command_list &&
           connection->command_list_remaining > 0 &&
           connection->discrete_finished)) {
            mpd_error_code(&connection->error, MPD_ERROR_STATE);
            mpd_error_message(&connection->error,
                          "already done processing current command");
            return NULL;
      }

      line = mpd_sync_recv_line(connection->async,
                          mpd_connection_timeout(connection));
      if (line == NULL) {
            connection->receiving = false;
            connection->sending_command_list = false;

            mpd_connection_sync_error(connection);
            return NULL;
      }

      result = mpd_parser_feed(connection->parser, line);
      switch (result) {
      case MPD_PARSER_MALFORMED:
            mpd_error_code(&connection->error, MPD_ERROR_MALFORMED);
            mpd_error_message(&connection->error,
                          "Failed to parse MPD response");
            connection->receiving = false;
            return NULL;

      case MPD_PARSER_SUCCESS:
            if (!mpd_parser_is_discrete(connection->parser)) {
                  if (connection->sending_command_list &&
                      connection->command_list_remaining > 0) {
                        mpd_error_code(&connection->error,
                                     MPD_ERROR_MALFORMED);
                        mpd_error_message(&connection->error,
                                      "expected more list_OK's");
                        connection->command_list_remaining = 0;
                  }

                  connection->receiving = false;
                  connection->sending_command_list = false;
                  connection->discrete_finished = false;
            } else {
                  if (!connection->sending_command_list ||
                      connection->command_list_remaining == 0) {
                        mpd_error_code(&connection->error,
                                     MPD_ERROR_MALFORMED);
                        mpd_error_message(&connection->error,
                                      "got an unexpected list_OK");
                  } else {
                        connection->discrete_finished = true;
                        --connection->command_list_remaining;
                  }
            }

            return NULL;

      case MPD_PARSER_ERROR:
            connection->receiving = false;
            connection->sending_command_list = false;
            mpd_error_server(&connection->error,
                         mpd_parser_get_server_error(connection->parser),
                         mpd_parser_get_at(connection->parser));
            msg = mpd_parser_get_message(connection->parser);
            if (msg == NULL)
                  msg = "Unspecified MPD error";
            mpd_error_message(&connection->error, msg);
            return NULL;

      case MPD_PARSER_PAIR:
            pair = &connection->pair;
            pair->name = mpd_parser_get_name(connection->parser);
            pair->value = mpd_parser_get_value(connection->parser);

            connection->pair_state = PAIR_STATE_FLOATING;
            return pair;
      }

      /* unreachable */
      assert(false);
      return NULL;
}


Generated by  Doxygen 1.6.0   Back to index