-fix time assertion introduce in last patch
[oweals/gnunet.git] / src / util / strings.c
index df0094cf4bae8b5418322b07a1a8e27c7e6ea270..3dbcaf2c00d90ca4d0cf6181def02730af1f10d8 100644 (file)
@@ -347,9 +347,6 @@ GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time,
 {
   struct tm tv;
   time_t t;
-#if HAVE_TM_GMTOFF
-  struct tm *tp;
-#endif
 
   if (0 == strcasecmp ("end of time", fancy_time))
   {
@@ -370,22 +367,6 @@ GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time,
     return GNUNET_SYSERR;
   t = mktime (&tv);
   atime->abs_value_us = (uint64_t) ((uint64_t) t * 1000LL * 1000LL);
-#if HAVE_TM_GMTOFF
-  tp = localtime (&t);
-  atime->abs_value_us += 1000LL * 1000LL * tp->tm_gmtoff;
-#elif defined LINUX
-  atime->abs_value_us -= 1000LL * 1000LL * timezone;
-#elif defined WINDOWS
-  {
-    DWORD tzv;
-    TIME_ZONE_INFORMATION tzi;
-    tzv = GetTimeZoneInformation (&tzi);
-    if (TIME_ZONE_ID_INVALID != tzv)
-    {
-      atime->abs_value_us -= 1000LL * 1000LL * tzi.Bias * 60LL;
-    }
-  }
-#endif
   return GNUNET_OK;
 }
 
@@ -449,7 +430,8 @@ GNUNET_STRINGS_conv (const char *input,
   free (encoded_string);
   return ret;
  fail:
-  LOG (GNUNET_ERROR_TYPE_WARNING, _("Character sets requested were `%s'->`%s'\n"),
+  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);
@@ -744,8 +726,35 @@ GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t)
   if (t.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
     return _("end of time");
   tt = t.abs_value_us / 1000LL / 1000LL;
-  tp = gmtime (&tt);
+  tp = localtime (&tt);
+  /* This is hacky, but i don't know a way to detect libc character encoding.
+   * Just expect utf8 from glibc these days.
+   * As for msvcrt, use the wide variant, which always returns utf16
+   * (otherwise we'd have to detect current codepage or use W32API character
+   * set conversion routines to convert to UTF8).
+   */
+#ifndef WINDOWS
   strftime (buf, sizeof (buf), "%a %b %d %H:%M:%S %Y", tp);
+#else
+  {
+    static wchar_t wbuf[255];
+    uint8_t *conved;
+    size_t ssize;
+
+    wcsftime (wbuf, sizeof (wbuf) / sizeof (wchar_t),
+        L"%a %b %d %H:%M:%S %Y", tp);
+
+    ssize = sizeof (buf);
+    conved = u16_to_u8 (wbuf, sizeof (wbuf) / sizeof (wchar_t),
+        (uint8_t *) buf, &ssize);
+    if (conved != (uint8_t *) buf)
+    {
+      strncpy (buf, (char *) conved, sizeof (buf));
+      buf[255 - 1] = '\0';
+      free (conved);
+    }
+  }
+#endif
   return buf;
 }
 
@@ -774,7 +783,8 @@ GNUNET_STRINGS_get_short_name (const char *filename)
 
 
 /**
- * Get the numeric value corresponding to a character.
+ * Get the decoded value corresponding to a character according to Crockford
+ * Base32 encoding.
  *
  * @param a a character
  * @return corresponding numeric value
@@ -782,21 +792,52 @@ GNUNET_STRINGS_get_short_name (const char *filename)
 static unsigned int
 getValue__ (unsigned char a)
 {
+  unsigned int dec;
+
+  switch (a)
+  {
+  case 'O':
+  case 'o':
+    a = '0';
+    break;
+  case 'i':
+  case 'I':
+  case 'l':
+  case 'L':
+    a = '1';
+    break;
+    /* also consider U to be V */
+  case 'u':
+  case 'U':
+    a = 'V';
+    break;
+  default:
+    break;
+  }
   if ((a >= '0') && (a <= '9'))
     return a - '0';
-  if ((a >= 'A') && (a <= 'V'))
-    return (a - 'A' + 10);
-  if ((a >= 'a') && (a <= 'v'))
-    return (a - 'a' + 10);
+  if ((a >= 'a') && (a <= 'z'))
+    a = toupper (a);
+    /* return (a - 'a' + 10); */
+  dec = 0;
+  if ((a >= 'A') && (a <= 'Z'))
+  {
+    if ('I' < a)
+      dec++;
+    if ('L' < a)
+      dec++;
+    if ('O' < a)
+      dec++;
+    if ('U' < a)
+      dec++;
+    return (a - 'A' + 10 - dec);
+  }
   return -1;
 }
 
 
 /**
- * Convert binary data to ASCII encoding.  The ASCII encoding is rather
- * GNUnet specific.  It was chosen such that it only uses characters
- * in [0-9A-V], can be produced without complex arithmetics and uses a
- * small number of characters.
+ * Convert binary data to ASCII encoding using Crockford Base32 encoding.
  * Does not append 0-terminator, but returns a pointer to the place where
  * it should be placed, if needed.
  *
@@ -813,7 +854,7 @@ GNUNET_STRINGS_data_to_string (const void *data, size_t size, char *out, size_t
   /**
    * 32 characters for encoding
    */
-  static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+  static char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
   unsigned int wpos;
   unsigned int rpos;
   unsigned int bits;
@@ -861,8 +902,8 @@ GNUNET_STRINGS_data_to_string (const void *data, size_t size, char *out, size_t
 
 
 /**
- * Convert ASCII encoding back to data
- * out_size must match exactly the size of the data before it was encoded.
+ * Convert Crockford Base32hex encoding back to data.
+ * @a out_size must match exactly the size of the data before it was encoded.
  *
  * @param enc the encoding
  * @param enclen number of characters in @a enc (without 0-terminator, which can be missing)
@@ -896,7 +937,7 @@ GNUNET_STRINGS_string_to_data (const char *enc, size_t enclen,
   {
     vbit = encoded_len % 5; /* padding! */
     shift = 5 - vbit;
-    bits = (ret = getValue__ (enc[--rpos])) >> (5 - (encoded_len % 5));
+    bits = (ret = getValue__ (enc[--rpos])) >> shift;
   }
   else
   {
@@ -1260,7 +1301,7 @@ GNUNET_STRINGS_to_address_ip (const char *addr,
 
 /**
  * Makes a copy of argv that consists of a single memory chunk that can be
- * freed with a single call to GNUNET_free ();
+ * freed with a single call to GNUNET_free();
  */
 static char *const *
 _make_continuous_arg_copy (int argc,
@@ -1291,7 +1332,7 @@ _make_continuous_arg_copy (int argc,
  * other than W32.
  * Returned argv has u8argv[u8argc] == NULL.
  * Returned argv is a single memory block, and can be freed with a single
- *   GNUNET_free () call.
+ *   GNUNET_free() call.
  *
  * @param argc argc (as given by main())
  * @param argv argv (as given by main())