Fix perf_crypto_rsa.c after various changes
[oweals/gnunet.git] / src / util / strings.c
index f526dd35a47484161877382f059aec46d42e0834..06d05f2eff5f9749c3a105a732c29c7a004066c8 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2005-2013 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2005-2013 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
@@ -29,7 +29,8 @@
 #if HAVE_ICONV
 #include <iconv.h>
 #endif
-#include "gnunet_util_lib.h"
+#include "gnunet_crypto_lib.h"
+#include "gnunet_strings_lib.h"
 #include <unicase.h>
 #include <unistr.h>
 #include <uniconv.h>
@@ -47,7 +48,7 @@
  *
  * Unlike using "snprintf" with "%s", this function
  * will add 0-terminators after each string.  The
- * "GNUNET_string_buffer_tokenize" function can be
+ * #GNUNET_string_buffer_tokenize() function can be
  * used to parse the buffer back into individual
  * strings.
  *
@@ -313,6 +314,8 @@ GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time,
     { "days", 24 * 60 * 60 * 1000LL * 1000LL},
     { "week", 7 * 24 * 60 * 60 * 1000LL * 1000LL},
     { "weeks", 7 * 24 * 60 * 60 * 1000LL * 1000LL},
+    { "year", 31536000000000LL /* year */ },
+    { "years", 31536000000000LL /* year */ },
     { "a", 31536000000000LL /* year */ },
     { NULL, 0}
   };
@@ -367,17 +370,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 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;
 }
 
@@ -441,7 +433,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);
@@ -793,7 +786,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
@@ -801,48 +795,80 @@ 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.
- * Does not append 0-terminator, but returns a pointer to the place where
- * it should be placed, if needed.
+ * Convert binary data to ASCII encoding using Crockford Base32 encoding.
+ * Returns a pointer to the byte after the last byte in the string, that
+ * is where the 0-terminator was placed if there was room.
  *
  * @param data data to encode
  * @param size size of data (in bytes)
  * @param out buffer to fill
  * @param out_size size of the buffer. Must be large enough to hold
- * ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5 bytes
- * @return pointer to the next byte in 'out' or NULL on error.
+ * (size * 8 + 4) / 5 bytes
+ * @return pointer to the next byte in @a out or NULL on error.
  */
 char *
-GNUNET_STRINGS_data_to_string (const void *data, size_t size, char *out, size_t out_size)
+GNUNET_STRINGS_data_to_string (const void *data,
+                               size_t size,
+                               char *out,
+                               size_t out_size)
 {
   /**
    * 32 characters for encoding
    */
-  static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+  static char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
   unsigned int wpos;
   unsigned int rpos;
   unsigned int bits;
   unsigned int vbit;
   const unsigned char *udata;
 
-  GNUNET_assert (data != NULL);
-  GNUNET_assert (out != NULL);
   udata = data;
-  if (out_size < (((size*8) + ((size*8) % 5)) % 5))
+  if (out_size < (size * 8 + 4) / 5)
   {
     GNUNET_break (0);
     return NULL;
@@ -872,7 +898,7 @@ GNUNET_STRINGS_data_to_string (const void *data, size_t size, char *out, size_t
     out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
     vbit -= 5;
   }
-  GNUNET_assert (vbit == 0);
+  GNUNET_assert (0 == vbit);
   if (wpos < out_size)
     out[wpos] = '\0';
   return &out[wpos];
@@ -880,8 +906,41 @@ 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.
+ * Return the base32crockford encoding of the given buffer.
+ *
+ * The returned string will be freshly allocated, and must be free'd
+ * with GNUNET_free().
+ *
+ * @param buffer with data
+ * @param size size of the buffer
+ * @return freshly allocated, null-terminated string
+ */
+char *
+GNUNET_STRINGS_data_to_string_alloc (const void *buf,
+                                     size_t size)
+{
+  char *str_buf;
+  size_t len = size * 8;
+  char *end;
+
+  if (len % 5 > 0)
+    len += 5 - len % 5;
+  len /= 5;
+  str_buf = GNUNET_malloc (len + 1);
+  end = GNUNET_STRINGS_data_to_string (buf, size, str_buf, len);
+  if (NULL == end)
+  {
+    GNUNET_free (str_buf);
+    return NULL;
+  }
+  *end = '\0';
+  return str_buf;
+}
+
+
+/**
+ * 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)
@@ -915,7 +974,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
   {