You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mp...@apache.org on 2017/01/10 23:21:57 UTC

[1/2] mesos git commit: Fixed wrong float serialization in JSON in locales different from C.

Repository: mesos
Updated Branches:
  refs/heads/master c44347b5a -> bea98b9b9


Fixed wrong float serialization in JSON in locales different from C.

Resolves an isse with the JSON serialization functions where floats
would use the process active locale as a decimal separator instead
of the JSON conformant period (`.`).

Review: https://reviews.apache.org/r/52877/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/bea98b9b
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/bea98b9b
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/bea98b9b

Branch: refs/heads/master
Commit: bea98b9b9866b376bb77efff702ed989829c7205
Parents: 0bfc812
Author: Alexander Rojas <al...@mesosphere.io>
Authored: Tue Jan 10 10:35:43 2017 -0800
Committer: Michael Park <mp...@apache.org>
Committed: Tue Jan 10 15:18:04 2017 -0800

----------------------------------------------------------------------
 3rdparty/stout/include/stout/jsonify.hpp | 36 +++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/bea98b9b/3rdparty/stout/include/stout/jsonify.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/jsonify.hpp b/3rdparty/stout/include/stout/jsonify.hpp
index 8220d00..3c48046 100644
--- a/3rdparty/stout/include/stout/jsonify.hpp
+++ b/3rdparty/stout/include/stout/jsonify.hpp
@@ -13,6 +13,9 @@
 #ifndef __STOUT_JSONIFY__
 #define __STOUT_JSONIFY__
 
+#include <xlocale.h>
+
+#include <clocale>
 #include <cstddef>
 #include <functional>
 #include <ostream>
@@ -21,6 +24,7 @@
 #include <type_traits>
 #include <utility>
 
+#include <stout/check.hpp>
 #include <stout/result_of.hpp>
 #include <stout/strings.hpp>
 
