/******************************************************************************
 * mod_uploader / Auxiliary.c
 ******************************************************************************
 * Copyright (C) 2004 Tetsuya Kimata <kimata@acapulco.dyndns.org>
 *
 * All rights reserved.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must
 *    not claim that you wrote the original software. If you use this
 *    software in a product, an acknowledgment in the product
 *    documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must
 *    not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 *    distribution.
 *
 * $Id: Auxiliary.c 674 2005-09-13 18:31:36Z svn $
 *****************************************************************************/

#include "Auxiliary.h"
#include "Misc.h"

#include "apr_file_info.h"
#include "apr_strings.h"

#include <string.h>
#include <ctype.h>


const char *rfc1738_encode(apr_pool_t *pool, const char* str)
{
    static char hex[] = "0123456789ABCDEF";

    char *encoded;
    char *buffer;
    unsigned char c;

    encoded = buffer = (char *)(apr_pcalloc(pool, strlen(str)*3));

    while (*str != '\0') {
        *buffer = *str++;

        if (!isalnum(*buffer)) {
            c = (unsigned char)(*buffer);

            *buffer++ = '%';
            *buffer++ = hex[c / 0x10];
            *buffer++ = hex[c % 0x10];
        } else {
            buffer++;
        }
    }

    return encoded;
}

const char *size_str(apr_pool_t *pool, apr_uint64_t size)
{
#ifdef NO_DOUBLE
    if (size > 1024*1024*1024) {
        return apr_psprintf(pool, "%" APR_UINT64_T_FMT " %s", size/(1024*1024*1024), GBYTE_UNIT);
    } else if (size > 1024*1024) {
        return apr_psprintf(pool, "%" APR_UINT64_T_FMT " %s", size/(1024*1024), MBYTE_UNIT);
    } else if (size > 1024) {
        return apr_psprintf(pool, "%" APR_UINT64_T_FMT " %s", size/1024, KBYTE_UNIT);
    } else {
        return apr_psprintf(pool, "%" APR_UINT64_T_FMT " %s", size, BYTE_UNIT);
    }
#else
    if (size > 1024*1024*1024) {
        return apr_psprintf(pool, "%.1f %s", (double)(size/(1024*1024))/1024, GBYTE_UNIT);
    } else if (size > 1024*1024) {
        return apr_psprintf(pool, "%.1f %s", (double)(size/1024)/1024, MBYTE_UNIT);
    } else if (size > 1024) {
        return apr_psprintf(pool, "%.1f %s", (double)(size)/1024, KBYTE_UNIT);
    } else {
        return apr_psprintf(pool, "%" APR_UINT64_T_FMT " %s", size, BYTE_UNIT);
    }
#endif
}

const char *comma_str(apr_pool_t *pool, apr_size_t number)
{
    apr_size_t figure = 1;
    char *str;

    {
        apr_size_t tmp = number;
        while ((tmp /= 10) != 0) {
            figure++;
        }
    }
    {
        apr_size_t size = figure + (figure-1)/3 + 1;
        str = (char *)(apr_palloc(pool, sizeof(char)*size));
        str += size - 1;
    }
    *str-- = '\0';
    {
        apr_size_t count = 0;
        do {
            *str-- = (char)(number%10) + '0';
            number /= 10;

            if ((number != 0) && ((++count % 3) == 0)) {
                *str-- = ',';
            }
        } while (number != 0);
    }

    return ++str;
}

const char *basename_ex(const char *path)
{
    const char *i = path + strlen(path) - 2;

    while ((*i != '/') && (*i != '\\') && (*i != ':') &&
           (*i != '\r') && (*i != '\n')) { /* 念のため */
        if (i == path) {
            return path;
        }

        i--;
    }

    return i + 1;
}

const char *dirname_ex(apr_pool_t *pool, const char *path)
{
    char *dirname;
    char *i;

    dirname = apr_pstrdup(pool, path);

    i = dirname + strlen(dirname) - 2;
    while ((*i != '/') && (*i != '\\') && (*i != ':') &&
           (*i != '\r') && (*i != '\n')) { /* 念のため */
        if (i == path) {
            break;
        }

        i--;
    }

    *i = '\0';

    return dirname;
}

#ifndef HAVE_STRNCHR
char *strnchr(const char *s, size_t count, int c)
{
    if (s == NULL) {
        return 0;
    }

    while (count-- > 0) {
        if (*s == c) {
            return (char *)s;
        } else if (*s == '\0') {
            return 0;
        }
        s++;
    }

    return 0;
}
#endif

#if !defined(HAVE_MEMMEM) || defined(WIN32)
void *memmem(const void *haystack, size_t haystacklen,
             const void *needle, size_t needlelen)
{
    unsigned char *start = (unsigned char *)haystack;
    unsigned char pat = *((unsigned char *)needle);
    unsigned char *pos  = start;
    apr_size_t remain = haystacklen;

    do {
        pos = (unsigned char *)memchr(pos, pat, remain);

        if (pos == NULL) {
            return NULL;
        }

        if ((memcmp(pos, needle, needlelen)) == 0) {
            return pos;
        }
        pos++;

        remain = haystacklen - (pos-start);
    } while (remain >= needlelen);

    return NULL;
}
#endif

/*
 * Local Variables:
 * mode: c
 * buffer-file-coding-system: euc-japan-dos
 * End:
 */
