#include "gnunet_strings_lib.h"
#include <unicase.h>
#include <unistr.h>
+#include <uniconv.h>
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
return GNUNET_SYSERR;
t = mktime (&tv);
atime->abs_value = (uint64_t) ((uint64_t) t * 1000LL);
+#if LINUX
atime->abs_value -= 1000LL * timezone;
+#endif
return GNUNET_OK;
}
GNUNET_STRINGS_conv (const char *input, size_t len, const char *input_charset, const char *output_charset)
{
char *ret;
-
-#if ENABLE_NLS && HAVE_ICONV
- size_t tmpSize;
- size_t finSize;
- char *tmp;
- char *itmp;
- iconv_t cd;
-
- cd = iconv_open (output_charset, input_charset);
- if (cd == (iconv_t) - 1)
+ uint8_t *u8_string;
+ char *encoded_string;
+ size_t u8_string_length;
+ size_t encoded_string_length;
+
+ u8_string = u8_conv_from_encoding (input_charset,
+ iconveh_error,
+ input, len,
+ NULL, NULL,
+ &u8_string_length);
+ if (NULL == u8_string)
{
- 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';
- return ret;
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "u8_conv_from_encoding");
+ goto fail;
}
- tmpSize = 3 * len + 4;
- tmp = GNUNET_malloc (tmpSize);
- itmp = tmp;
- finSize = tmpSize;
- if (iconv (cd,
-#if FREEBSD || DARWIN || WINDOWS
- (const char **) &input,
-#else
- (char **) &input,
-#endif
- &len, &itmp, &finSize) == SIZE_MAX)
+ if (0 == strcmp (output_charset, "UTF-8"))
{
- LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv");
- iconv_close (cd);
- GNUNET_free (tmp);
- ret = GNUNET_malloc (len + 1);
- memcpy (ret, input, len);
- ret[len] = '\0';
+ ret = GNUNET_malloc (u8_string_length + 1);
+ memcpy (ret, u8_string, u8_string_length);
+ ret[u8_string_length] = '\0';
+ free (u8_string);
return ret;
}
- ret = GNUNET_malloc (tmpSize - finSize + 1);
- memcpy (ret, tmp, tmpSize - finSize);
- ret[tmpSize - finSize] = '\0';
- GNUNET_free (tmp);
- if (0 != iconv_close (cd))
- LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv_close");
+ encoded_string = u8_conv_to_encoding (output_charset, iconveh_error,
+ u8_string, u8_string_length,
+ NULL, NULL,
+ &encoded_string_length);
+ free (u8_string);
+ if (NULL == encoded_string)
+ {
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "u8_conv_to_encoding");
+ goto fail;
+ }
+ ret = GNUNET_malloc (encoded_string_length + 1);
+ memcpy (ret, encoded_string, encoded_string_length);
+ ret[encoded_string_length] = '\0';
+ free (encoded_string);
return ret;
-#else
+ fail:
+ LOG (GNUNET_ERROR_TYPE_WARNING, _("Character sets requested were `%s'->`%s'\n"),
+ "UTF-8", output_charset);
ret = GNUNET_malloc (len + 1);
memcpy (ret, input, len);
ret[len] = '\0';
return ret;
-#endif
}
/**
* Give relative time in human-readable fancy format.
+ * This is one of the very few calls in the entire API that is
+ * NOT reentrant!
*
* @param delta time in milli seconds
+ * @param do_round are we allowed to round a bit?
* @return time as human-readable string
*/
-char *
-GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta)
+const char *
+GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta,
+ int do_round)
{
+ static char buf[128];
const char *unit = _( /* time unit */ "ms");
- char *ret;
uint64_t dval = delta.rel_value;
- if (delta.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
- return GNUNET_strdup (_("eternity"));
- if ( (dval > 5 * 1000) || (0 == (dval % 1000) ))
+ if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value == delta.rel_value)
+ return _("forever");
+ if (0 == delta.rel_value)
+ return _("0 ms");
+ if ( ( (GNUNET_YES == do_round) &&
+ (dval > 5 * 1000) ) ||
+ (0 == (dval % 1000) ))
{
dval = dval / 1000;
unit = _( /* time unit */ "s");
- if ( (dval > 5 * 60) || (0 == (dval % 60) ) )
+ if ( ( (GNUNET_YES == do_round) &&
+ (dval > 5 * 60) ) ||
+ (0 == (dval % 60) ) )
{
dval = dval / 60;
unit = _( /* time unit */ "m");
- if ( (dval > 5 * 60) || (0 == (dval % 60) ))
+ if ( ( (GNUNET_YES == do_round) &&
+ (dval > 5 * 60) ) ||
+ (0 == (dval % 60) ))
{
dval = dval / 60;
unit = _( /* time unit */ "h");
- if ( (dval > 5 * 24) || (0 == (dval % 24)) )
- {
+ if ( ( (GNUNET_YES == do_round) &&
+ (dval > 5 * 24) ) ||
+ (0 == (dval % 24)) )
+ {
dval = dval / 24;
if (1 == dval)
unit = _( /* time unit */ "day");
}
}
}
- GNUNET_asprintf (&ret, "%llu %s", dval, unit);
- return ret;
+ GNUNET_snprintf (buf, sizeof (buf),
+ "%llu %s", dval, unit);
+ return buf;
}
/**
* "asctime", except for GNUnet time.
+ * This is one of the very few calls in the entire API that is
+ * NOT reentrant!
*
* @param t time to convert
* @return absolute time in human-readable format
*/
-char *
+const char *
GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t)
{
+ static char buf[255];
time_t tt;
struct tm *tp;
- char buf[255];
if (t.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
- return GNUNET_strdup (_("end of time"));
+ return _("end of time");
tt = t.abs_value / 1000;
tp = gmtime (&tt);
strftime (buf, sizeof (buf), "%a %b %d %H:%M:%S %Y", tp);
- return GNUNET_strdup (buf);
+ return buf;
}
}
else
{
- is_uri = GNUNET_NO;
if (r_is_uri)
*r_is_uri = GNUNET_NO;
}