+
+static memcached_return_t _read_one_response(memcached_server_write_instance_st ptr,
+ char *buffer, const size_t buffer_length,
+ memcached_result_st *result,
+ uint64_t& numeric_value)
+{
+ memcached_server_response_decrement(ptr);
+
+ if (result == NULL)
+ {
+ memcached_st *root= (memcached_st *)ptr->root;
+ result = &root->result;
+ }
+
+ memcached_return_t rc;
+ if (memcached_is_binary(ptr->root))
+ {
+ rc= binary_read_one_response(ptr, buffer, buffer_length, result);
+ }
+ else
+ {
+ rc= textual_read_one_response(ptr, buffer, buffer_length, result, numeric_value);
+ assert(rc != MEMCACHED_PROTOCOL_ERROR);
+ }
+
+ if (rc == MEMCACHED_UNKNOWN_READ_FAILURE or
+ rc == MEMCACHED_READ_FAILURE or
+ rc == MEMCACHED_PROTOCOL_ERROR or
+ rc == MEMCACHED_CLIENT_ERROR or
+ rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE)
+ {
+ memcached_io_reset(ptr);
+ }
+
+ return rc;
+}
+
+memcached_return_t memcached_read_one_response(memcached_server_write_instance_st ptr,
+ memcached_result_st *result)
+{
+ uint64_t numeric_value;
+ char buffer[SMALL_STRING_LEN];
+
+ if (memcached_is_udp(ptr->root))
+ {
+ return memcached_set_error(*ptr, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT);
+ }
+
+
+ return _read_one_response(ptr, buffer, sizeof(buffer), result, numeric_value);
+}
+
+memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
+ char *buffer, size_t buffer_length,
+ memcached_result_st *result)
+{
+ uint64_t numeric_value;
+
+ return memcached_response(ptr, buffer, buffer_length, result, numeric_value);
+}
+
+memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
+ char *buffer, size_t buffer_length,
+ memcached_result_st *result,
+ uint64_t& numeric_value)
+{
+ if (memcached_is_udp(ptr->root))
+ {
+ return memcached_set_error(*ptr, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT);
+ }
+
+ /* We may have old commands in the buffer not set, first purge */
+ if ((ptr->root->flags.no_block) and (memcached_is_processing_input(ptr->root) == false))
+ {
+ (void)memcached_io_write(ptr);
+ }
+
+ /*
+ * The previous implementation purged all pending requests and just
+ * returned the last one. Purge all pending messages to ensure backwards
+ * compatibility.
+ */
+ if (memcached_is_binary(ptr->root) == false and memcached_server_response_count(ptr) > 1)
+ {
+ memcached_result_st junked_result;
+ memcached_result_st *junked_result_ptr= memcached_result_create(ptr->root, &junked_result);
+
+ assert(junked_result_ptr);
+
+ while (memcached_server_response_count(ptr) > 1)
+ {
+ memcached_return_t rc= _read_one_response(ptr, buffer, buffer_length, junked_result_ptr, numeric_value);
+
+ // @TODO should we return an error on another but a bad read case?
+ if (rc != MEMCACHED_END and
+ rc != MEMCACHED_STORED and
+ rc != MEMCACHED_SUCCESS and
+ rc != MEMCACHED_STAT and
+ rc != MEMCACHED_DELETED and
+ rc != MEMCACHED_NOTFOUND and
+ rc != MEMCACHED_NOTSTORED and
+ rc != MEMCACHED_DATA_EXISTS)
+ {
+ memcached_result_free(junked_result_ptr);
+ return rc;
+ }
+ }
+ memcached_result_free(junked_result_ptr);
+ }
+
+ return _read_one_response(ptr, buffer, buffer_length, result, numeric_value);
+}