project_files/frontlib/ini/inihelper.c
author Medo <smaxein@googlemail.com>
Thu, 07 Jun 2012 02:45:18 +0200
changeset 7175 038e3415100a
child 7177 bf6cf4dd847a
permissions -rw-r--r--
Added ini reading/writing for game schemes to the frontend lib

#include "inihelper.h"
#include "../logging.h"

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <stdarg.h>

static char *flib_asprintf(const char *fmt, ...) {
	va_list argp;
	va_start(argp, fmt);
	size_t requiredSize = vsnprintf(NULL, 0, fmt, argp)+1;
	char *buf = malloc(requiredSize);
	if(buf) {
		vsnprintf(buf, requiredSize, fmt, argp);
	}
	va_end(argp);
	return buf;
}

char *inihelper_strdupnull(const char *str) {
	if(!str) {
		return NULL;
	}
	return flib_asprintf("%s", str);
}

static bool keychar_needs_urlencoding(char c) {
	return !isalnum(c);
}

char *inihelper_urlencode(const char *inbuf) {
	if(!inbuf) {
		return NULL;
	}
	size_t insize = strlen(inbuf);
	if(insize > SIZE_MAX/4) {
		return NULL;
	}

	char *outbuf = malloc(insize*3+1);
	if(!outbuf) {
		return NULL;
	}

    size_t inpos = 0, outpos = 0;
    while(inbuf[inpos]) {
        if(!keychar_needs_urlencoding(inbuf[inpos])) {
        	outbuf[outpos++] = inbuf[inpos++];
        } else {
            sprintf(outbuf+outpos, "%%%02X", inbuf[inpos]);
            inpos++;
            outpos += 3;
        }
    }
    outbuf[outpos] = 0;
    return outbuf;
}

char *inihelper_urldecode(const char *inbuf) {
	char *outbuf = malloc(strlen(inbuf)+1);
	if(!outbuf) {
		return NULL;
	}

    size_t inpos = 0, outpos = 0;
    while(inbuf[inpos]) {
        if(inbuf[inpos] == '%' && isxdigit(inbuf[inpos+1]) && isxdigit(inbuf[inpos+2])) {
            char temp[3] = {inbuf[inpos+1],inbuf[inpos+2],0};
            outbuf[outpos++] = strtol(temp, NULL, 16);
            inpos += 3;
        } else {
        	outbuf[outpos++] = inbuf[inpos++];
        }
    }
    outbuf[outpos] = 0;
    return outbuf;
}

char *inihelper_createDictKey(const char *sectionName, const char *keyName) {
	if(!sectionName || !keyName) {
		return NULL;
	}
	return flib_asprintf("%s:%s", sectionName, keyName);
}

char *inihelper_getstring(dictionary *inifile, bool *error, const char *sectionName, const char *keyName) {
	if(!inifile || !sectionName || !keyName) {
		*error = true;
		return NULL;
	}
	char *extendedkey = inihelper_createDictKey(sectionName, keyName);
	if(!extendedkey) {
		*error = true;
		return NULL;
	}
	char *result = iniparser_getstring(inifile, extendedkey, NULL);
	free(extendedkey);
	if(!result) {
		flib_log_i("Missing ini setting: %s/%s", sectionName, keyName);
		*error = true;
	}
	return result;
}

char *inihelper_getstringdup(dictionary *inifile, bool *error, const char *sectionName, const char *keyName) {
	return inihelper_strdupnull(inihelper_getstring(inifile, error, sectionName, keyName));
}

int inihelper_getint(dictionary *inifile, bool *error, const char *sectionName, const char *keyName) {
	char *value = inihelper_getstring(inifile, error, sectionName, keyName);
	if(!value) {
		return 0;
	} else {
		errno = 0;
		long val = strtol(value, NULL, 10);
		if(errno!=0) {
			*error = true;
			return 0;
		}
		if(val<INT_MIN || val>INT_MAX) {
			*error = true;
			return 0;
		}
		return (int)val;
	}
}

bool inihelper_getbool(dictionary *inifile, bool *error, const char *sectionName, const char *keyName) {
	char *value = inihelper_getstring(inifile, error, sectionName, keyName);
	if(!value) {
		return false;
	} else {
		bool trueval = strchr("1tTyY", value[0]);
		bool falseval = strchr("0fFnN", value[0]);
		if(!trueval && !falseval) {
			*error = true;
			return false;
		} else {
			return trueval;
		}
	}
}

int inihelper_setstr(dictionary *dict, const char *sectionName, const char *keyName, const char *value) {
	int result = -1;
	if(!dict || !sectionName || !keyName || !value) {
		flib_log_e("inihelper_setstr called with bad parameters");
	} else {
		char *extendedkey = inihelper_createDictKey(sectionName, keyName);
		if(extendedkey) {
			result = iniparser_set(dict, extendedkey, value);
			free(extendedkey);
		}
	}
	return result;
}

int inihelper_setint(dictionary *dict, const char *sectionName, const char *keyName, int value) {
	int result = -1;
	if(!dict || !sectionName || !keyName) {
		flib_log_e("inihelper_setint called with bad parameters");
	} else {
		char *strvalue = flib_asprintf("%i", value);
		if(strvalue) {
			result = inihelper_setstr(dict, sectionName, keyName, strvalue);
			free(strvalue);
		}
	}
	return result;
}

int inihelper_setbool(dictionary *dict, const char *sectionName, const char *keyName, bool value) {
	int result = -1;
	if(!dict || !sectionName || !keyName) {
		flib_log_e("inihelper_setint called with bad parameters");
	} else {
		result = inihelper_setstr(dict, sectionName, keyName, value ? "true" : "false");
	}
	return result;
}