@@ -49,6 +53,32 @@ JSON::Proxy jsonify(const T&);
 
 namespace JSON {
 
+namespace internal {
+
+class ClassicLocale
+{
+public:
+  ClassicLocale()
+  {
+    c_locale_ = newlocale(LC_NUMERIC_MASK, "C", nullptr);
+    original_locale_ = uselocale(c_locale_);
+  }
+
+  ~ClassicLocale()
+  {
+    uselocale(original_locale_);
+    CHECK(c_locale_ != 0);
+    freelocale(c_locale_);
+  }
+
+private:
+  locale_t original_locale_;
+  locale_t c_locale_;
+};
+
+} // namespace internal {
+
+
 // The result of `jsonify`. This is a light-weight proxy object that can either
 // be implicitly converted to a `std::string`, or directly inserted into an
 // output stream.
@@ -62,6 +92,9 @@ class Proxy
 public:
   operator std::string() &&
   {
+    // Needed to set C locale and therefore creating proper JSON output.
+    internal::ClassicLocale guard;
+
     std::ostringstream stream;
     stream << std::move(*this);
     return stream.str();
@@ -94,6 +127,9 @@ private:
 
 inline std::ostream& operator<<(std::ostream& stream, Proxy&& that)
 {
+  // Needed to set C locale and therefore creating proper JSON output.
+  internal::ClassicLocale guard;
+
   that.write_(&stream);
   return stream;
 }


[2/2] mesos git commit: Used `jsonify` in `operator<<` for `JSON::*` to reduce duplicate code.

Posted by mp...@apache.org.
Used `jsonify` in `operator<<` for `JSON::*` to reduce duplicate code.

The printing logic for `json.hpp` and `jsonify.hpp` are currently
duplicated. We can reduce this duplication by leveraging `jsonify` for
the implementation of `operator<<` for `JSON::*`. Since `JSON::Value`s
are not generally used for printing, there should be no performance
concerns here.

Review: https://reviews.apache.org/r/55296/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/0bfc812e
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/0bfc812e
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/0bfc812e

Branch: refs/heads/master
Commit: 0bfc812ec14525e40e6b0d8e26a425fa8681e643
Parents: c44347b
Author: Michael Park <mp...@apache.org>
Authored: Tue Jan 10 10:35:20 2017 -0800
Committer: Michael Park <mp...@apache.org>
Committed: Tue Jan 10 15:18:04 2017 -0800

----------------------------------------------------------------------
 3rdparty/stout/include/stout/json.hpp | 51 ++++++++++--------------------
 1 file changed, 16 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/0bfc812e/3rdparty/stout/include/stout/json.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/json.hpp b/3rdparty/stout/include/stout/json.hpp
index 62ce152..b0fd667 100644
--- a/3rdparty/stout/include/stout/json.hpp
+++ b/3rdparty/stout/include/stout/json.hpp
@@ -36,6 +36,7 @@
 
 #include <stout/check.hpp>
 #include <stout/foreach.hpp>
+#include <stout/jsonify.hpp>
 #include <stout/numify.hpp>
 #include <stout/result.hpp>
 #include <stout/strings.hpp>
@@ -661,54 +662,34 @@ inline bool operator!=(const Value& lhs, const Value& rhs)
 
 inline std::ostream& operator<<(std::ostream& stream, const String& string)
 {
-  // TODO(benh): This escaping DOES NOT handle unicode, it encodes as ASCII.
-  // See RFC4627 for the JSON string specificiation.
-  return stream << picojson::value(string.value).serialize();
+  return stream << jsonify(string.value);
 }
 
 
 inline std::ostream& operator<<(std::ostream& stream, const Number& number)
 {
   switch (number.type) {
-    case Number::FLOATING: {
-      // Prints a floating point value, with the specified precision, see:
-      // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2005.pdf
-      // Additionally ensures that a decimal point is in the output.
-      char buffer[50] {}; // More than long enough for the specified precision.
-      snprintf(
-          buffer,
-          sizeof(buffer),
-          "%#.*g",
-          std::numeric_limits<double>::digits10,
-          number.value);
-
-      // Get rid of excess trailing zeroes before outputting.
-      // Otherwise, printing 1.0 would result in "1.00000000000000".
-      // NOTE: valid JSON numbers cannot end with a '.'.
-      std::string trimmed = strings::trim(buffer, strings::SUFFIX, "0");
-      return stream << trimmed << (trimmed.back() == '.' ? "0" : "");
-    }
+    case Number::FLOATING:
+      stream << jsonify(number.value);
+      break;
     case Number::SIGNED_INTEGER:
-      return stream << number.signed_integer;
+      stream << jsonify(number.signed_integer);
+      break;
     case Number::UNSIGNED_INTEGER:
-      return stream << number.unsigned_integer;
-
-    // NOTE: By not setting a default we leverage the compiler
-    // errors when the enumeration is augmented to find all
-    // the cases we need to provide.
+      stream << jsonify(number.unsigned_integer);
+      break;
   }
-
-  UNREACHABLE();
+  return stream;
 }
 
 
+// TODO(mpark): Extend `jsonify` to be usable for this implementation.
 inline std::ostream& operator<<(std::ostream& stream, const Object& object)
 {
   stream << "{";
-  std::map<std::string, Value>::const_iterator iterator;
-  iterator = object.values.begin();
+  auto iterator = object.values.begin();
   while (iterator != object.values.end()) {
-    stream << String((*iterator).first) << ":" << (*iterator).second;
+    stream << jsonify(iterator->first) << ":" << iterator->second;
     if (++iterator != object.values.end()) {
       stream << ",";
     }
@@ -718,11 +699,11 @@ inline std::ostream& operator<<(std::ostream& stream, const Object& object)
 }
 
 
+// TODO(mpark): Extend `jsonify` to be usable for this implementation.
 inline std::ostream& operator<<(std::ostream& stream, const Array& array)
 {
   stream << "[";
-  std::vector<Value>::const_iterator iterator;
-  iterator = array.values.begin();
+  auto iterator = array.values.begin();
   while (iterator != array.values.end()) {
     stream << *iterator;
     if (++iterator != array.values.end()) {
@@ -736,7 +717,7 @@ inline std::ostream& operator<<(std::ostream& stream, const Array& array)
 
 inline std::ostream& operator<<(std::ostream& stream, const Boolean& boolean)
 {
-  return stream << (boolean.value ? "true" : "false");
+  return stream << jsonify(boolean.value);
 }