From 9b0e674a17cbcf079187b9bd1e4f61c6a7eaa84f Mon Sep 17 00:00:00 2001
From: Emmanuel Christophe <emmanuel.christophe@orfeo-toolbox.org>
Date: Mon, 27 Apr 2009 22:55:36 +0800
Subject: [PATCH] BUG: fix segfault when some data are not set

---
 Code/IO/otbSHPVectorDataIO.txx       |  6 +-
 Code/IO/otbVectorDataKeywordlist.cxx | 98 ++++++++++++++++++++++++++--
 Code/IO/otbVectorDataKeywordlist.h   | 13 +++-
 3 files changed, 106 insertions(+), 11 deletions(-)

diff --git a/Code/IO/otbSHPVectorDataIO.txx b/Code/IO/otbSHPVectorDataIO.txx
index b0a191ecc3..9177440d3a 100644
--- a/Code/IO/otbSHPVectorDataIO.txx
+++ b/Code/IO/otbSHPVectorDataIO.txx
@@ -211,10 +211,12 @@ SHPVectorDataIO<TData>
       if (geometry != NULL)
       {
         otb::VectorDataKeywordlist kwl;
-        std::cout << "Inserting " << feature->GetFieldCount() << " fields." << std::endl;
         for (int fieldNum=0; fieldNum< feature->GetFieldCount(); ++fieldNum)
         {
-          kwl.AddField(feature->GetFieldDefnRef(fieldNum), feature->GetRawFieldRef(fieldNum));
+          if (feature->IsFieldSet(fieldNum))
+          {
+            kwl.AddField(feature->GetFieldDefnRef(fieldNum), feature->GetRawFieldRef(fieldNum));
+          }
         }
 
 
diff --git a/Code/IO/otbVectorDataKeywordlist.cxx b/Code/IO/otbVectorDataKeywordlist.cxx
index b9091d9341..8a89beda58 100644
--- a/Code/IO/otbVectorDataKeywordlist.cxx
+++ b/Code/IO/otbVectorDataKeywordlist.cxx
@@ -42,9 +42,9 @@ void VectorDataKeywordlist::
     AddField(OGRFieldDefn* fieldDefn, OGRField* field)
 {
   FieldType newField;
-  newField.first = new OGRFieldDefn(fieldDefn);
-  newField.second = *field; //FIXME this is only a shallow copy
-  m_FieldList.push_back(newField);
+  newField.first = fieldDefn;
+  newField.second = *field;
+  m_FieldList.push_back(CopyOgrField(newField));
 };
 
 void
@@ -53,10 +53,7 @@ VectorDataKeywordlist::
 {
   for (unsigned int i = 0; i < p.m_FieldList.size(); ++i)
   {
-    FieldType newField;
-    newField.first = new OGRFieldDefn(p.m_FieldList[i].first);
-    newField.second = p.m_FieldList[i].second; //FIXME this is only a shallow copy
-    m_FieldList.push_back(newField);
+    m_FieldList.push_back(CopyOgrField(p.m_FieldList[i]));
   }
 }
 
@@ -158,6 +155,93 @@ VectorDataKeywordlist::
   return output.str();
 }
 
+
+VectorDataKeywordlist::FieldType
+VectorDataKeywordlist::
+    CopyOgrField(FieldType field)
+{
+  FieldType outField;
+  outField.first = new OGRFieldDefn(field.first);
+  switch(field.first->GetType())
+  {
+    case OFTInteger:
+    {
+      outField.second.Integer = field.second.Integer;
+      break;
+    }
+    case OFTIntegerList:
+    {
+      std::cerr  << "OGR type not handled" << std::endl;
+      break;
+    }
+    case OFTReal:
+    {
+      outField.second.Real = field.second.Real;
+      break;
+    }
+    case OFTRealList:
+    {
+      std::cerr << "OGR type not handled" << std::endl;
+      break;
+    }
+    case OFTString:
+    {
+      if (field.second.String != NULL)
+      {
+        CPLFree( outField.second.String );
+        outField.second.String = CPLStrdup( field.second.String );
+      }
+      break;
+    }
+    case OFTStringList:
+    {
+      std::cerr << "OGR type not handled" << std::endl;
+      break;
+    }
+    case OFTWideString:
+    {
+      std::cerr << "OGR type not handled" << std::endl;
+      break;
+    }
+    case OFTWideStringList:
+    {
+      std::cerr << "OGR type not handled" << std::endl;
+      break;
+    }
+    case OFTBinary:
+    {
+      std::cerr << "OGR type not handled" << std::endl;
+      break;
+    }
+    case OFTDate:
+    {
+      outField.second.Date.Year = field.second.Date.Year;
+      outField.second.Date.Month = field.second.Date.Month;
+      outField.second.Date.Day = field.second.Date.Day;
+      break;
+    }
+    case OFTTime:
+    {
+      outField.second.Date.Hour = field.second.Date.Hour;
+      outField.second.Date.Minute = field.second.Date.Minute;
+      outField.second.Date.Second = field.second.Date.Second;
+      break;
+    }
+    case OFTDateTime:
+    {
+      outField.second.Date.Year = field.second.Date.Year;
+      outField.second.Date.Month = field.second.Date.Month;
+      outField.second.Date.Day = field.second.Date.Day;
+      outField.second.Date.Hour = field.second.Date.Hour;
+      outField.second.Date.Minute = field.second.Date.Minute;
+      outField.second.Date.Second = field.second.Date.Second;
+      break;
+    }
+  }
+  return outField;
+}
+
+
 std::ostream &
     operator<<(std::ostream &os, const VectorDataKeywordlist &kwl)
 {
diff --git a/Code/IO/otbVectorDataKeywordlist.h b/Code/IO/otbVectorDataKeywordlist.h
index 123dfd6022..ebba3e089b 100644
--- a/Code/IO/otbVectorDataKeywordlist.h
+++ b/Code/IO/otbVectorDataKeywordlist.h
@@ -27,8 +27,16 @@
 namespace otb
 {
 /** \class VectorDataKeywordlist
-   * \brief this class represents the metadata of vector data.
-   *
+ * \brief this class handle the metadata of vector data.
+ *
+ * This class is used internaly to handle the information associated with
+ * a vector object. This information is retrieved from the input file (a
+ * shapefile for example) and propagated along the pipeline with the object.
+ *
+ * This is the equivalent of the otbOssimKeywordlist class but for OGR information.
+ *
+ * \todo add the accessor to enable modifying/updating the data.
+ *
  */
 
 class VectorDataKeywordlist
@@ -67,6 +75,7 @@ class VectorDataKeywordlist
   private:
 
     std::string PrintField(FieldType field) const;
+    FieldType CopyOgrField(FieldType field);
     FieldListType m_FieldList;
 
 
-- 
GitLab