Search code examples
cpointersstructesp-idf

How to assign a character to a string pointed by a struct?


I have a struct that contains a field named void * user_data. Here is the library declaration:

typedef struct esp_http_client_event {
    esp_http_client_event_id_t event_id;
    esp_http_client_handle_t client;
    void *data;
    int data_len;
    void *user_data;
    char *header_key;
    char *header_value;
} esp_http_client_event_t;

When I declare the struct, I assign a buffer to user_data:

char g_http_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = { 0 };
...
esp_http_client_config_t config = {
    .url = WEB_URL,
    .event_handler = client_event_handler,
    .transport_type = HTTP_TRANSPORT_OVER_SSL,
    .crt_bundle_attach = esp_crt_bundle_attach,
    .buffer_size_tx = 1024,
    .user_data = g_http_response_buffer,
};

After that, I want to manipulate g_http_response_buffer by using the structure, passed to a function (the function is a callback, but I don't think it's relevant). Inside the function, I use it in the following way:

esp_err_t
client_event_handler (esp_http_client_event_handle_t evt)
{
    static int output_len = 0;
    esp_err_t ret = ESP_OK;

    switch (evt->event_id)
    {
        case HTTP_EVENT_ERROR:
            ESP_LOGI(g_p_tag, "HTTP_EVENT_ERROR");
        break;

        case HTTP_EVENT_ON_CONNECTED:
            ESP_LOGI(g_p_tag, "HTTP_EVENT_ON_CONNECTED");
        break;

        case HTTP_EVENT_HEADER_SENT:
            ESP_LOGI(g_p_tag, "HTTP_EVENT_HEADER_SENT");
        break;

        case HTTP_EVENT_ON_HEADER:
            ESP_LOGI(g_p_tag, "HTTP_EVENT_ON_HEADER, key=%s, value=%s",
                     evt->header_key, evt->header_value);
        break;

        case HTTP_EVENT_ON_DATA:
            ESP_LOGI(g_p_tag, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
            if (!esp_http_client_is_chunked_response(evt->client))
            {
                if (evt->user_data)
                {
                    memcpy(evt->user_data + output_len, evt->data,
                           evt->data_len);
                    ESP_LOGI(g_p_tag, "Dati non chunk: %s",
                             (char *) evt->user_data);
                }

                if (ESP_OK == ret)
                {
                    output_len += evt->data_len;
                }
            }
            else
            {
                if (evt->user_data)
                {
                    memcpy(evt->user_data + output_len, evt->data,
                           evt->data_len);
                    ESP_LOGI(g_p_tag, "Dati chunk: %s",
                             (char *) evt->user_data);
                }

                if (ESP_OK == ret)
                {
                    output_len += evt->data_len;
                }
            }
        break;

        case HTTP_EVENT_ON_FINISH:
            ESP_LOGI(g_p_tag, "HTTP_EVENT_ON_FINISH");
            g_http_response_buffer[output_len] = '\0'; // <- HERE!
            ESP_LOGI(g_p_tag, "Dato finale: %s", (char *) evt->user_data);
            output_len = 0;
        break;
    }
    return ret;
}   /* client_event_handler() */

How can I insert the terminator string by using a pointer to user_data? I tried (evt + output_len)->user_data = '\0' but it seems wrong.


Solution

  • How can I insert the terminator string by using a pointer to user_data?

    You cannot "insert" into arrays strictly speaking. You can assign a char in any index to be a null terminator like this:

    char* ptr_to_user_data = config.user_data;
    assert(index < MAX_HTTP_OUTPUT_BUFFER);
    ptr_to_user_data[index] = '\0';