#include "gnunet_common.h"
#include "gnunet_strings_lib.h"
+#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+
+#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
+
/**
* Fill a buffer of the given size with
if (size > 5 * 1024)
{
size = size / 1024;
- unit = _( /* size unit */ "KiB");
+ unit = "KiB";
if (size > 5 * 1024)
{
size = size / 1024;
- unit = _( /* size unit */ "MiB");
+ unit = "MiB";
if (size > 5 * 1024)
{
size = size / 1024;
- unit = _( /* size unit */ "GiB");
+ unit = "GiB";
if (size > 5 * 1024)
{
size = size / 1024;
- unit = _( /* size unit */ "TiB");
+ unit = "TiB";
}
}
}
}
+/**
+ * Convert a given fancy human-readable size to bytes.
+ *
+ * @param fancy_size human readable string (i.e. 1 MB)
+ * @param size set to the size in bytes
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
+ unsigned long long *size)
+{
+ struct
+ {
+ const char *name;
+ unsigned long long value;
+ } table[] =
+ {
+ {
+ "B", 1},
+ {
+ "KiB", 1024},
+ {
+ "kB", 1000},
+ {
+ "MiB", 1024 * 1024},
+ {
+ "MB", 1000 * 1000},
+ {
+ "GiB", 1024 * 1024 * 1024},
+ {
+ "GB", 1000 * 1000 * 1000},
+ {
+ "TiB", 1024LL * 1024LL * 1024LL * 1024LL},
+ {
+ "TB", 1000LL * 1000LL * 1000LL * 1024LL},
+ {
+ "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL},
+ {
+ "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL},
+ {
+ "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL},
+ {
+ "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL},
+ {
+ NULL, 0}
+ };
+ unsigned long long ret;
+ char *in;
+ const char *tok;
+ unsigned long long last;
+ unsigned int i;
+
+ ret = 0;
+ last = 0;
+ in = GNUNET_strdup (fancy_size);
+ for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " "))
+ {
+ i = 0;
+ while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok)))
+ i++;
+ if (table[i].name != NULL)
+ last *= table[i].value;
+ else
+ {
+ ret += last;
+ last = 0;
+ if (1 != sscanf (tok, "%llu", &last))
+ {
+ GNUNET_free (in);
+ return GNUNET_SYSERR; /* expected number */
+ }
+ }
+ }
+ ret += last;
+ *size = ret;
+ GNUNET_free (in);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Convert a given fancy human-readable time to our internal
+ * representation.
+ *
+ * @param fancy_size human readable string (i.e. 1 minute)
+ * @param rtime set to the relative time
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_size,
+ struct GNUNET_TIME_Relative *rtime)
+{
+ struct
+ {
+ const char *name;
+ unsigned long long value;
+ } table[] =
+ {
+ {
+ "ms", 1},
+ {
+ "s", 1000},
+ {
+ "\"", 1000},
+ {
+ "min", 60 * 1000},
+ {
+ "minutes", 60 * 1000},
+ {
+ "'", 60 * 1000},
+ {
+ "h", 60 * 60 * 1000},
+ {
+ "d", 24 * 60 * 60 * 1000},
+ {
+ "a", 31557600 /* year */ },
+ {
+ NULL, 0}
+ };
+ unsigned long long ret;
+ char *in;
+ const char *tok;
+ unsigned long long last;
+ unsigned int i;
+
+ if ((0 == strcasecmp (fancy_size, "infinity")) ||
+ (0 == strcasecmp (fancy_size, "forever")))
+ {
+ *rtime = GNUNET_TIME_UNIT_FOREVER_REL;
+ return GNUNET_OK;
+ }
+ ret = 0;
+ last = 0;
+ in = GNUNET_strdup (fancy_size);
+ for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " "))
+ {
+ i = 0;
+ while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok)))
+ i++;
+ if (table[i].name != NULL)
+ last *= table[i].value;
+ else
+ {
+ ret += last;
+ last = 0;
+ if (1 != sscanf (tok, "%llu", &last))
+ {
+ GNUNET_free (in);
+ return GNUNET_SYSERR; /* expected number */
+ }
+ }
+ }
+ ret += last;
+ rtime->rel_value = (uint64_t) ret;
+ GNUNET_free (in);
+ return GNUNET_OK;
+}
+
/**
* Convert the len characters long character sequence
- * given in input that is in the given charset
- * to UTF-8.
+ * given in input that is in the given input charset
+ * to a string in given output charset.
* @return the converted string (0-terminated),
* if conversion fails, a copy of the orignal
* string is returned.
*/
char *
-GNUNET_STRINGS_to_utf8 (const char *input, size_t len, const char *charset)
+GNUNET_STRINGS_conv (const char *input, size_t len, const char *input_charset, const char *output_charset)
{
char *ret;
char *itmp;
iconv_t cd;
- cd = iconv_open ("UTF-8", charset);
+ cd = iconv_open (output_charset, input_charset);
if (cd == (iconv_t) - 1)
{
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv_open");
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Character set requested was `%s'\n"), charset);
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv_open");
+ LOG (GNUNET_ERROR_TYPE_WARNING, _("Character sets requested were `%s'->`%s'\n"),
+ input_charset, output_charset);
ret = GNUNET_malloc (len + 1);
memcpy (ret, input, len);
ret[len] = '\0';
#endif
&len, &itmp, &finSize) == SIZE_MAX)
{
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv");
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv");
iconv_close (cd);
GNUNET_free (tmp);
ret = GNUNET_malloc (len + 1);
ret[tmpSize - finSize] = '\0';
GNUNET_free (tmp);
if (0 != iconv_close (cd))
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv_close");
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv_close");
return ret;
#else
ret = GNUNET_malloc (len + 1);
}
+/**
+ * Convert the len characters long character sequence
+ * given in input that is in the given charset
+ * to UTF-8.
+ * @return the converted string (0-terminated),
+ * if conversion fails, a copy of the orignal
+ * string is returned.
+ */
+char *
+GNUNET_STRINGS_to_utf8 (const char *input, size_t len, const char *charset)
+{
+ return GNUNET_STRINGS_conv (input, len, charset, "UTF-8");
+}
+
+/**
+ * Convert the len bytes-long UTF-8 string
+ * given in input to the given charset.
+
+ * @return the converted string (0-terminated),
+ * if conversion fails, a copy of the orignal
+ * string is returned.
+ */
+char *
+GNUNET_STRINGS_from_utf8 (const char *input, size_t len, const char *charset)
+{
+ return GNUNET_STRINGS_conv (input, len, "UTF-8", charset);
+}
+
+
+
/**
* Complete filename (a la shell) from abbrevition.
* @param fil the name of the file, may contain ~/ or
fm = getenv ("HOME");
if (fm == NULL)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _
- ("Failed to expand `$HOME': environment variable `HOME' not set"));
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to expand `$HOME': environment variable `HOME' not set"));
return NULL;
}
fm = GNUNET_strdup (fm);
}
if (fm == NULL)
{
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "getcwd");
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "getcwd");
buffer = getenv ("PWD"); /* alternative */
if (buffer != NULL)
fm = GNUNET_strdup (buffer);
if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS)
{
SetErrnoFromWinError (lRet);
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path");
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path");
return NULL;
}
/* is the path relative? */
if (lRet + strlen (fn) + 1 > (MAX_PATH + 1))
{
SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW);
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory");
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory");
return NULL;
}
buffer = GNUNET_malloc (MAX_PATH + 1);