Add g_checksum_type_get_length, and change g_checksum_get_digest to use a
authorChristian Persch <chpe@gnome.org>
Wed, 19 Dec 2007 18:53:27 +0000 (18:53 +0000)
committerChristian Persch <chpe@src.gnome.org>
Wed, 19 Dec 2007 18:53:27 +0000 (18:53 +0000)
2007-12-19  Christian Persch  <chpe@gnome.org>

* glib/gchecksum.c: (g_checksum_type_get_length),
(g_checksum_get_digest):
* glib/gchecksum.h:
* glib/glib.symbols:
* tests/checksum-test.c: (test_checksum): Add
g_checksum_type_get_length, and change g_checksum_get_digest to use a
provided buffer instead of returning allocated memory. Bug #501853.

svn path=/trunk/; revision=6162

ChangeLog
docs/reference/glib/glib-sections.txt
glib/gchecksum.c
glib/gchecksum.h
glib/glib.symbols
tests/checksum-test.c

index 520c90c..d143763 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-12-19  Christian Persch  <chpe@gnome.org>
+
+       * glib/gchecksum.c: (g_checksum_type_get_length),
+       (g_checksum_get_digest):
+       * glib/gchecksum.h:
+       * glib/glib.symbols:
+       * tests/checksum-test.c: (test_checksum): Add
+       g_checksum_type_get_length, and change g_checksum_get_digest to use a
+       provided buffer instead of returning allocated memory. Bug #501853.
+
 2007-12-19  Emmanuele Bassi  <ebassi@gnome.org>
 
        * glib/gtimer.c (g_time_val_from_iso8601): Fix the date validation
index 0f8f583..b28ead1 100644 (file)
@@ -2530,6 +2530,7 @@ g_uri_unescape_string
 <TITLE>Data Checksums</TITLE>
 <FILE>checksum</FILE>
 GChecksumType
+g_checksum_type_get_length
 GChecksum
 g_checksum_new
 g_checksum_copy
