[glom] Document: Save image data in base64 format rather than GDA format.



commit f142e5bb4755a0a5b5dc44a978fb93e0f270e462
Author: Murray Cumming <murrayc murrayc com>
Date:   Sun Nov 11 07:59:43 2012 +0100

    Document: Save image data in base64 format rather than GDA format.
    
            * glom/libglom/document/document.cc: Increase the file format
    version.
            * glom/libglom/data_structure/field.[h|cc]:
    to_file_format(): Save the data in the XML as base64 instead
    of using gda_binary_to_string().
    from_file_format(): Optionally interpret image data as the old
    GDA image format. Otherwise, use base64.
            * glom/libglom/xml_utils.cc: set_node_text_child_as_value():
    Set the attribute format=base64 for image data.
    get_node_attribute_value_as_value(): Check for the format
    attribute and optionally ask from_file_format() to use the old
    format.
            * glom/glom_document.dtd: value: Mention the format attribute.

 ChangeLog                            |   18 +++++++++++
 glom/glom_document.dtd               |    3 +-
 glom/libglom/data_structure/field.cc |   57 ++++++++++++++++++++++++++++------
 glom/libglom/data_structure/field.h  |    2 +-
 glom/libglom/document/document.cc    |    5 ++-
 glom/libglom/xml_utils.cc            |   19 +++++++++--
 6 files changed, 87 insertions(+), 17 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6da95a5..223fec1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2012-11-10  Murray Cumming  <murrayc murrayc com>
 
+        Document: Save image data in base64 format rather than GDA format.
+
+        * glom/libglom/document/document.cc: Increase the file format
+	version.
+        * glom/libglom/data_structure/field.[h|cc]:
+	to_file_format(): Save the data in the XML as base64 instead 
+	of using gda_binary_to_string().
+	from_file_format(): Optionally interpret image data as the old 
+	GDA image format. Otherwise, use base64.
+        * glom/libglom/xml_utils.cc: set_node_text_child_as_value():
+	Set the attribute format="base64" for image data.
+	get_node_attribute_value_as_value(): Check for the format
+	attribute and optionally ask from_file_format() to use the old
+	format.
+        * glom/glom_document.dtd: value: Mention the format attribute.
+
+2012-11-10  Murray Cumming  <murrayc murrayc com>
+
         Update a test for the newer translations.
 
         * tests/test_document_load_translations.cc: Increase the number
