gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r22345 - in gnunet/src: include util


From: gnunet
Subject: [GNUnet-SVN] r22345 - in gnunet/src: include util
Date: Wed, 27 Jun 2012 14:24:26 +0200

Author: harsha
Date: 2012-06-27 14:24:26 +0200 (Wed, 27 Jun 2012)
New Revision: 22345

Modified:
   gnunet/src/include/gnunet_configuration_lib.h
   gnunet/src/util/configuration.c
Log:
configuration serialization

Modified: gnunet/src/include/gnunet_configuration_lib.h
===================================================================
--- gnunet/src/include/gnunet_configuration_lib.h       2012-06-27 12:00:59 UTC 
(rev 22344)
+++ gnunet/src/include/gnunet_configuration_lib.h       2012-06-27 12:24:26 UTC 
(rev 22345)
@@ -113,6 +113,19 @@
 
 
 /**
+ * Serializes the given configuration.
+ *
+ * @param cfg configuration to serialize
+ * @param size will be set to the size of the serialized memory block
+ * @return the memory block where the serialized configuration is
+ *           present. This memory should be freed by the caller
+ */
+char *
+GNUNET_CONFIGURATION_serialize (struct GNUNET_CONFIGURATION_Handle *cfg,
+                               uint16_t *size);
+
+
+/**
  * Write configuration file.
  *
  * @param cfg configuration to write

Modified: gnunet/src/util/configuration.c
===================================================================
--- gnunet/src/util/configuration.c     2012-06-27 12:00:59 UTC (rev 22344)
+++ gnunet/src/util/configuration.c     2012-06-27 12:24:26 UTC (rev 22345)
@@ -271,88 +271,139 @@
 
 
 /**
- * Write configuration file.
+ * Serializes the given configuration.
  *
- * @param cfg configuration to write
- * @param filename where to write the configuration
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ * @param cfg configuration to serialize
+ * @param size will be set to the size of the serialized memory block
+ * @return the memory block where the serialized configuration is
+ *           present. This memory should be freed by the caller
  */
-int
-GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
-                            const char *filename)
+char *
+GNUNET_CONFIGURATION_serialize (struct GNUNET_CONFIGURATION_Handle *cfg,
+                               uint16_t *size)
 {
   struct ConfigSection *sec;
   struct ConfigEntry *ent;
-  FILE *fp;
-  int error;
-  char *fn;
+  char *mem;
+  char *cbuf;
   char *val;
   char *pos;
+  uint16_t len;
+  uint16_t m_size;
+  uint16_t c_size;
 
-  fn = GNUNET_STRINGS_filename_expand (filename);
-  if (fn == NULL)
-    return GNUNET_SYSERR;
-  if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn))
+
+  /* Pass1 : calculate the buffer size required */
+  m_size = 0;
+  sec = cfg->sections;
+  while (NULL != sec)
   {
-    GNUNET_free (fn);
-    return GNUNET_SYSERR;
+    /* For each section we need to add 3 charaters: {'[',']','\n'} */
+    m_size += strlen (sec->name) + 3;
+    ent = sec->entries;
+    while (NULL != ent)
+    {
+      if (NULL != ent->val)
+      {
+       /* if val has any '\n' then they occupy +1 character as '\n'->'\\','n' 
*/
+       pos = ent->val;
+       while (NULL != (pos = strstr (pos, "\n")))
+       {
+         m_size++;
+         pos++;
+       }
+       /* For each key = value pair we need to add 4 characters (2
+          spaces and 1 equal-to character and 1 new line) */
+       m_size += strlen (ent->key) + strlen (ent->val) + 4;    
+      }
+      ent = ent->next;
+    }
+    /* A new line after section end */
+    m_size++;
+    sec = sec->next;
   }
-  if (NULL == (fp = FOPEN (fn, "w")))
-  {
-    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fopen", fn);
-    GNUNET_free (fn);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (fn);
-  error = 0;
+
+  /* Pass2: Allocate memory and write the configuration to it */
+  mem = GNUNET_malloc (m_size);
   sec = cfg->sections;
-  while (sec != NULL)
+  c_size = 0;
+  *size = c_size;  
+  while (NULL != sec)
   {
-    if (0 > FPRINTF (fp, "[%s]\n", sec->name))
-    {
-      error = 1;
-      break;
-    }
+    len = GNUNET_asprintf (&cbuf, "[%s]\n", sec->name);
+    memcpy (mem + c_size, cbuf, len);
+    c_size += len;
+    GNUNET_free (cbuf);
     ent = sec->entries;
-    while (ent != NULL)
+    while (NULL != ent)
     {
-      if (ent->val != NULL)
+      if (NULL != ent->val)
       {
-        val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
-        strcpy (val, ent->val);
+       val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
+       strcpy (val, ent->val);
         while (NULL != (pos = strstr (val, "\n")))
         {
           memmove (&pos[2], &pos[1], strlen (&pos[1]));
           pos[0] = '\\';
           pos[1] = 'n';
         }
-        if (0 > FPRINTF (fp, "%s = %s\n", ent->key, val))
-        {
-          error = 1;
-          GNUNET_free (val);
-          break;
-        }
-        GNUNET_free (val);
+       len = GNUNET_asprintf (&cbuf, "%s = %s\n", ent->key, val);
+       GNUNET_free (val);
+       memcpy (mem + c_size, cbuf, len);
+       c_size += len;
+       GNUNET_free (cbuf);     
       }
       ent = ent->next;
     }
-    if (error != 0)
-      break;
-    if (0 > FPRINTF (fp, "%s\n", ""))
-    {
-      error = 1;
-      break;
-    }
+    memcpy (mem + c_size, "\n", 1);
+    c_size ++;
     sec = sec->next;
   }
-  if (error != 0)
-    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", filename);
-  GNUNET_assert (0 == FCLOSE (fp));
-  if (error != 0)
+  GNUNET_assert (c_size == m_size);
+  *size = c_size;
+  return mem;
+}
+
+
+/**
+ * Write configuration file.
+ *
+ * @param cfg configuration to write
+ * @param filename where to write the configuration
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
+                            const char *filename)
+{
+  char *fn;
+  char *cfg_buf;
+  uint16_t size;
+
+  fn = GNUNET_STRINGS_filename_expand (filename);
+  if (fn == NULL)
+    return GNUNET_SYSERR;
+  if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn))
   {
+    GNUNET_free (fn);
+    return GNUNET_SYSERR;
+  }
+  cfg_buf = GNUNET_CONFIGURATION_serialize (cfg, &size);
+  if (size != GNUNET_DISK_fn_write (fn, cfg_buf, size,
+                                   GNUNET_DISK_PERM_USER_READ 
+                                   | GNUNET_DISK_PERM_USER_WRITE
+                                   | GNUNET_DISK_PERM_GROUP_READ 
+                                   | GNUNET_DISK_PERM_GROUP_WRITE))
+  {
+    GNUNET_free (fn);
+    GNUNET_free (cfg_buf);
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Writing configration to file: %s failed\n", filename);
     cfg->dirty = GNUNET_SYSERR; /* last write failed */
     return GNUNET_SYSERR;
   }
+  GNUNET_free (fn);
+  GNUNET_free (cfg_buf);
   cfg->dirty = GNUNET_NO;       /* last write succeeded */
   return GNUNET_OK;
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]