#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>

typedef char gchar;

/*
 * Function to replace %20 by a space. No need to reallocate.
 */
void
Scan_Convert_P20_Into_Space_2 (gchar *string)
{
    gchar *tmp = string;

    while ((tmp = strstr (tmp, "%20")) != NULL)
    {
        *(tmp++) = ' ';
        strcpy (tmp, tmp + 2);
    }
}

/*
 * Function to replace %20 by a space. No need to reallocate.
 */
void
Scan_Convert_P20_Into_Space_1_5 (gchar *string)
{
    gchar *r = string;
    gchar *w = string;

    while (*r)
    {
	    if (*r == '%' && r[1] == '2' && r[2] == '0')
	    {
		    *(w++) = ' ';
		    r += 3;
	    }
	    else
	    {
		    *(w++) = *(r++);
	    }
    }
    *w = *r;
}

/*
 * Function to replace %20 by a space. No need to reallocate.
 */
void
Scan_Convert_P20_Into_Space_1_1 (gchar *string)
{
    gchar *r;

    if ((r = strstr (string, "%20")) != NULL)
    {
        gchar *w = r;
        *(w++) = ' ';
        r += 3;

        while (*r)
        {
            if (*r == '%' && r[1] == '2' && r[2] == '0')
            {
                *(w++) = ' ';
                r += 3;
            }
            else
            {
                *(w++) = *(r++);
            }
        }
        *w = *r;
    }
}

/*
 * Function to replace %20 by a space. No need to reallocate.
 */
void
Scan_Convert_P20_Into_Space_1 (gchar *string)
{
    gchar *r;

    if ((r = strstr (string, "%20")) != NULL)
    {
        gchar *w = r;
        *(w++) = ' ';
        r += 3;

        while (*r)
        {
            if (strncmp (r, "%20", 3) != 0)
            {
                *(w++) = ' ';
                r += 3;
            }
            else
            {
                *(w++) = *(r++);
            }
        }
        *w = *r;
    }
}

/*
 * Function to replace %20 by a space. No need to reallocate.
 */
void
Scan_Convert_P20_Into_Space_0 (gchar *string)
{
    gchar *i = string;

    while ((i = strstr (i, "%20")) != NULL)
    {
        gchar *tmp1 = i + 3;
        gchar *tmp = i + 1;
        *(i++) = ' ';
        while (*tmp1)
            *(tmp++) = *(tmp1++);
        *tmp = '\0';
    }
}

/*
 * Function to replace %20 by a space. No need to reallocate.
 */
void
Scan_Convert_P20_Into_Space (gchar *string)
{
    gchar *tmp, *tmp1;

    while ((tmp = strstr (string, "%20")) != NULL)
    {
        tmp1 = tmp + 3;
        *(tmp++) = ' ';
        while (*tmp1)
            *(tmp++) = *(tmp1++);
        *tmp = '\0';
    }
}

int main(int argc, char **argv)
{
    const char *sample = "01%20-%20scooter%20-%20maria.mp3";
    int count = 100000;
    int i;
    int sl;
    size_t n;
    char **array;

    struct {
        const gchar *name;
        void (*scanner)(gchar *s);
    } scanners[] = {
#define SCANNER(x) { #x, x }
        SCANNER(Scan_Convert_P20_Into_Space),
        SCANNER(Scan_Convert_P20_Into_Space_0),
        SCANNER(Scan_Convert_P20_Into_Space_1),
        SCANNER(Scan_Convert_P20_Into_Space_1_1),
        SCANNER(Scan_Convert_P20_Into_Space_1_5),
        SCANNER(Scan_Convert_P20_Into_Space_2),
    };

    if (argc > 1)
        count = atoi(argv[1]);
    if (argc > 2)
        sample = argv[2];

    sl = strlen(sample);

    array = alloca(sizeof(*array) * count);

    for (i = 0; i < count; i++)
        array[i] = malloc(sl + 1);

    for (n = 0; n < sizeof(scanners) / sizeof(*scanners); n++) {
        struct timeval t0;
        struct timeval t1;
        for (i = 0; i < count; i++)
            strcpy(array[i], sample);
        gettimeofday(&t0, NULL);
        for (i = 0; i < count; i++)
            scanners[n].scanner(array[i]);
        gettimeofday(&t1, NULL);
        printf("%s took %ld ms\n", scanners[n].name, (t1.tv_sec - t0.tv_sec) * 1000 + (t1.tv_usec - t0.tv_usec) / 1000);
    }

    return 0;
}