diff --git a/glom/glom_document.dtd b/glom/glom_document.dtd
index 979f537..e884016 100644
--- a/glom/glom_document.dtd
+++ b/glom/glom_document.dtd
@@ -110,7 +110,8 @@ TODO: Should we specify the presence of child text nodes in the ELEMENT somehow?
 
     <!ELEMENT value (#PCDATA)>
     <!ATTLIST value
-        column CDATA #REQUIRED>
+        column CDATA #REQUIRED
+        format CDATA #IMPLIED>
 
 <!-- relationships describe connections between databases. -->
 
diff --git a/glom/libglom/data_structure/field.cc b/glom/libglom/data_structure/field.cc
index bc610c5..927fb6f 100644
--- a/glom/libglom/data_structure/field.cc
+++ b/glom/libglom/data_structure/field.cc
@@ -286,17 +286,38 @@ Glib::ustring Field::to_file_format(const Gnome::Gda::Value& value, glom_field_t
         return Glib::ustring();
       else
       {
-        str = gda_binary_to_string(gdabinary, 0);
+        gchar* base64 = g_base64_encode(gdabinary->data, gdabinary->binary_length);
+        if(!base64)
+          return Glib::ustring();
+        else
+        {
+          str = base64;
+        }
       }
     }
     else if(value_type == GDA_TYPE_BLOB)
     {
       const GdaBlob* gdablob = gda_value_get_blob(value.gobj());
-      if(!gdablob)
+
+      if(!gdablob || !gdablob->op)
         return Glib::ustring();
       else
       {
-        str = gda_blob_to_string(const_cast<GdaBlob*>(gdablob), 0);
+        if(!gda_blob_op_read_all(const_cast<GdaBlobOp*>(gdablob->op), const_cast<GdaBlob*>(gdablob)))
+        {
+          return Glib::ustring();
+        }
+        else
+        {
+          const GdaBinary* gdabinary = &(gdablob->data);
+          gchar* base64 = g_base64_encode(gdabinary->data, gdabinary->binary_length);
+          if(!base64)
+            return Glib::ustring();
+          else
+          {
+            str = base64;
+          }
+        }
       }
     }
 
@@ -345,7 +366,7 @@ Gnome::Gda::Value Field::from_file_format(const Glib::ustring& str, bool& succes
   return from_file_format(str, m_glom_type, success);
 }
 
-Gnome::Gda::Value Field::from_file_format(const Glib::ustring& str, glom_field_type glom_type, bool& success)
+Gnome::Gda::Value Field::from_file_format(const Glib::ustring& str, glom_field_type glom_type, bool& success, bool old_image_format)
 {
   success = true;
 
@@ -365,17 +386,33 @@ Gnome::Gda::Value Field::from_file_format(const Glib::ustring& str, glom_field_t
   if(glom_type == TYPE_IMAGE)
   {
     if(string_unescaped.empty())
-      return  Gnome::Gda::Value();
-
-    GdaBinary* gdabinary = gda_string_to_binary(string_unescaped.c_str());
-    if(!success || !gdabinary)
       return Gnome::Gda::Value();
-    else
+
+    if(old_image_format)
     {
+      //We used the GDA format before:
+      GdaBinary* gdabinary = gda_string_to_binary(string_unescaped.c_str());
+      if(!success || !gdabinary)
+        return Gnome::Gda::Value();
+      else
+      {
+        Gnome::Gda::Value value;
+        value_reinit(value.gobj(), GDA_TYPE_BINARY);
+        gda_value_take_binary(value.gobj(), gdabinary);
+        return value;
+      }
+    } else {
+      //What we use now in new files:
+
+      GdaBinary* gdabinary = g_new(GdaBinary, 1);
+      gsize len = 0;
+      gdabinary->data = g_base64_decode(string_unescaped.c_str(), &len);
+      gdabinary->binary_length = len;
+
       Gnome::Gda::Value value;
       value_reinit(value.gobj(), GDA_TYPE_BINARY);
       gda_value_take_binary(value.gobj(), gdabinary);
-      return value; 
+      return value;
     }
   }
   else
diff --git a/glom/libglom/data_structure/field.h b/glom/libglom/data_structure/field.h
index 03fa91b..e734a2c 100644
--- a/glom/libglom/data_structure/field.h
+++ b/glom/libglom/data_structure/field.h
@@ -180,7 +180,7 @@ public:
    */
   Gnome::Gda::Value from_file_format(const Glib::ustring& str, bool& success) const;
 
-  static Gnome::Gda::Value from_file_format(const Glib::ustring& str, glom_field_type glom_type, bool& success);
+  static Gnome::Gda::Value from_file_format(const Glib::ustring& str, glom_field_type glom_type, bool& success, bool old_image_format = false);
 
   /** Escape the value so that it can be used in a SQL command for a find.
    */
diff --git a/glom/libglom/document/document.cc b/glom/libglom/document/document.cc
index a141b80..edaa3a1 100644
--- a/glom/libglom/document/document.cc
+++ b/glom/libglom/document/document.cc
@@ -4485,9 +4485,10 @@ guint Document::get_latest_known_document_format_version()
   // Version 5: (Glom 1.14). Extra layout item formatting options were added, plus a startup script.
   // Version 6: (Glom 1.16). Extra show_all option for choices that show related records. Extra related choice fields are now a layout group instead of just a second field name.
   // Version 7: (Glom 1.20). New print layout details. Related records: Number of rows can be specified. All colors can now be in CSS3 string format (via GdkRGBA)
-  // Version 8: (Glom 1.22). The database_title attribute is replaced by the title attribute. 
+  // Version 8: (Glom 1.22). The database_title attribute is replaced by the title attribute.
+  // Version 9: (Glom 1.24). <value> tags now have a format="base64" attribute by default. Having no format attribute is deprecated.
 
-  return 8;
+  return 9;
 }
 
 std::vector<Glib::ustring> Document::get_library_module_names() const
diff --git a/glom/libglom/xml_utils.cc b/glom/libglom/xml_utils.cc
index 08c5a09..2a13ea8 100644
--- a/glom/libglom/xml_utils.cc
+++ b/glom/libglom/xml_utils.cc
@@ -22,6 +22,9 @@
 #include <libglom/utils.h>
 #include <limits> // for numeric_limits
 
+static const char GLOM_ATTRIBUTE_IMAGE_DATA_FORMAT[] = "format";
+static const char GLOM_ATTRIBUTE_IMAGE_DATA_FORMAT_BASE64[] = "base64"; //No attribute here means the old GDA format.
+
 namespace Glom
 {
 
@@ -220,6 +223,11 @@ void set_node_text_child_as_value(xmlpp::Element* node, const Gnome::Gda::Value&
 
   const Glib::ustring value_as_text = Field::to_file_format(value, field_type);
   node->set_child_text( Utils::string_clean_for_xml(value_as_text) );
+
+  if(field_type == Field::TYPE_IMAGE)
+  {
+    set_node_attribute_value(node, GLOM_ATTRIBUTE_IMAGE_DATA_FORMAT, GLOM_ATTRIBUTE_IMAGE_DATA_FORMAT_BASE64);
+  }
 }
 
 Gnome::Gda::Value get_node_attribute_value_as_value(const xmlpp::Element* node, const Glib::ustring& strAttributeName, Field::glom_field_type field_type)
@@ -242,12 +250,17 @@ Gnome::Gda::Value get_node_text_child_as_value(const xmlpp::Element* node, Field
 
   const Glib::ustring value_string = text_child->get_content();
 
+  bool old_image_format = false;
+  const Glib::ustring format = get_node_attribute_value(node, GLOM_ATTRIBUTE_IMAGE_DATA_FORMAT);
+  if(format.empty()) //We previously used the GDA format, before we even specified it.
+    old_image_format = true;
+    
   bool success = false;
-  const Gnome::Gda::Value result = Field::from_file_format(value_string, field_type, success);
+  const Gnome::Gda::Value result = Field::from_file_format(value_string, field_type, success, old_image_format);
   if(success)
     return result;
-  else
-    return Gnome::Gda::Value();
+
+  return Gnome::Gda::Value();
 }
 
 



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