Description: Fix fieldbase calculation.
Author: Athena Capital Research <acr-debian@athenacr.com>
--- trunk.orig/src/C++/Field.h
+++ trunk/src/C++/Field.h
@@ -27,6 +27,7 @@
 #endif
 
 #include <sstream>
+#include <algorithm>
 #include <numeric>
 #include "FieldNumbers.h"
 #include "FieldConvertors.h"
@@ -47,7 +48,7 @@
   friend class Message;
 public:
   FieldBase( int field, const std::string& string )
-    : m_field( field ), m_string(string), m_length( 0 ), m_total( 0 ),
+    : m_field( field ), m_string(string),
       m_calculated( false )
   {}
 
@@ -57,6 +58,7 @@
   {
     m_field = field;
     m_calculated = false;
+    m_data.clear(); // dirty
   }
 
   void setString( const std::string& string )
@@ -84,13 +86,13 @@
   int getLength() const
   {
     calculate();
-    return m_length;
+    return m_data.length();
   }
 
   /// Get the total value the fields characters added together
   int getTotal() const
   {
-    calculate();
+    sum();
     return m_total;
   }
 
@@ -103,33 +105,46 @@
   {
     if( m_calculated ) return;
 
-    char buf[64];
+    m_total = -1; // dirty
 
-    if( 13 + m_string.length() < sizeof(buf) )
+    if( m_data.empty() )
     {
-      int tagLength = STRING_SPRINTF( buf, "%d=", m_field );
-      m_length = tagLength + m_string.length() + 1;
-      memcpy( buf + tagLength, m_string.data(), m_string.length() );
-      buf[m_length - 1] = '\001';
-      m_data.assign( buf, m_length );
+      // buffer is big enough for significant digits and extra digit,
+      // minus and equals (but no null)
+      char buf[std::numeric_limits<int>::digits10 + 3];
+      char* p = integer_to_string( buf, sizeof (buf), m_field );
+      buf[sizeof (buf) - 1] = '=';
+
+      m_tagLength = buf + sizeof (buf) - p;
+      m_data.resize( m_tagLength + m_string.length() + 1 );
+      std::copy( p, p + m_tagLength, m_data.begin() );
     }
     else
     {
-      m_data = IntConvertor::convert(m_field) + "=" + m_string + "\001";
-      m_length = m_data.length();
+      m_data.resize( m_tagLength + m_string.length() + 1 );
     }
 
-    const unsigned char* iter =
-      reinterpret_cast<const unsigned char*>( m_data.c_str() );
-    m_total = std::accumulate( iter, iter + m_length, 0 );
+    std::copy( m_string.begin(), m_string.end(), m_data.begin() + m_tagLength );
+    m_data[m_data.length() - 1] = '\001';
 
     m_calculated = true;
   }
 
+  void sum() const
+  {
+    calculate();
+
+    if( m_total != -1 ) return;
+
+    const unsigned char* iter =
+      reinterpret_cast<const unsigned char*>( m_data.c_str() );
+    m_total = std::accumulate( iter, iter + m_data.length(), 0 );
+  }
+
   int m_field;
   std::string m_string;
   mutable std::string m_data;
-  mutable int m_length;
+  mutable int m_tagLength;
   mutable int m_total;
   mutable bool m_calculated;
 };
