/* 'checkit_tiff' is a conformance checker for baseline TIFFs
 *
 * author: Andreas Romeyke, 2015-2022
 * licensed under conditions of libtiff
 * (see http://libtiff.maptools.org/misc.html)
 *
 */

#include "simple_string.h"

unsigned long atoul (const char * s) {
    /*
    errno = 0;
    char *endptr;
    unsigned long val = strtoul(s, &endptr, 10);
    if (errno != 0) {
        perror("strtoul");
        exit(EXIT_FAILURE);
    }
    if (endptr == s) {
        fprintf(stderr, "No digits were found\n");
        exit(EXIT_FAILURE);
    }
    printf("ATOUL: '%s' -> %lu\n", s, val);
    return val;
     */
    long long int tmp = atoll(s);
    if (tmp < 0) {
        perror("negative numbers not supported");
        exit(EXIT_FAILURE);
    }
    unsigned long v = (unsigned long) tmp & 0xffffffff;
    return v;
}

unsigned int count_multiple_zero_bytes(const char *val, uint32 count) {
    unsigned int r = 0;
    for (uint32 i=0; i<count-1; i++) {
        if (val[i] == '\0' && val[i+1] =='\0') {
            r = i+1;
            break;
        }
    }
    return r;
}

char * sprint_string_as_hexdump(const char * val, uint32 len) {
    /* largest possible value is:
     * 12                    -> for string constants
     * strlen(val) * 2  + 2  -> for worst case of string
     * strlen(val) * 14      -> for worst case of hexdump
     * + some extra space    -> reserved + \0
     */
    unsigned long res_size = len * 16 + 64;
    char * res = malloc(res_size * sizeof( char));
    if (NULL == res) {
        perror("could not allocate memory for string\n");
        exit(EXIT_FAILURE);
    }
    unsigned int res_pos = 0;
    const char * str = "str='";
    strncpy(res+res_pos, str , res_size-1);
    res_pos+=strlen(str);
    for (unsigned int i = 0; i<= len-1; i++) {
        if (isprint(val[i]) ) {
            res[res_pos] = val[i];
        } else {
            strncpy(res+res_pos, "�", res_size-res_pos-1);
            res_pos+=2;
        }
        res_pos++;
    }
    const char * hex = "' hex=";
    strncpy(res+res_pos, hex, res_size-res_pos-1);
    res_pos+=strlen(hex);

    /* hex output */
    for (unsigned int i = 0; i<= len-1; i++) {
        if (isprint(val[i])) {
            snprintf(res + res_pos, res_size-res_pos-1, " %02x", val[i]);
            res_pos += 3;
        } else {
            /* problem here ist to determine the size of output */
            char tmp[res_size];
            snprintf( tmp, res_size-1, " ---->%02x<----", (unsigned char) val[i]);
            unsigned int tmp_len = strlen( tmp);
            strncpy( res+res_pos, tmp, res_size-res_pos-1);
            res_pos += tmp_len;
        }
        if (res_pos >= res_size -1 ) {
            res[res_size-1] = '\0';
            break;
        }
    }
    res[res_pos] = '\0';
    //printf("respos=%u (res_size=%lu)", res_pos, res_size);
    return res;
}
