diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h
index 86f1f2c..f02537b 100644
--- a/src/lib_json/json_tool.h
+++ b/src/lib_json/json_tool.h
@@ -88,41 +88,47 @@ static inline void uintToString(LargestUInt value, char*& current) {
  * We had a sophisticated way, but it did not work in WinCE.
  * @see https://github.com/open-source-parsers/jsoncpp/pull/9
  */
-static inline void fixNumericLocale(char* begin, char* end) {
-  while (begin < end) {
+template <typename Iter>
+Iter fixNumericLocale(Iter begin, Iter end) {
+  for (; begin != end; ++begin) {
     if (*begin == ',') {
       *begin = '.';
     }
-    ++begin;
   }
+  return begin;
 }
 
-static inline void fixNumericLocaleInput(char* begin, char* end) {
+template <typename Iter>
+void fixNumericLocaleInput(Iter begin, Iter end) {
   char decimalPoint = getDecimalPoint();
-  if (decimalPoint != '\0' && decimalPoint != '.') {
-    while (begin < end) {
-      if (*begin == '.') {
-        *begin = decimalPoint;
-      }
-      ++begin;
+  if (decimalPoint == '\0' || decimalPoint == '.') {
+    return;
+  }
+  for (; begin != end; ++begin) {
+    if (*begin == '.') {
+      *begin = decimalPoint;
     }
   }
 }
 
 /**
- * Delete zeros in the end of string, if it isn't last zero before '.' character.
+ * Return iterator that would be the new end of the range [begin,end), if we
+ * were to delete zeros in the end of string, but not the last zero before '.'.
  */
-static inline void fixZerosInTheEnd(char* begin, char* end) {
-  end--;
-  while ((begin < end) && (*end == '0')) {
-    // don't delete last zero before point.
-    if (*(end - 1) != '.') {
-      *end = '\0';
+template <typename Iter>
+Iter fixZerosInTheEnd(Iter begin, Iter end) {
+  for (; begin != end; --end) {
+    if (*(end-1) != '0') {
+      return end;
+    }
+    // Don't delete the last zero before the decimal point.
+    if (begin != (end-1) && *(end-2) == '.') {
+      return end;
     }
-    end--;
   }
+  return end;
 }
 
-} // namespace Json {
+} // namespace Json
 
 #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp
index 823e96d..30c6833 100644
--- a/src/lib_json/json_writer.cpp
+++ b/src/lib_json/json_writer.cpp
@@ -127,48 +127,45 @@ JSONCPP_STRING valueToString(UInt value) {
 
 namespace {
 JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType) {
-  // Allocate a buffer that is more than large enough to store the 16 digits of
-  // precision requested below.
-  char buffer[36];
-  int len = -1;
-
-  char formatString[15];
-  if (precisionType == PrecisionType::significantDigits) {
-    snprintf(formatString, sizeof(formatString), "%%.%ug", precision);
-  } else {
-    snprintf(formatString, sizeof(formatString), "%%.%uf", precision);
-  }
-
   // Print into the buffer. We need not request the alternative representation
   // that always has a decimal point because JSON doesn't distinguish the
   // concepts of reals and integers.
-  if (isfinite(value)) {
-    len = snprintf(buffer, sizeof(buffer), formatString, value);
-    fixNumericLocale(buffer, buffer + len);
-    // to delete use-less too much zeros in the end of string
-    if (precisionType == PrecisionType::decimalPlaces) {
-      fixZerosInTheEnd(buffer, buffer + len);
-    }
-
-    // try to ensure we preserve the fact that this was given to us as a double on input
-    if (!strchr(buffer, '.') && !strchr(buffer, 'e')) {
-      strcat(buffer, ".0");
-    }
-
-  } else {
-
-    if (isnan(value)) {
-      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null");
-    } else if (value < 0) {
-      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999");
-    } else {
-      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999");
-    }
+  if (!isfinite(value)) {
+    static const char* const reps[2][3] = {
+      {"NaN", "-Infinity", "Infinity"},
+      {"null", "-1e+9999", "1e+9999"}};
+    return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 : (value < 0) ? 1 : 2];
+  }
+
+  JSONCPP_STRING buffer(size_t(36), '\0');
+  while (true) {
+      int len = snprintf(&*buffer.begin(), buffer.size(),
+                         (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f",
+                         precision, value);
+      assert(len >= 0);
+      size_t wouldPrint = static_cast<size_t>(len);
+      if (wouldPrint >= buffer.size()) {
+         buffer.resize(wouldPrint + 1);
+         continue;
+      }
+      buffer.resize(wouldPrint);
+      break;
+  }
+
+  buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end());
+
+  // strip the zero padding from the right
+  if (precisionType == PrecisionType::decimalPlaces) {
+    buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end());
+  }
+
+  // try to ensure we preserve the fact that this was given to us as a double on input
+  if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) {
+    buffer += ".0";
   }
-  assert(len >= 0);
   return buffer;
 }
-}
+}  // namespace
 
 JSONCPP_STRING valueToString(double value, unsigned int precision, PrecisionType precisionType) {
   return valueToString(value, false, precision, precisionType);