index 9c19729..764b605 100644 (file)
@@ -1049,6 +1049,41 @@ sha256_sum_digest (Sha256sum *sha256,
  */
 
 /**
+ * g_checksum_type_get_length:
+ * @checksum_type: a #GChecksumType
+ *
+ * Gets the length in bytes of digests of type @type
+ *
+ * Return value: the checksum length, or -1 if @type is
+ * not supported.
+ * 
+ * Since: 2.16
+ */
+gssize
+g_checksum_type_get_length (GChecksumType checksum_type)
+{
+  gssize len = -1;
+
+  switch (checksum_type)
+    {
+    case G_CHECKSUM_MD5:
+      len = MD5_DIGEST_LEN;
+      break;
+    case G_CHECKSUM_SHA1:
+      len = SHA1_DIGEST_LEN;
+      break;
+    case G_CHECKSUM_SHA256:
+      len = SHA256_DIGEST_LEN;
+      break;
+    default:
+      len = -1;
+      break;
+    }
+
+  return len;
+}
+
+/**
  * g_checksum_new:
  * @checksum_type: the desired type of checksum
  *
@@ -1244,8 +1279,9 @@ g_checksum_get_string (GChecksum *checksum)
 /**
  * g_checksum_get_digest:
  * @checksum: a #GChecksum
- * @digest: return location for the digest
- * @digest_len: return location for the length of the digest, or %NULL
+ * @digest: output buffer
+ * @digest_len: an inout parameter. The caller initializes it to the size of @buffer.
+ *   After the call it contains the length of the digest.
  *
  * Gets the digest from @checksum as a raw binary vector and places it
  * into @digest. The size of the digest depends on the type of checksum.
@@ -1257,16 +1293,17 @@ g_checksum_get_string (GChecksum *checksum)
  */
 void
 g_checksum_get_digest (GChecksum  *checksum,
-                       guint8    **digest,
+                       guint8     *buffer,
                        gsize      *digest_len)
 {
   gboolean checksum_open = FALSE;
-  guint8 *new;
   gchar *str = NULL;
-  gsize len = 0;
+  gsize len;
 
   g_return_if_fail (checksum != NULL);
-  g_return_if_fail (digest == NULL || *digest == NULL);
+
+  len = g_checksum_type_get_length (checksum->type);
+  g_return_if_fail (*digest_len >= len);
 
   checksum_open = !!(checksum->digest_str == NULL);
 
@@ -1278,9 +1315,7 @@ g_checksum_get_digest (GChecksum  *checksum,
           md5_sum_close (&(checksum->sum.md5));
           str = md5_sum_to_string (&(checksum->sum.md5));
         }
-      new = g_new (guint8, MD5_DIGEST_LEN);
-      md5_sum_digest (&(checksum->sum.md5), new);
-      len = MD5_DIGEST_LEN;
+      md5_sum_digest (&(checksum->sum.md5), buffer);
       break;
     case G_CHECKSUM_SHA1:
       if (checksum_open)
@@ -1288,9 +1323,7 @@ g_checksum_get_digest (GChecksum  *checksum,
           sha1_sum_close (&(checksum->sum.sha1));
           str = sha1_sum_to_string (&(checksum->sum.sha1));
         }
-      new = g_new (guint8, SHA1_DIGEST_LEN);
-      sha1_sum_digest (&(checksum->sum.sha1), new);
-      len = SHA1_DIGEST_LEN;
+      sha1_sum_digest (&(checksum->sum.sha1), buffer);
       break;
     case G_CHECKSUM_SHA256:
       if (checksum_open)
@@ -1298,13 +1331,9 @@ g_checksum_get_digest (GChecksum  *checksum,
           sha256_sum_close (&(checksum->sum.sha256));
           str = sha256_sum_to_string (&(checksum->sum.sha256));
         }
-      new = g_new (guint8, SHA256_DIGEST_LEN);
-      sha256_sum_digest (&(checksum->sum.sha256), new);
-      len = SHA256_DIGEST_LEN;
+      sha256_sum_digest (&(checksum->sum.sha256), buffer);
       break;
     default:
-      new = NULL;
-      len = 0;
       g_assert_not_reached ();
       break;
     }
@@ -1312,21 +1341,7 @@ g_checksum_get_digest (GChecksum  *checksum,
   if (str)
     checksum->digest_str = str;
 
-  if (digest == NULL)
-    g_free (new);
-  else
-    {
-      if (*digest == NULL)
-        *digest = new;
-      else
-        g_warning ("Digest set on top of a previous digest or uninitialized "
-                   "memory\n"
-                   "This indicates a bug in someone's code. You must ensure "
-                   "a digest is NULL before it's set.");
-    }
-
-  if (digest_len)
-    *digest_len = len;
+  *digest_len = len;
 }
 
 /**
index 988f866..efa0e1b 100644 (file)
@@ -47,6 +47,8 @@ typedef enum {
 
 typedef struct _GChecksum       GChecksum;
 
+gssize                g_checksum_type_get_length (GChecksumType checksum_type);
+
 GChecksum *           g_checksum_new        (GChecksumType     checksum_type);
 GChecksum *           g_checksum_copy       (const GChecksum  *checksum);
 void                  g_checksum_free       (GChecksum        *checksum);
@@ -55,7 +57,7 @@ void                  g_checksum_update     (GChecksum        *checksum,
                                              gsize             length);
 G_CONST_RETURN gchar *g_checksum_get_string (GChecksum        *checksum);
 void                  g_checksum_get_digest (GChecksum        *checksum,
-                                             guint8          **digest,
+                                             guint8           *buffer,
                                              gsize            *digest_len);
 
 gchar *g_compute_checksum_for_data   (GChecksumType  checksum_type,
index 6d5d393..80b9f78 100644 (file)
@@ -173,6 +173,7 @@ g_cache_value_foreach
 
 #if IN_HEADER(__G_CHECKSUM_H__)
 #if IN_FILE(__G_CHECKSUM_C__)
+g_checksum_type_get_length
 g_checksum_new
 g_checksum_copy
 g_checksum_free
index 0448302..b44be76 100644 (file)
@@ -48,8 +48,8 @@ test_checksum (GChecksumType  checksum_type,
   gchar *data;
   guchar *p;
   gsize data_len;
-  guint8 *digest1, *digest2;
-  gsize len1, len2;
+  guint8 digest1[64], digest2[64];
+  gsize len1 = sizeof (digest1), len2 = sizeof (digest2);
   gchar *digest_str1, *digest_str2;
 
   checksum0 = g_checksum_new (checksum_type);
@@ -96,21 +96,8 @@ test_checksum (GChecksumType  checksum_type,
  
   g_free (data);
 
-  digest1 = NULL;
-  g_checksum_get_digest (checksum1, &digest1, &len1);
-  if (!digest1)
-    {
-      g_print ("No %s digest found for checksum1\n", type);
-      exit (1);
-    }
-
-  digest2 = NULL;
-  g_checksum_get_digest (checksum2, &digest2, &len2);
-  if (!digest2)
-    {
-      g_print ("No %s digest found for checksum2\n", type);
-      exit (1);
-    }
+  g_checksum_get_digest (checksum1, digest1, &len1);
+  g_checksum_get_digest (checksum2, digest2, &len2);
   
   digest_str1 = digest_to_string (digest1, len1);
   digest_str2 = digest_to_string (digest2, len2);
@@ -126,8 +113,6 @@ test_checksum (GChecksumType  checksum_type,
 
   g_free (digest_str1);
   g_free (digest_str2);
-  g_free (digest1);
-  g_free (digest2);
 
   digest_str1 = g_strdup (g_checksum_get_string (checksum1));
   digest_str2 = g_strdup (g_checksum_get_string (checksum2));