From: Brian Aker Date: Mon, 30 Jan 2012 05:01:36 +0000 (-0800) Subject: Push version parsing into the parser. X-Git-Tag: 1.0.5~77 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=ab9ea0e2b9e1cb2bf88510f3077950cd8e464622;p=m6w6%2Flibmemcached Push version parsing into the parser. --- diff --git a/libmemcached/response.cc b/libmemcached/response.cc index 8ed3469c..b840e9d7 100644 --- a/libmemcached/response.cc +++ b/libmemcached/response.cc @@ -180,12 +180,12 @@ read_error: return MEMCACHED_PARTIAL_READ; } -static memcached_return_t textual_read_one_response(memcached_server_write_instance_st ptr, +static memcached_return_t textual_read_one_response(memcached_server_write_instance_st instance, char *buffer, const size_t buffer_length, memcached_result_st *result) { size_t total_read; - memcached_return_t rc= memcached_io_readline(ptr, buffer, buffer_length, total_read); + memcached_return_t rc= memcached_io_readline(instance, buffer, buffer_length, total_read); if (memcached_failed(rc)) { @@ -201,12 +201,46 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta if (buffer[1] == 'A' and buffer[2] == 'L' and buffer[3] == 'U' and buffer[4] == 'E') /* VALUE */ { /* We add back in one because we will need to search for END */ - memcached_server_response_increment(ptr); - return textual_value_fetch(ptr, buffer, result); + memcached_server_response_increment(instance); + return textual_value_fetch(instance, buffer, result); } // VERSION else if (buffer[1] == 'E' and buffer[2] == 'R' and buffer[3] == 'S' and buffer[4] == 'I' and buffer[5] == 'O' and buffer[6] == 'N') /* VERSION */ { + /* Find the space, and then move one past it to copy version */ + char *response_ptr= index(buffer, ' '); + response_ptr++; + + long int version= strtol(response_ptr, (char **)NULL, 10); + if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); + } + instance->major_version= uint8_t(version); + + response_ptr= index(response_ptr, '.'); + response_ptr++; + + version= strtol(response_ptr, (char **)NULL, 10); + if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version")); + } + instance->minor_version= uint8_t(version); + + response_ptr= index(response_ptr, '.'); + response_ptr++; + + version= strtol(response_ptr, (char **)NULL, 10); + if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); + } + instance->micro_version= uint8_t(version); + return MEMCACHED_SUCCESS; } } @@ -227,7 +261,7 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta // STAT if (buffer[1] == 'T' and buffer[2] == 'A' and buffer[3] == 'T') /* STORED STATS */ { - memcached_server_response_increment(ptr); + memcached_server_response_increment(instance); return MEMCACHED_STAT; } // SERVER_ERROR @@ -262,7 +296,7 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta char *endptr= startptr; while (*endptr != '\r' && *endptr != '\n') endptr++; - return memcached_set_error(*ptr, MEMCACHED_SERVER_ERROR, MEMCACHED_AT, startptr, size_t(endptr - startptr)); + return memcached_set_error(*instance, MEMCACHED_SERVER_ERROR, MEMCACHED_AT, startptr, size_t(endptr - startptr)); } // STORED else if (buffer[1] == 'T' and buffer[2] == 'O' and buffer[3] == 'R') // and buffer[4] == 'E' and buffer[5] == 'D') @@ -346,7 +380,7 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta if (buffer[1] == 'T' and buffer[2] == 'E' and buffer[3] == 'M') { /* We add back in one because we will need to search for END */ - memcached_server_response_increment(ptr); + memcached_server_response_increment(instance); return MEMCACHED_ITEM; } } @@ -380,13 +414,13 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta if (auto_return_value == ULLONG_MAX and errno == ERANGE) { result->numeric_value= UINT64_MAX; - return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("Numeric response was out of range")); } else if (errno == EINVAL) { result->numeric_value= UINT64_MAX; - return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("Numeric response was out of range")); } @@ -405,11 +439,11 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta if (total_read >= sizeof("STORSTORED") -1) { fprintf(stderr, "%s:%d '%s', %.*s\n", __FILE__, __LINE__, - buffer, MEMCACHED_MAX_BUFFER, ptr->read_buffer); + buffer, MEMCACHED_MAX_BUFFER, instance->read_buffer); assert(memcmp(buffer,"STORSTORED", sizeof("STORSTORED") -1)); } #endif - return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, buffer, total_read); } diff --git a/libmemcached/version.cc b/libmemcached/version.cc index b889bf4f..961f6916 100644 --- a/libmemcached/version.cc +++ b/libmemcached/version.cc @@ -47,8 +47,8 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr) { { memcached_literal_param("version\r\n") }, }; - memcached_return_t rc= MEMCACHED_SUCCESS; + bool errors_happened= false; for (uint32_t x= 0; x < memcached_server_count(ptr); x++) { memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x); @@ -59,67 +59,22 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr) continue; } - memcached_return_t rrc= memcached_vdo(instance, vector, 1, true); - if (memcached_failed(rrc)) + memcached_return_t rrc; + if (memcached_failed(rrc= memcached_vdo(instance, vector, 1, true))) { + errors_happened= true; (void)memcached_set_error(*instance, rrc, MEMCACHED_AT); instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - rc= MEMCACHED_SOME_ERRORS; - continue; } - - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - rrc= memcached_response(instance, buffer, sizeof(buffer), NULL); - if (memcached_failed(rrc)) + else if (memcached_failed(rrc= memcached_response(instance, NULL))) { + errors_happened= true; memcached_set_error(*instance, rrc, MEMCACHED_AT); instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - rc= MEMCACHED_SOME_ERRORS; - continue; - } - - /* Find the space, and then move one past it to copy version */ - char *response_ptr= index(buffer, ' '); - response_ptr++; - - long int version= strtol(response_ptr, (char **)NULL, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0) - { - memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); - instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - rc= MEMCACHED_SOME_ERRORS; - continue; - } - instance->major_version= uint8_t(version); - - response_ptr= index(response_ptr, '.'); - response_ptr++; - - version= strtol(response_ptr, (char **)NULL, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) - { - memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version")); - instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - rc= MEMCACHED_SOME_ERRORS; - continue; } - instance->minor_version= uint8_t(version); - - response_ptr= index(response_ptr, '.'); - response_ptr++; - - version= strtol(response_ptr, (char **)NULL, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) - { - memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); - instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - rc= MEMCACHED_SOME_ERRORS; - continue; - } - instance->micro_version= uint8_t(version); } - return rc; + return errors_happened ? MEMCACHED_SOME_ERRORS : MEMCACHED_SUCCESS; } static inline memcached_return_t memcached_version_binary(memcached_st *ptr) @@ -134,7 +89,7 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) { request.bytes, sizeof(request.bytes) } }; - memcached_return_t rc= MEMCACHED_SUCCESS; + bool errors_happened= false; for (uint32_t x= 0; x < memcached_server_count(ptr); x++) { memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x); @@ -148,7 +103,7 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) if (memcached_failed(rrc)) { memcached_io_reset(instance); - rc= MEMCACHED_SOME_ERRORS; + errors_happened= true; continue; } } @@ -171,7 +126,7 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) if (memcached_failed(rrc)) { memcached_io_reset(instance); - rc= MEMCACHED_SOME_ERRORS; + errors_happened= true; continue; } @@ -180,7 +135,7 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) { memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - rc= MEMCACHED_SOME_ERRORS; + errors_happened= true; continue; } instance->major_version= uint8_t(version); @@ -190,7 +145,7 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) { memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - rc= MEMCACHED_SOME_ERRORS; + errors_happened= true; continue; } instance->minor_version= uint8_t(version); @@ -200,14 +155,14 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) { memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - rc= MEMCACHED_SOME_ERRORS; + errors_happened= true; continue; } instance->micro_version= uint8_t(version); } } - return rc; + return errors_happened ? MEMCACHED_SOME_ERRORS : MEMCACHED_SUCCESS; } memcached_return_t memcached_version(memcached_st *ptr) @@ -225,12 +180,8 @@ memcached_return_t memcached_version(memcached_st *ptr) if (memcached_is_binary(ptr)) { - rc= memcached_version_binary(ptr); - } - else - { - rc= memcached_version_textual(ptr); + return memcached_version_binary(ptr); } - return rc; + return memcached_version_textual(ptr); }